gisele-language 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +5 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +26 -0
- data/LICENCE.md +22 -0
- data/Manifest.txt +13 -0
- data/README.md +7 -0
- data/Rakefile +11 -0
- data/gisele-language.gemspec +188 -0
- data/gisele-language.noespec +24 -0
- data/lib/gisele/language/ast/bool_and.rb +14 -0
- data/lib/gisele/language/ast/bool_expr.rb +22 -0
- data/lib/gisele/language/ast/bool_not.rb +14 -0
- data/lib/gisele/language/ast/bool_or.rb +14 -0
- data/lib/gisele/language/ast/case_st.rb +14 -0
- data/lib/gisele/language/ast/else_clause.rb +14 -0
- data/lib/gisele/language/ast/elsif_clause.rb +14 -0
- data/lib/gisele/language/ast/if_st.rb +14 -0
- data/lib/gisele/language/ast/node.rb +35 -0
- data/lib/gisele/language/ast/task_call_st.rb +14 -0
- data/lib/gisele/language/ast/var_ref.rb +14 -0
- data/lib/gisele/language/ast/when_clause.rb +14 -0
- data/lib/gisele/language/ast/while_st.rb +14 -0
- data/lib/gisele/language/grammar.citrus +236 -0
- data/lib/gisele/language/grammar.sexp.yml +83 -0
- data/lib/gisele/language/processors/elsif_flattener.rb +36 -0
- data/lib/gisele/language/processors/if_to_case.rb +65 -0
- data/lib/gisele/language/processors/scoping_helper.rb +32 -0
- data/lib/gisele/language/processors/sugar_removal.rb +17 -0
- data/lib/gisele/language/processors.rb +4 -0
- data/lib/gisele/language/syntax/bool_and.rb +14 -0
- data/lib/gisele/language/syntax/bool_expr.rb +14 -0
- data/lib/gisele/language/syntax/bool_lit.rb +14 -0
- data/lib/gisele/language/syntax/bool_not.rb +14 -0
- data/lib/gisele/language/syntax/bool_or.rb +14 -0
- data/lib/gisele/language/syntax/bool_paren.rb +14 -0
- data/lib/gisele/language/syntax/case_st.rb +19 -0
- data/lib/gisele/language/syntax/else_clause.rb +14 -0
- data/lib/gisele/language/syntax/elsif_clause.rb +16 -0
- data/lib/gisele/language/syntax/event_set.rb +15 -0
- data/lib/gisele/language/syntax/fluent_def.rb +18 -0
- data/lib/gisele/language/syntax/if_st.rb +18 -0
- data/lib/gisele/language/syntax/implicit_seq_st.rb +16 -0
- data/lib/gisele/language/syntax/node.rb +40 -0
- data/lib/gisele/language/syntax/par_st.rb +14 -0
- data/lib/gisele/language/syntax/seq_st.rb +14 -0
- data/lib/gisele/language/syntax/st_list.rb +14 -0
- data/lib/gisele/language/syntax/task_call_st.rb +14 -0
- data/lib/gisele/language/syntax/task_def.rb +18 -0
- data/lib/gisele/language/syntax/trackvar_def.rb +19 -0
- data/lib/gisele/language/syntax/unit_def.rb +14 -0
- data/lib/gisele/language/syntax/var_ref.rb +14 -0
- data/lib/gisele/language/syntax/when_clause.rb +16 -0
- data/lib/gisele/language/syntax/while_st.rb +16 -0
- data/lib/gisele/language.rb +31 -0
- data/lib/gisele-language/loader.rb +3 -0
- data/lib/gisele-language/version.rb +16 -0
- data/lib/gisele-language.rb +19 -0
- data/spec/fixtures/tasks/complete.gis +40 -0
- data/spec/fixtures/tasks/simple.ast +51 -0
- data/spec/fixtures/tasks/simple.gis +16 -0
- data/spec/language/ast/test_bool_expr.rb +50 -0
- data/spec/language/grammar_sexp/test_case_st.rb +20 -0
- data/spec/language/grammar_sexp/test_event_set.rb +14 -0
- data/spec/language/grammar_sexp/test_fluent_def.rb +18 -0
- data/spec/language/grammar_sexp/test_initially.rb +18 -0
- data/spec/language/grammar_sexp/test_nop_st.rb +10 -0
- data/spec/language/grammar_sexp/test_when_clause.rb +12 -0
- data/spec/language/processors/test_elsif_flattener.rb +94 -0
- data/spec/language/processors/test_if_to_case.rb +105 -0
- data/spec/language/processors/test_scoping_helper.rb +45 -0
- data/spec/language/syntax/grammar/test_bool_expr.rb +34 -0
- data/spec/language/syntax/grammar/test_boolean_literal.rb +17 -0
- data/spec/language/syntax/grammar/test_case_st.rb +60 -0
- data/spec/language/syntax/grammar/test_event.rb +18 -0
- data/spec/language/syntax/grammar/test_event_name.rb +21 -0
- data/spec/language/syntax/grammar/test_event_set.rb +26 -0
- data/spec/language/syntax/grammar/test_fluent_def.rb +21 -0
- data/spec/language/syntax/grammar/test_if_st.rb +21 -0
- data/spec/language/syntax/grammar/test_par_st.rb +11 -0
- data/spec/language/syntax/grammar/test_process_statement.rb +19 -0
- data/spec/language/syntax/grammar/test_seq_st.rb +11 -0
- data/spec/language/syntax/grammar/test_spaces.rb +19 -0
- data/spec/language/syntax/grammar/test_spacing.rb +17 -0
- data/spec/language/syntax/grammar/test_task_def.rb +35 -0
- data/spec/language/syntax/grammar/test_task_name.rb +19 -0
- data/spec/language/syntax/grammar/test_task_start_or_end.rb +17 -0
- data/spec/language/syntax/grammar/test_trackvar_def.rb +21 -0
- data/spec/language/syntax/grammar/test_unit_def.rb +29 -0
- data/spec/language/syntax/grammar/test_variable_name.rb +51 -0
- data/spec/language/syntax/grammar/test_when_clause.rb +21 -0
- data/spec/language/syntax/grammar/test_while_st.rb +11 -0
- data/spec/language/syntax/to_ast/test_bool_expr.rb +32 -0
- data/spec/language/syntax/to_ast/test_case_st.rb +47 -0
- data/spec/language/syntax/to_ast/test_else_clause.rb +13 -0
- data/spec/language/syntax/to_ast/test_elsif_clause.rb +15 -0
- data/spec/language/syntax/to_ast/test_event_set.rb +24 -0
- data/spec/language/syntax/to_ast/test_fluent_def.rb +26 -0
- data/spec/language/syntax/to_ast/test_if_st.rb +39 -0
- data/spec/language/syntax/to_ast/test_par_st.rb +12 -0
- data/spec/language/syntax/to_ast/test_seq_st.rb +12 -0
- data/spec/language/syntax/to_ast/test_task_call_st.rb +10 -0
- data/spec/language/syntax/to_ast/test_task_def.rb +44 -0
- data/spec/language/syntax/to_ast/test_trackvar_def.rb +26 -0
- data/spec/language/syntax/to_ast/test_unit_def.rb +28 -0
- data/spec/language/syntax/to_ast/test_var_ref.rb +12 -0
- data/spec/language/syntax/to_ast/test_when_clause.rb +15 -0
- data/spec/language/syntax/to_ast/test_while_st.rb +24 -0
- data/spec/language/test_syntax.rb +51 -0
- data/spec/spec_helper.rb +44 -0
- data/spec/test_gisele-language.rb +8 -0
- data/tasks/gem.rake +73 -0
- data/tasks/spec_test.rake +71 -0
- metadata +269 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Gisele
|
|
2
|
+
module Language
|
|
3
|
+
module Syntax
|
|
4
|
+
module Node
|
|
5
|
+
|
|
6
|
+
def to_ast
|
|
7
|
+
Language::sexpr(value, {:citrus_match => self})
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def value
|
|
11
|
+
_to_ast
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end # module Node
|
|
15
|
+
end # module Syntax
|
|
16
|
+
end # module Language
|
|
17
|
+
end # module Gisele
|
|
18
|
+
require_relative 'event_set'
|
|
19
|
+
require_relative 'fluent_def'
|
|
20
|
+
require_relative 'trackvar_def'
|
|
21
|
+
require_relative 'var_ref'
|
|
22
|
+
require_relative 'bool_lit'
|
|
23
|
+
require_relative 'bool_paren'
|
|
24
|
+
require_relative 'bool_not'
|
|
25
|
+
require_relative 'bool_and'
|
|
26
|
+
require_relative 'bool_or'
|
|
27
|
+
require_relative 'bool_expr'
|
|
28
|
+
require_relative 'st_list'
|
|
29
|
+
require_relative 'implicit_seq_st'
|
|
30
|
+
require_relative 'task_call_st'
|
|
31
|
+
require_relative 'seq_st'
|
|
32
|
+
require_relative 'par_st'
|
|
33
|
+
require_relative 'while_st'
|
|
34
|
+
require_relative 'if_st'
|
|
35
|
+
require_relative 'else_clause'
|
|
36
|
+
require_relative 'elsif_clause'
|
|
37
|
+
require_relative 'case_st'
|
|
38
|
+
require_relative 'when_clause'
|
|
39
|
+
require_relative 'task_def'
|
|
40
|
+
require_relative 'unit_def'
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Gisele
|
|
2
|
+
module Language
|
|
3
|
+
module Syntax
|
|
4
|
+
module TaskDef
|
|
5
|
+
include Node
|
|
6
|
+
|
|
7
|
+
def _to_ast
|
|
8
|
+
name = captures[:task_name].first.strip
|
|
9
|
+
defs = captures[:some_def].map{|x| x.to_ast}
|
|
10
|
+
ref = captures[:explicit_statement].map{|x| x.to_ast}.first
|
|
11
|
+
ref = [:nop_st] unless ref
|
|
12
|
+
[:task_def, name] + defs + [ref]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end # module TaskDef
|
|
16
|
+
end # module Syntax
|
|
17
|
+
end # module Language
|
|
18
|
+
end # module Gisele
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Gisele
|
|
2
|
+
module Language
|
|
3
|
+
module Syntax
|
|
4
|
+
module TrackvarDef
|
|
5
|
+
include Node
|
|
6
|
+
|
|
7
|
+
def _to_ast
|
|
8
|
+
name = captures[:variable_name].first.strip
|
|
9
|
+
init, term = captures[:event_set].map{|x| x.to_ast}
|
|
10
|
+
term = [:event_set] unless term
|
|
11
|
+
initval = captures[:initially_def].first
|
|
12
|
+
initval = (initval && !initval.empty?) ? initval.value : nil
|
|
13
|
+
[:trackvar_def, name, init, term, initval]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end # module TrackvarDef
|
|
17
|
+
end # module Syntax
|
|
18
|
+
end # module Language
|
|
19
|
+
end # module Gisele
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Gisele
|
|
2
|
+
module Language
|
|
3
|
+
module Syntax
|
|
4
|
+
module UnitDef
|
|
5
|
+
include Node
|
|
6
|
+
|
|
7
|
+
def _to_ast
|
|
8
|
+
[:unit_def] + captures[:task_def].map{|x| x.to_ast}
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
end # module UnitDef
|
|
12
|
+
end # module Syntax
|
|
13
|
+
end # module Language
|
|
14
|
+
end # module Gisele
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Gisele
|
|
2
|
+
module Language
|
|
3
|
+
module Syntax
|
|
4
|
+
module WhenClause
|
|
5
|
+
include Node
|
|
6
|
+
|
|
7
|
+
def _to_ast
|
|
8
|
+
cond = captures[:bool_expr].first.to_ast
|
|
9
|
+
dost = captures[:process_statement].first.to_ast
|
|
10
|
+
[:when_clause, cond, dost]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
end # module WhenClause
|
|
14
|
+
end # module Syntax
|
|
15
|
+
end # module Language
|
|
16
|
+
end # module Gisele
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Gisele
|
|
2
|
+
module Language
|
|
3
|
+
module Syntax
|
|
4
|
+
module WhileSt
|
|
5
|
+
include Node
|
|
6
|
+
|
|
7
|
+
def _to_ast
|
|
8
|
+
cond = captures[:bool_expr].first.to_ast
|
|
9
|
+
dost = captures[:process_statement].first.to_ast
|
|
10
|
+
[:while_st, cond, dost]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
end # module WhileSt
|
|
14
|
+
end # module Syntax
|
|
15
|
+
end # module Language
|
|
16
|
+
end # module Gisele
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
module Gisele
|
|
3
|
+
|
|
4
|
+
# Load the Language through Sexpr
|
|
5
|
+
Language = Sexpr.load Path.dir/"language/grammar.sexp.yml"
|
|
6
|
+
|
|
7
|
+
# Load syntax nodes, abstract syntax nodes, and processors
|
|
8
|
+
require_relative 'language/syntax/node'
|
|
9
|
+
require_relative 'language/ast/node'
|
|
10
|
+
require_relative 'language/processors'
|
|
11
|
+
|
|
12
|
+
# Force loading the Citrus parser now
|
|
13
|
+
Language.parser.parser
|
|
14
|
+
|
|
15
|
+
module Language
|
|
16
|
+
|
|
17
|
+
# By default, Sexpr will find for abstract nodes under Language itself. We
|
|
18
|
+
# override that behavior here and let it know that the AST module is the
|
|
19
|
+
# parent of all ast nodes.
|
|
20
|
+
def tagging_reference
|
|
21
|
+
AST
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# The tagging function (from s-expr kind to AST module) is not complete so far.
|
|
25
|
+
# This allows us to at least include the AST:Node module in all s-expressions.
|
|
26
|
+
def default_tagging_module
|
|
27
|
+
AST::Node
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end # module Language
|
|
31
|
+
end # module Gisele
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require "gisele-language/loader"
|
|
2
|
+
require_relative "gisele/language"
|
|
3
|
+
require "gisele-language/version"
|
|
4
|
+
module Gisele
|
|
5
|
+
|
|
6
|
+
def parse(*args)
|
|
7
|
+
Language::parse(*args)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def ast(*args)
|
|
11
|
+
Language::sexpr(*args)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def sexpr(*args)
|
|
15
|
+
Language::sexpr(*args)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
extend(self)
|
|
19
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
task Complete
|
|
2
|
+
|
|
3
|
+
trackvar everyOneHappy
|
|
4
|
+
{FirstTask:start}
|
|
5
|
+
|
|
6
|
+
fluent someoneHappy
|
|
7
|
+
{DrinkBeer:start, DrinkBeers:start},
|
|
8
|
+
{DoNothingSpecial:end}
|
|
9
|
+
initially false
|
|
10
|
+
|
|
11
|
+
task DrinkBeers
|
|
12
|
+
while not(drunk)
|
|
13
|
+
DrinkBeer
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
seq
|
|
18
|
+
FirstTask
|
|
19
|
+
if everyoneHappy
|
|
20
|
+
par
|
|
21
|
+
MakeJoy
|
|
22
|
+
DrinkBeers
|
|
23
|
+
end
|
|
24
|
+
elsif someoneHappy
|
|
25
|
+
DrinkBeer
|
|
26
|
+
else
|
|
27
|
+
DoNothingSpecial
|
|
28
|
+
end
|
|
29
|
+
while not(endOfTheDay)
|
|
30
|
+
case curState
|
|
31
|
+
when somethingToDo
|
|
32
|
+
DoSomething
|
|
33
|
+
when nothingToDo
|
|
34
|
+
DoNothing
|
|
35
|
+
else
|
|
36
|
+
WaitAndSee
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
[
|
|
2
|
+
:unit_def,
|
|
3
|
+
[
|
|
4
|
+
:task_def,
|
|
5
|
+
"Simple",
|
|
6
|
+
[
|
|
7
|
+
:fluent_def,
|
|
8
|
+
"diagKnown",
|
|
9
|
+
[
|
|
10
|
+
:event_set,
|
|
11
|
+
"Diagnosis:start"
|
|
12
|
+
],
|
|
13
|
+
[
|
|
14
|
+
:event_set,
|
|
15
|
+
"Treatment:end"
|
|
16
|
+
],
|
|
17
|
+
nil
|
|
18
|
+
],
|
|
19
|
+
[
|
|
20
|
+
:seq_st,
|
|
21
|
+
[
|
|
22
|
+
:if_st,
|
|
23
|
+
[
|
|
24
|
+
:bool_expr,
|
|
25
|
+
[
|
|
26
|
+
:bool_not,
|
|
27
|
+
[
|
|
28
|
+
:var_ref,
|
|
29
|
+
"diagKnown"
|
|
30
|
+
]
|
|
31
|
+
]
|
|
32
|
+
],
|
|
33
|
+
[
|
|
34
|
+
:task_call_st,
|
|
35
|
+
"Diagnosis"
|
|
36
|
+
],
|
|
37
|
+
[
|
|
38
|
+
:else_clause,
|
|
39
|
+
[
|
|
40
|
+
:task_call_st,
|
|
41
|
+
"NoDiag"
|
|
42
|
+
]
|
|
43
|
+
]
|
|
44
|
+
],
|
|
45
|
+
[
|
|
46
|
+
:task_call_st,
|
|
47
|
+
"Treatment"
|
|
48
|
+
]
|
|
49
|
+
]
|
|
50
|
+
]
|
|
51
|
+
]
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language::AST
|
|
3
|
+
describe BoolExpr, "negate" do
|
|
4
|
+
|
|
5
|
+
def sexpr(expr, options = {})
|
|
6
|
+
Gisele.sexpr(Gisele.parse(expr, options))
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
subject{ sexpr(expr, :root => :bool_expr).negate }
|
|
10
|
+
|
|
11
|
+
shared_examples_for 'A negated bool_expr' do
|
|
12
|
+
|
|
13
|
+
it 'is consistently rewrited' do
|
|
14
|
+
(Gisele::Language[:bool_expr] === subject).should be_true
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'is correctly tagged' do
|
|
18
|
+
subject.should be_a(Sexpr)
|
|
19
|
+
subject.should be_a(BoolExpr)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'has no immediate traceability marker' do
|
|
23
|
+
subject.citrus_match.should be_nil
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe "on a normal expression" do
|
|
28
|
+
let(:expr){ "x and y" }
|
|
29
|
+
|
|
30
|
+
it_behaves_like 'A negated bool_expr'
|
|
31
|
+
|
|
32
|
+
it "negates as expected" do
|
|
33
|
+
expected = sexpr("not(x and y)", :root => :bool_expr)
|
|
34
|
+
subject.should eq(expected)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe "on a negated expression" do
|
|
39
|
+
let(:expr){ "not(x and y)" }
|
|
40
|
+
|
|
41
|
+
it_behaves_like 'A negated bool_expr'
|
|
42
|
+
|
|
43
|
+
it "removes the negation" do
|
|
44
|
+
expected = sexpr("x and y", :root => :bool_expr)
|
|
45
|
+
subject.should eq(expected)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe "the Sexp grammar", "case_st" do
|
|
4
|
+
|
|
5
|
+
it 'matches when no variable is specified' do
|
|
6
|
+
case_st = \
|
|
7
|
+
[:case_st, nil,
|
|
8
|
+
[:when_clause, [:bool_expr, [:bool_lit, true]], [:nop_st]] ]
|
|
9
|
+
(sexp_grammar[:case_st] === case_st).should be_true
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'matches when a variable is specified' do
|
|
13
|
+
case_st = \
|
|
14
|
+
[:case_st, [:var_ref, "varName"],
|
|
15
|
+
[:when_clause, [:bool_expr, [:bool_lit, true]], [:nop_st]] ]
|
|
16
|
+
(sexp_grammar[:case_st] === case_st).should be_true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe "the Sexp grammar", "event_set" do
|
|
4
|
+
|
|
5
|
+
it 'matches an empty set' do
|
|
6
|
+
(sexp_grammar[:event_set] === [:event_set]).should be_true
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'matches a non empty set' do
|
|
10
|
+
(sexp_grammar[:event_set] === [:event_set, "event", "Task:start"]).should be_true
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe "the Sexp grammar", "fluent_def" do
|
|
4
|
+
|
|
5
|
+
let(:g){ Gisele::Language }
|
|
6
|
+
|
|
7
|
+
it 'matches an fluent with initial value' do
|
|
8
|
+
fluent = [:fluent_def, "name", [:event_set, "start"], [:event_set, "stop"], true]
|
|
9
|
+
(sexp_grammar[:fluent_def] === fluent).should be_true
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'matches an fluent without initial value' do
|
|
13
|
+
fluent = [:fluent_def, "name", [:event_set, "start"], [:event_set, "stop"], nil]
|
|
14
|
+
(sexp_grammar[:fluent_def] === fluent).should be_true
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe "the Sexp grammar", "initially" do
|
|
4
|
+
|
|
5
|
+
it 'matches true' do
|
|
6
|
+
(sexp_grammar[:initially] === true).should be_true
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'matches false' do
|
|
10
|
+
(sexp_grammar[:initially] === false).should be_true
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'matches nil' do
|
|
14
|
+
(sexp_grammar[:initially] === nil).should be_true
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe "the Sexp grammar", "when_clause" do
|
|
4
|
+
|
|
5
|
+
it 'matches a valid when clause' do
|
|
6
|
+
when_clause = \
|
|
7
|
+
[:when_clause, [:bool_expr, [:bool_lit, true]], [:nop_st]]
|
|
8
|
+
(sexp_grammar[:when_clause] === when_clause).should be_true
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe ElsifFlattener do
|
|
4
|
+
|
|
5
|
+
def ast(source)
|
|
6
|
+
Gisele.ast(Gisele.parse(source.strip, :root => :if_st))
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def rewrite(ast)
|
|
10
|
+
@rewrited = ElsifFlattener.call(ast)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
after{
|
|
14
|
+
(sexp_grammar[:if_st] === @rewrited).should be_true
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
it 'rewrites a single if correctly' do
|
|
18
|
+
source = ast("if goodCond Task1 end")
|
|
19
|
+
rewrite(source).should eq(source)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'rewrites a if/else correctly' do
|
|
23
|
+
source = ast("if goodCond Task1 else Task2 end")
|
|
24
|
+
rewrite(source).should eq(source)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'rewrites a if/elsif correctly' do
|
|
28
|
+
source = ast("if good Task1 elsif bad Task2 end")
|
|
29
|
+
expected = ast("if good Task1 else if bad Task2 end end")
|
|
30
|
+
rewrite(source).should eq(expected)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'rewrites a if/elsif/else correctly' do
|
|
34
|
+
source = ast("if good Task1 elsif bad Task2 else Task3 end")
|
|
35
|
+
expected = ast("if good Task1 else if bad Task2 else Task3 end end")
|
|
36
|
+
rewrite(source).should eq(expected)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'rewrites a if/elsif/elsif/else correctly' do
|
|
40
|
+
source = ast(<<-EOF.strip)
|
|
41
|
+
if good Task1
|
|
42
|
+
elsif bad Task2
|
|
43
|
+
elsif none Task3
|
|
44
|
+
else Task4
|
|
45
|
+
end
|
|
46
|
+
EOF
|
|
47
|
+
expected = ast(<<-EOF.strip)
|
|
48
|
+
if good
|
|
49
|
+
Task1
|
|
50
|
+
else
|
|
51
|
+
if bad
|
|
52
|
+
Task2
|
|
53
|
+
else
|
|
54
|
+
if none
|
|
55
|
+
Task3
|
|
56
|
+
else
|
|
57
|
+
Task4
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
EOF
|
|
62
|
+
rewrite(source).should eq(expected)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'recurses by default' do
|
|
66
|
+
source = ast(<<-EOF.strip)
|
|
67
|
+
if goodCond
|
|
68
|
+
Task1
|
|
69
|
+
else
|
|
70
|
+
if bad
|
|
71
|
+
Task2
|
|
72
|
+
elsif middle
|
|
73
|
+
Task3
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
EOF
|
|
77
|
+
expected = ast(<<-EOF.strip)
|
|
78
|
+
if goodCond
|
|
79
|
+
Task1
|
|
80
|
+
else
|
|
81
|
+
if bad
|
|
82
|
+
Task2
|
|
83
|
+
else
|
|
84
|
+
if middle
|
|
85
|
+
Task3
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
EOF
|
|
90
|
+
rewrite(source).should eq(expected)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
end
|
|
94
|
+
end
|