gisele 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +73 -44
- data/Gemfile.lock +1 -0
- data/examples/meeting-scheduler/MeetingScheduling.gis +23 -23
- data/examples/rectal-cancer-pathway/RectalCancerPathway.gis +64 -0
- data/gisele.noespec +1 -1
- data/lib/gisele/command.rb +6 -4
- 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/node.rb +3 -1
- data/lib/gisele/language/ast/{unit.rb → unit_def.rb} +2 -2
- data/lib/gisele/language/dot.yml +1 -1
- data/lib/gisele/language/elsif_flattener.rb +35 -0
- data/lib/gisele/language/if_to_case.rb +63 -0
- data/lib/gisele/language/rewriter/helper.rb +41 -0
- data/lib/gisele/language/rewriter/scoping.rb +34 -0
- data/lib/gisele/language/rewriter/work_on_nodes.rb +30 -0
- data/lib/gisele/language/rewriter.rb +60 -0
- data/lib/gisele/language/sugar_removal.rb +2 -64
- data/lib/gisele/language/syntax/case_st.rb +19 -0
- data/lib/gisele/language/syntax/grammar.citrus +61 -28
- data/lib/gisele/language/syntax/node.rb +3 -3
- data/lib/gisele/language/syntax/task_def.rb +5 -4
- data/lib/gisele/language/syntax/{unit.rb → unit_def.rb} +3 -3
- data/lib/gisele/language/syntax/when_clause.rb +16 -0
- data/lib/gisele/language/to_graph.rb +43 -16
- data/lib/gisele/language.rb +25 -1
- data/lib/gisele/version.rb +1 -1
- data/spec/command/main/gisele_ast_ruby.stdout +29 -35
- data/spec/command/main/gisele_graph.stdout +24 -14
- data/spec/command/main/gisele_help.stdout +1 -1
- data/spec/command/main/gisele_no_sugar.cmd +1 -1
- data/spec/command/main/gisele_no_sugar.stdout +119 -25
- data/spec/command/main/gisele_version.stdout +1 -1
- data/spec/fixtures/tasks/complete.gis +24 -2
- data/spec/fixtures/tasks/simple.ast +29 -35
- data/spec/fixtures/tasks/simple.gis +7 -2
- data/spec/spec_helper.rb +10 -0
- data/spec/unit/language/ast/test_node.rb +10 -11
- data/spec/unit/language/rewriter/test_helper.rb +87 -0
- data/spec/unit/language/rewriter/test_scoping.rb +46 -0
- data/spec/unit/language/rewriter/test_work_on_nodes.rb +45 -0
- data/spec/unit/language/syntax/grammar/test_bool_expr.rb +34 -0
- data/spec/unit/language/syntax/grammar/test_boolean_literal.rb +17 -0
- data/spec/unit/language/syntax/grammar/test_case_st.rb +60 -0
- data/spec/unit/language/syntax/grammar/test_event.rb +18 -0
- data/spec/unit/language/syntax/grammar/test_event_name.rb +21 -0
- data/spec/unit/language/syntax/grammar/test_event_set.rb +27 -0
- data/spec/unit/language/syntax/grammar/test_fluent_def.rb +21 -0
- data/spec/unit/language/syntax/grammar/test_if_st.rb +21 -0
- data/spec/unit/language/syntax/grammar/test_par_st.rb +11 -0
- data/spec/unit/language/syntax/grammar/test_process_statement.rb +19 -0
- data/spec/unit/language/syntax/grammar/test_seq_st.rb +11 -0
- data/spec/unit/language/syntax/grammar/test_spaces.rb +19 -0
- data/spec/unit/language/syntax/grammar/test_spacing.rb +18 -0
- data/spec/unit/language/syntax/grammar/test_task_def.rb +35 -0
- data/spec/unit/language/syntax/grammar/test_task_name.rb +19 -0
- data/spec/unit/language/syntax/grammar/test_task_start_or_end.rb +17 -0
- data/spec/unit/language/syntax/grammar/test_trackvar_def.rb +21 -0
- data/spec/unit/language/syntax/grammar/test_unit_def.rb +29 -0
- data/spec/unit/language/syntax/grammar/test_variable_name.rb +30 -0
- data/spec/unit/language/syntax/grammar/test_when_clause.rb +21 -0
- data/spec/unit/language/syntax/grammar/test_while_st.rb +11 -0
- data/spec/unit/language/syntax/to_ast/test_bool_expr.rb +28 -0
- data/spec/unit/language/syntax/to_ast/test_case_st.rb +47 -0
- data/spec/unit/language/syntax/to_ast/test_else_clause.rb +13 -0
- data/spec/unit/language/syntax/to_ast/test_elsif_clause.rb +15 -0
- data/spec/unit/language/syntax/to_ast/test_event_set.rb +24 -0
- data/spec/unit/language/syntax/to_ast/test_fluent_def.rb +26 -0
- data/spec/unit/language/syntax/to_ast/test_if_st.rb +39 -0
- data/spec/unit/language/syntax/to_ast/test_par_st.rb +12 -0
- data/spec/unit/language/syntax/to_ast/test_seq_st.rb +12 -0
- data/spec/unit/language/syntax/to_ast/test_task_call_st.rb +10 -0
- data/spec/unit/language/syntax/to_ast/test_task_def.rb +44 -0
- data/spec/unit/language/syntax/to_ast/test_trackvar_def.rb +26 -0
- data/spec/unit/language/syntax/to_ast/test_unit_def.rb +28 -0
- data/spec/unit/language/syntax/to_ast/test_var_ref.rb +12 -0
- data/spec/unit/language/syntax/to_ast/test_when_clause.rb +15 -0
- data/spec/unit/language/syntax/to_ast/test_while_st.rb +24 -0
- data/spec/unit/language/test_ast.rb +4 -4
- data/spec/unit/language/test_elsif_flattener.rb +90 -0
- data/spec/unit/language/test_if_to_case.rb +107 -0
- data/spec/unit/language/{test_transformer.rb → test_rewriter.rb} +24 -11
- data/spec/unit/language/test_syntax.rb +1 -1
- data/spec/unit/language/test_to_graph.rb +9 -2
- metadata +120 -34
- data/lib/gisele/language/syntax/task_refinement.rb +0 -15
- data/lib/gisele/language/syntax/task_signature.rb +0 -15
- data/lib/gisele/language/transformer.rb +0 -38
- data/spec/unit/language/sugar_removal/test_if_to_guarded_commands.rb +0 -110
- data/spec/unit/language/syntax/test_grammar.rb +0 -317
- data/spec/unit/language/syntax/test_to_ast.rb +0 -257
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Gisele::Language::Syntax
|
3
|
+
describe SeqSt, "to_ast" do
|
4
|
+
|
5
|
+
it 'parses as expected' do
|
6
|
+
expr = "seq Task1 Task2 end"
|
7
|
+
expected = [:seq_st, [:task_call_st, "Task1"], [:task_call_st, "Task2"]]
|
8
|
+
ast(expr, :seq_st).should eq(expected)
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Gisele::Language::Syntax
|
3
|
+
describe TaskDef, "to_ast" do
|
4
|
+
|
5
|
+
it 'parses an explicit definition as expected' do
|
6
|
+
expr = <<-EXPR.strip
|
7
|
+
task Task1
|
8
|
+
fluent diagKnown {}, {}
|
9
|
+
Task2
|
10
|
+
end
|
11
|
+
EXPR
|
12
|
+
expected = \
|
13
|
+
[:task_def, "Task1",
|
14
|
+
[:fluent, "diagKnown", [:event_set], [:event_set], nil],
|
15
|
+
[:task_call_st, "Task2"]]
|
16
|
+
ast(expr, :task_def).should eq(expected)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'uses :nop if no statement' do
|
20
|
+
expr = <<-EXPR.strip
|
21
|
+
task Task1
|
22
|
+
fluent diagKnown {}, {}
|
23
|
+
end
|
24
|
+
EXPR
|
25
|
+
expected = \
|
26
|
+
[:task_def, "Task1",
|
27
|
+
[:fluent, "diagKnown", [:event_set], [:event_set], nil],
|
28
|
+
[:nop]]
|
29
|
+
ast(expr, :task_def).should eq(expected)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'uses :nop when empty' do
|
33
|
+
expr = <<-EXPR.strip
|
34
|
+
task Task1
|
35
|
+
end
|
36
|
+
EXPR
|
37
|
+
expected = \
|
38
|
+
[:task_def, "Task1",
|
39
|
+
[:nop]]
|
40
|
+
ast(expr, :task_def).should eq(expected)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Gisele::Language::Syntax
|
3
|
+
describe TrackvarDef, "to_ast" do
|
4
|
+
|
5
|
+
it 'converts tracking variable definitions as expected' do
|
6
|
+
defn = "trackvar mplus {Diagnosis:start}"
|
7
|
+
expected = [:trackvar,
|
8
|
+
"mplus",
|
9
|
+
[:event_set, "Diagnosis:start"],
|
10
|
+
[:event_set],
|
11
|
+
nil]
|
12
|
+
ast(defn, :trackvar_def).should eq(expected)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'supports obsolete events and initial value' do
|
16
|
+
defn = "trackvar mplus {Diagnosis:start}, {Treatment:end} initially true"
|
17
|
+
expected = [:trackvar,
|
18
|
+
"mplus",
|
19
|
+
[:event_set, "Diagnosis:start"],
|
20
|
+
[:event_set, "Treatment:end"],
|
21
|
+
true]
|
22
|
+
ast(defn, :trackvar_def).should eq(expected)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Gisele::Language::Syntax
|
3
|
+
describe UnitDef, 'to_ast' do
|
4
|
+
|
5
|
+
it 'converts a single task definition as expected' do
|
6
|
+
expr = <<-UNIT.strip
|
7
|
+
task Task1 end
|
8
|
+
UNIT
|
9
|
+
expected = \
|
10
|
+
[:unit_def,
|
11
|
+
[:task_def, "Task1", [:nop]]]
|
12
|
+
ast(expr, :unit_def).should eq(expected)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'accepts multiple task definitions' do
|
16
|
+
expr = <<-UNIT.strip
|
17
|
+
task Task1 end
|
18
|
+
task Task2 end
|
19
|
+
UNIT
|
20
|
+
expected = \
|
21
|
+
[:unit_def,
|
22
|
+
[:task_def, "Task1", [:nop]],
|
23
|
+
[:task_def, "Task2", [:nop]] ]
|
24
|
+
ast(expr, :unit_def).should eq(expected)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Gisele::Language::Syntax
|
3
|
+
describe WhenClause, 'to_ast' do
|
4
|
+
|
5
|
+
it 'converts a when clause as expected' do
|
6
|
+
expr = 'when goodCond Task'
|
7
|
+
expected = \
|
8
|
+
[:when_clause,
|
9
|
+
[:bool_expr, [:var_ref, "goodCond"] ],
|
10
|
+
[:task_call_st, "Task"]]
|
11
|
+
ast(expr, :when_clause).should eq(expected)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Gisele::Language::Syntax
|
3
|
+
describe WhileSt, "to_ast" do
|
4
|
+
|
5
|
+
it 'parses as expected' do
|
6
|
+
expr = "while goodCond Task1 end"
|
7
|
+
expected = \
|
8
|
+
[:while_st,
|
9
|
+
[:bool_expr, [:var_ref, "goodCond"]],
|
10
|
+
[:task_call_st, "Task1"]]
|
11
|
+
ast(expr, :while_st).should eq(expected)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'recognizes implicit sequences' do
|
15
|
+
expr = "while goodCond Task1 Task2 end"
|
16
|
+
expected = \
|
17
|
+
[:while_st,
|
18
|
+
[:bool_expr, [:var_ref, "goodCond"]],
|
19
|
+
[:seq_st, [:task_call_st, "Task1"], [:task_call_st, "Task2"]]]
|
20
|
+
ast(expr, :while_st).should eq(expected)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -5,13 +5,13 @@ module Gisele::Language
|
|
5
5
|
describe 'ast' do
|
6
6
|
|
7
7
|
it 'returns a node' do
|
8
|
-
node = [:
|
8
|
+
node = [:unit_def].extend(AST::Node)
|
9
9
|
AST.node(node).object_id.should eq(node.object_id)
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'coerces an array' do
|
13
|
-
AST.node([:
|
14
|
-
AST.node([:
|
13
|
+
AST.node([:unit_def]).should eq([:unit_def])
|
14
|
+
AST.node([:unit_def]).should be_a(AST::UnitDef)
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'falls back to Node' do
|
@@ -20,7 +20,7 @@ module Gisele::Language
|
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'applies coercions recursively' do
|
23
|
-
source = [:
|
23
|
+
source = [:unit_def, [:hello, "world"]]
|
24
24
|
AST.node(source).should eq(source)
|
25
25
|
AST.node(source).last.should be_a(AST::Node)
|
26
26
|
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Gisele::Language
|
3
|
+
describe ElsifFlattener do
|
4
|
+
|
5
|
+
def ast(source)
|
6
|
+
Syntax.ast(source.strip, :root => :if_st)
|
7
|
+
end
|
8
|
+
|
9
|
+
def rewrite(ast)
|
10
|
+
ElsifFlattener.new.call(ast)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'rewrites a single if correctly' do
|
14
|
+
source = ast("if goodCond Task1 end")
|
15
|
+
rewrite(source).should eq(source)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'rewrites a if/else correctly' do
|
19
|
+
source = ast("if goodCond Task1 else Task2 end")
|
20
|
+
rewrite(source).should eq(source)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'rewrites a if/elsif correctly' do
|
24
|
+
source = ast("if good Task1 elsif bad Task2 end")
|
25
|
+
expected = ast("if good Task1 else if bad Task2 end end")
|
26
|
+
rewrite(source).should eq(expected)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'rewrites a if/elsif/else correctly' do
|
30
|
+
source = ast("if good Task1 elsif bad Task2 else Task3 end")
|
31
|
+
expected = ast("if good Task1 else if bad Task2 else Task3 end end")
|
32
|
+
rewrite(source).should eq(expected)
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'rewrites a if/elsif/elsif/else correctly' do
|
36
|
+
source = ast(<<-EOF.strip)
|
37
|
+
if good Task1
|
38
|
+
elsif bad Task2
|
39
|
+
elsif none Task3
|
40
|
+
else Task4
|
41
|
+
end
|
42
|
+
EOF
|
43
|
+
expected = ast(<<-EOF.strip)
|
44
|
+
if good
|
45
|
+
Task1
|
46
|
+
else
|
47
|
+
if bad
|
48
|
+
Task2
|
49
|
+
else
|
50
|
+
if none
|
51
|
+
Task3
|
52
|
+
else
|
53
|
+
Task4
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
EOF
|
58
|
+
rewrite(source).should eq(expected)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'recurses by default' do
|
62
|
+
source = ast(<<-EOF.strip)
|
63
|
+
if goodCond
|
64
|
+
Task1
|
65
|
+
else
|
66
|
+
if bad
|
67
|
+
Task2
|
68
|
+
elsif middle
|
69
|
+
Task3
|
70
|
+
end
|
71
|
+
end
|
72
|
+
EOF
|
73
|
+
expected = ast(<<-EOF.strip)
|
74
|
+
if goodCond
|
75
|
+
Task1
|
76
|
+
else
|
77
|
+
if bad
|
78
|
+
Task2
|
79
|
+
else
|
80
|
+
if middle
|
81
|
+
Task3
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
EOF
|
86
|
+
rewrite(source).should eq(expected)
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module Gisele::Language
|
3
|
+
describe IfToCase do
|
4
|
+
|
5
|
+
def ast(source)
|
6
|
+
Syntax.ast(source.strip, :root => :if_st)
|
7
|
+
end
|
8
|
+
|
9
|
+
def rewrite(ast)
|
10
|
+
IfToCase.new.call(ast)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'rewrites single if correctly' do
|
14
|
+
source = ast("if goodCond Task1 end")
|
15
|
+
expected = \
|
16
|
+
[:case_st, nil,
|
17
|
+
[:when_clause,
|
18
|
+
[:bool_expr, [:var_ref, "goodCond"]],
|
19
|
+
[:task_call_st, "Task1"] ]]
|
20
|
+
rewrite(source).should eq(expected)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'negates the else clause' do
|
24
|
+
source = ast("if goodCond Task1 else Task2 end")
|
25
|
+
expected = \
|
26
|
+
[:case_st, nil,
|
27
|
+
[:when_clause,
|
28
|
+
[:bool_expr, [:var_ref, "goodCond"]],
|
29
|
+
[:task_call_st, "Task1"] ],
|
30
|
+
[:when_clause,
|
31
|
+
[:bool_expr, [:bool_not, [:var_ref, "goodCond"]]],
|
32
|
+
[:task_call_st, "Task2"] ]
|
33
|
+
]
|
34
|
+
rewrite(source).should eq(expected)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'handles elsif clauses correctly' do
|
38
|
+
source = ast(<<-IF)
|
39
|
+
if c1 Task1
|
40
|
+
elsif c2 Task2
|
41
|
+
elsif c3 Task3
|
42
|
+
else Task4
|
43
|
+
end
|
44
|
+
IF
|
45
|
+
expected = \
|
46
|
+
[:case_st, nil,
|
47
|
+
[:when_clause,
|
48
|
+
[:bool_expr, [:var_ref, "c1"]],
|
49
|
+
[:task_call_st, "Task1"] ],
|
50
|
+
[:when_clause,
|
51
|
+
[:bool_expr, [:bool_and,
|
52
|
+
[:var_ref, "c2"],
|
53
|
+
[:bool_not, [:var_ref, "c1"]] ]],
|
54
|
+
[:task_call_st, "Task2"] ],
|
55
|
+
[:when_clause,
|
56
|
+
[:bool_expr, [:bool_and,
|
57
|
+
[:var_ref, "c3"],
|
58
|
+
[:bool_and,
|
59
|
+
[:bool_not, [:var_ref, "c2"]],
|
60
|
+
[:bool_not, [:var_ref, "c1"]] ]]],
|
61
|
+
[:task_call_st, "Task3"] ],
|
62
|
+
[:when_clause,
|
63
|
+
[:bool_expr, [:bool_and,
|
64
|
+
[:bool_not, [:var_ref, "c3"]],
|
65
|
+
[:bool_and,
|
66
|
+
[:bool_not, [:var_ref, "c2"]],
|
67
|
+
[:bool_not, [:var_ref, "c1"]]]]],
|
68
|
+
[:task_call_st, "Task4"] ],
|
69
|
+
]
|
70
|
+
rewrite(source).should eq(expected)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'avoids double negations' do
|
74
|
+
source = ast("if not(goodCond) Task1 else Task2 end")
|
75
|
+
expected = \
|
76
|
+
[:case_st, nil,
|
77
|
+
[:when_clause,
|
78
|
+
[:bool_expr, [:bool_not, [:var_ref, "goodCond"]]],
|
79
|
+
[:task_call_st, "Task1"] ],
|
80
|
+
[:when_clause,
|
81
|
+
[:bool_expr, [:var_ref, "goodCond"]],
|
82
|
+
[:task_call_st, "Task2"] ] ]
|
83
|
+
rewrite(source).should eq(expected)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'recurse on other nodes' do
|
87
|
+
if_st = ast("if goodCond Task1 end")
|
88
|
+
rw_st = rewrite(if_st)
|
89
|
+
rewrite([:unit, if_st]).should eq([:unit, rw_st])
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'keeps traceability markers on a single if' do
|
93
|
+
if_st = ast("if goodCond Task1 end")
|
94
|
+
rw_st = rewrite(if_st)
|
95
|
+
rw_st.markers.should eq(if_st.markers)
|
96
|
+
rw_st.last.markers.should eq(if_st.markers)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'keeps traceability markers when a else if present' do
|
100
|
+
if_st = ast("if goodCond Task1 else Task2 end")
|
101
|
+
rw_st = rewrite(if_st)
|
102
|
+
rw_st.markers.should eq(if_st.markers)
|
103
|
+
rw_st.last.markers.should eq(if_st.last.markers)
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
module Gisele::Language
|
3
|
-
describe
|
3
|
+
describe Rewriter do
|
4
4
|
|
5
|
-
let(:
|
6
|
-
Class.new(
|
5
|
+
let(:rewriter_class){
|
6
|
+
Class.new(Rewriter) do
|
7
7
|
|
8
8
|
def on_hello(node)
|
9
9
|
[:seen_hello, node]
|
@@ -23,33 +23,46 @@ module Gisele::Language
|
|
23
23
|
|
24
24
|
end
|
25
25
|
}
|
26
|
-
let(:
|
26
|
+
let(:rewriter){ rewriter_class.new }
|
27
|
+
|
28
|
+
describe 'mainflow' do
|
29
|
+
|
30
|
+
it 'defaults to self' do
|
31
|
+
rewriter.mainflow.should eq(rewriter)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'may be passed through options' do
|
35
|
+
rw = rewriter_class.new(:mainflow => :hello)
|
36
|
+
rw.mainflow.should eq(:hello)
|
37
|
+
end
|
38
|
+
|
39
|
+
end # mainflow
|
27
40
|
|
28
41
|
describe 'call' do
|
29
42
|
|
30
43
|
it 'dispatches to existing methods' do
|
31
44
|
ast = [:hello, "world"]
|
32
|
-
|
45
|
+
rewriter.call(ast).should eq([:seen_hello, [:hello, "world"]])
|
33
46
|
end
|
34
47
|
|
35
48
|
it 'calls on_missing when not found' do
|
36
49
|
ast = [:nosuchone, "world"]
|
37
|
-
|
50
|
+
rewriter.call(ast).should eq([:seen_missing, [:nosuchone, "world"]])
|
38
51
|
end
|
39
52
|
|
40
53
|
it 'raises unexpected by default in on_missing' do
|
41
54
|
ast = [:nonono, "world"]
|
42
|
-
lambda{
|
55
|
+
lambda{ rewriter.call(ast) }.should raise_error(Gisele::UnexpectedNodeError, /nonono/)
|
43
56
|
end
|
44
57
|
|
45
58
|
it 'performs post node transformation if required' do
|
46
59
|
ast = [:hello, "world"]
|
47
|
-
|
60
|
+
rewriter.call(ast).should be_a(AST::Node)
|
48
61
|
end
|
49
62
|
|
50
63
|
it 'raises an ArgumentError unless called on a non terminal' do
|
51
64
|
lambda{
|
52
|
-
|
65
|
+
rewriter.call("world").should raise_error(ArgumentError, /world/)
|
53
66
|
}
|
54
67
|
end
|
55
68
|
|
@@ -59,10 +72,10 @@ module Gisele::Language
|
|
59
72
|
|
60
73
|
it 'provides a friendly way of applying copy/recurse' do
|
61
74
|
ast = [:copy, [:hello, 'world'], "!"]
|
62
|
-
|
75
|
+
rewriter.call(ast).should eq([:copy, [:seen_hello, [:hello, "world"]], "!"])
|
63
76
|
end
|
64
77
|
|
65
78
|
end
|
66
79
|
|
67
80
|
end
|
68
|
-
end
|
81
|
+
end
|
@@ -40,7 +40,7 @@ module Gisele::Language
|
|
40
40
|
parsed = Syntax.ast(file)
|
41
41
|
parsed.should be_a(Array)
|
42
42
|
parsed.should be_a(AST::Node)
|
43
|
-
parsed.first.should eq(:
|
43
|
+
parsed.first.should eq(:unit_def)
|
44
44
|
if (astfile = file.sub_ext(".ast")).exist?
|
45
45
|
parsed.should eq(Kernel::eval(astfile.read, TOPLEVEL_BINDING, astfile.to_s))
|
46
46
|
end
|
@@ -2,8 +2,15 @@ require 'spec_helper'
|
|
2
2
|
module Gisele::Language
|
3
3
|
describe ToGraph do
|
4
4
|
|
5
|
-
it 'returns a
|
6
|
-
ToGraph.new.call(complete_ast)
|
5
|
+
it 'returns an array of Digraphs when called on a unit_def' do
|
6
|
+
got = ToGraph.new.call(complete_ast)
|
7
|
+
got.should be_a(Array)
|
8
|
+
got.all?{|x| x.is_a? Yargi::Digraph}.should be_true
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'returns a Digraph when called on a task_def' do
|
12
|
+
got = ToGraph.new.call(complete_ast.last)
|
13
|
+
got.should be_a(Yargi::Digraph)
|
7
14
|
end
|
8
15
|
|
9
16
|
end
|