gobstones 0.0.1.1
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.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/.simplecov +3 -0
- data/.travis.yml +4 -0
- data/CHANGELOG +4 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +47 -0
- data/LICENSE +675 -0
- data/README.md +17 -0
- data/Rakefile +4 -0
- data/bin/gobstones +12 -0
- data/gobstones.gemspec +24 -0
- data/lib/gobstones/cli/board_template +39 -0
- data/lib/gobstones/cli/printer.rb +106 -0
- data/lib/gobstones/cli/runner.rb +52 -0
- data/lib/gobstones/extensions/all.rb +2 -0
- data/lib/gobstones/extensions/boolean.rb +17 -0
- data/lib/gobstones/extensions/fixnum.rb +9 -0
- data/lib/gobstones/lang/all.rb +5 -0
- data/lib/gobstones/lang/commands/all.rb +13 -0
- data/lib/gobstones/lang/commands/assignments.rb +29 -0
- data/lib/gobstones/lang/commands/boom_cmd.rb +28 -0
- data/lib/gobstones/lang/commands/command_block.rb +37 -0
- data/lib/gobstones/lang/commands/conditional_cmd.rb +27 -0
- data/lib/gobstones/lang/commands/if_cmd.rb +38 -0
- data/lib/gobstones/lang/commands/ir_al_origen_cmd.rb +19 -0
- data/lib/gobstones/lang/commands/mover_cmd.rb +25 -0
- data/lib/gobstones/lang/commands/poner_cmd.rb +31 -0
- data/lib/gobstones/lang/commands/procedure_call.rb +23 -0
- data/lib/gobstones/lang/commands/repeat_with_cmd.rb +73 -0
- data/lib/gobstones/lang/commands/sacar_cmd.rb +31 -0
- data/lib/gobstones/lang/commands/skip_cmd.rb +19 -0
- data/lib/gobstones/lang/commands/vaciar_tablero_cmd.rb +19 -0
- data/lib/gobstones/lang/commands/while_cmd.rb +25 -0
- data/lib/gobstones/lang/definitions/all.rb +4 -0
- data/lib/gobstones/lang/definitions/definition.rb +32 -0
- data/lib/gobstones/lang/definitions/definition_call.rb +24 -0
- data/lib/gobstones/lang/definitions/function.rb +14 -0
- data/lib/gobstones/lang/definitions/main.rb +26 -0
- data/lib/gobstones/lang/definitions/no_return_statement.rb +15 -0
- data/lib/gobstones/lang/definitions/procedure.rb +44 -0
- data/lib/gobstones/lang/definitions/return_from_function.rb +22 -0
- data/lib/gobstones/lang/definitions/return_from_main.rb +22 -0
- data/lib/gobstones/lang/definitions/var_tuple.rb +26 -0
- data/lib/gobstones/lang/expressions/all.rb +8 -0
- data/lib/gobstones/lang/expressions/arithmetic_expressions.rb +52 -0
- data/lib/gobstones/lang/expressions/boolean_expressions.rb +29 -0
- data/lib/gobstones/lang/expressions/comparison_expressions.rb +45 -0
- data/lib/gobstones/lang/expressions/function_call.rb +15 -0
- data/lib/gobstones/lang/expressions/one_arg_expression.rb +21 -0
- data/lib/gobstones/lang/expressions/parentheses_expression.rb +13 -0
- data/lib/gobstones/lang/expressions/primitive_functions.rb +68 -0
- data/lib/gobstones/lang/expressions/two_arg_expression.rb +34 -0
- data/lib/gobstones/lang/expressions/type_bound_functions.rb +66 -0
- data/lib/gobstones/lang/expressions/var_name.rb +31 -0
- data/lib/gobstones/lang/literals/all.rb +4 -0
- data/lib/gobstones/lang/literals/booleans.rb +109 -0
- data/lib/gobstones/lang/literals/colors.rb +94 -0
- data/lib/gobstones/lang/literals/directions.rb +137 -0
- data/lib/gobstones/lang/literals/literal.rb +63 -0
- data/lib/gobstones/lang/literals/number.rb +49 -0
- data/lib/gobstones/lang/program.rb +32 -0
- data/lib/gobstones/modules/equal_by_class.rb +13 -0
- data/lib/gobstones/parser/ast/ast.rb +210 -0
- data/lib/gobstones/parser/grammar/gobstones.treetop +316 -0
- data/lib/gobstones/parser/parse_error.rb +17 -0
- data/lib/gobstones/parser/treetop_parser.rb +73 -0
- data/lib/gobstones/runner/all.rb +6 -0
- data/lib/gobstones/runner/board.rb +57 -0
- data/lib/gobstones/runner/cell.rb +60 -0
- data/lib/gobstones/runner/errors/all.rb +8 -0
- data/lib/gobstones/runner/errors/boom_error.rb +11 -0
- data/lib/gobstones/runner/errors/definition_not_found_error.rb +19 -0
- data/lib/gobstones/runner/errors/empty_cell_error.rb +11 -0
- data/lib/gobstones/runner/errors/gobstones_runtime_error.rb +11 -0
- data/lib/gobstones/runner/errors/gobstones_type_error.rb +11 -0
- data/lib/gobstones/runner/errors/out_of_board_error.rb +11 -0
- data/lib/gobstones/runner/errors/undefined_variable_error.rb +11 -0
- data/lib/gobstones/runner/errors/wrong_arguments_error.rb +11 -0
- data/lib/gobstones/runner/execution_context.rb +89 -0
- data/lib/gobstones/runner/head.rb +101 -0
- data/lib/gobstones/type_check_result.rb +16 -0
- data/spec/lang/commands/assignments_spec.rb +13 -0
- data/spec/lang/commands/boom_cmd_spec.rb +8 -0
- data/spec/lang/commands/cmd_block_spec.rb +21 -0
- data/spec/lang/commands/if_cmd_spec.rb +49 -0
- data/spec/lang/commands/ir_al_origen_cmd_spec.rb +16 -0
- data/spec/lang/commands/mover_cmd_spec.rb +38 -0
- data/spec/lang/commands/poner_cmd_spec.rb +29 -0
- data/spec/lang/commands/procedure_call_spec.rb +44 -0
- data/spec/lang/commands/procedure_spec.rb +67 -0
- data/spec/lang/commands/repeat_with_cmd_spec.rb +41 -0
- data/spec/lang/commands/sacar_cmd_spec.rb +34 -0
- data/spec/lang/commands/skip_cmd_spec.rb +12 -0
- data/spec/lang/commands/vaciar_tablero_cmd_spec.rb +13 -0
- data/spec/lang/commands/while_cmd_spec.rb +37 -0
- data/spec/lang/expressions/arithmetic_expressions_spec.rb +108 -0
- data/spec/lang/expressions/boolean_expressions_spec.rb +56 -0
- data/spec/lang/expressions/comparison_expressions_spec.rb +285 -0
- data/spec/lang/expressions/primitive_functions_spec.rb +126 -0
- data/spec/lang/expressions/type_bound_functions_spec.rb +39 -0
- data/spec/lang/expressions/var_name_spec.rb +16 -0
- data/spec/lang/literals/booleans_spec.rb +13 -0
- data/spec/lang/literals/colors_spec.rb +13 -0
- data/spec/lang/literals/directions_spec.rb +45 -0
- data/spec/lang/literals/numbers_spec.rb +8 -0
- data/spec/matchers/parse_matcher.rb +84 -0
- data/spec/parser/arithmetic_expressions_spec.rb +129 -0
- data/spec/parser/assignments_spec.rb +39 -0
- data/spec/parser/boolean_expressions_spec.rb +111 -0
- data/spec/parser/command_block_spec.rb +50 -0
- data/spec/parser/data_types_spec.rb +67 -0
- data/spec/parser/function_calls_spec.rb +37 -0
- data/spec/parser/function_definitions_spec.rb +50 -0
- data/spec/parser/gobstones_program_spec.rb +55 -0
- data/spec/parser/if_command_spec.rb +46 -0
- data/spec/parser/main_definition_spec.rb +42 -0
- data/spec/parser/nested_expressions_spec.rb +39 -0
- data/spec/parser/primitive_expressions_spec.rb +105 -0
- data/spec/parser/procedure_calls_spec.rb +36 -0
- data/spec/parser/procedure_definitions_spec.rb +39 -0
- data/spec/parser/repeat_with_command_spec.rb +23 -0
- data/spec/parser/simple_commands_spec.rb +62 -0
- data/spec/parser/treetop_parser_spec.rb +109 -0
- data/spec/parser/var_tuple_spec.rb +30 -0
- data/spec/parser/while_command_spec.rb +30 -0
- data/spec/runner/board_spec.rb +85 -0
- data/spec/runner/cell_spec.rb +72 -0
- data/spec/runner/execution_context_spec.rb +64 -0
- data/spec/runner/head_spec.rb +139 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/type_checker_spec.rb +37 -0
- metadata +242 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
describe Gobstones::Parser, "main definition" do
|
2
|
+
|
3
|
+
it "should parse a valid Main definition without return nor commands" do
|
4
|
+
main = Main.new CmdBlock.new([]), NoReturnStatement.new
|
5
|
+
|
6
|
+
expect('procedure Main() {}').to be_parsed_as(:definition).and_fail
|
7
|
+
expect('procedure Main() {}').to be_parsed_as(:main).and_return(main)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should parse a valid main procedure with a return of var names" do
|
11
|
+
return_tuple = VarTuple.new [VarName.new('x'), VarName.new('y')]
|
12
|
+
main = Main.new CmdBlock.new([]), ReturnFromMain.new(return_tuple)
|
13
|
+
|
14
|
+
expect('procedure Main() { return (x, y); }').
|
15
|
+
to be_parsed_as(:main).and_return(main)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should parse a valid main procedure with commands and return" do
|
19
|
+
return_tuple = VarTuple.new [VarName.new('x'), VarName.new('y')]
|
20
|
+
cmd_block = CmdBlock.new [Mover.new(Oeste.new), Skip.new]
|
21
|
+
main = Main.new cmd_block, ReturnFromMain.new(return_tuple)
|
22
|
+
|
23
|
+
expect('procedure Main() {
|
24
|
+
Mover(Oeste)
|
25
|
+
Skip
|
26
|
+
return (x, y)
|
27
|
+
}').to be_parsed_as(:main).and_return(main)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should not parse a main procedure with an invalid identifier" do
|
31
|
+
expect('procedure NotMain() {}').to be_parsed_as(:main).and_fail
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should not parse a main procedure with a return of expressions" do
|
35
|
+
expect('procedure Main() { return (3+4) }').to be_parsed_as(:main).and_fail
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should not parse a main procedure with args" do
|
39
|
+
expect('procedure Main(arg1, arg2) {}').to be_parsed_as(:main).and_fail
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
describe Gobstones::Parser, "nested expressions" do
|
2
|
+
|
3
|
+
it "should parse literals between ()" do
|
4
|
+
expect('( 42 )').to be_parsed_as(:expression).
|
5
|
+
and_return(ParenthesesExpr.new(42.to_gbs_num))
|
6
|
+
expect('(True )').to be_parsed_as(:expression).
|
7
|
+
and_return(ParenthesesExpr.new(True.new))
|
8
|
+
expect('(Rojo )').to be_parsed_as(:expression).
|
9
|
+
and_return(ParenthesesExpr.new(Rojo.new))
|
10
|
+
expect('(Verde)').to be_parsed_as(:expression).
|
11
|
+
and_return(ParenthesesExpr.new(Verde.new))
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should parse primitive functions between ()" do
|
15
|
+
puede_mover = ParenthesesExpr.new(PuedeMover.new(Norte.new))
|
16
|
+
expect('(puedeMover(Norte))').
|
17
|
+
to be_parsed_as(:expression).and_return(puede_mover)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should parse nested arithmetic expressions between ()" do
|
21
|
+
paren_expr = ParenthesesExpr.new Add.new(3.to_gbs_num, 5.to_gbs_num)
|
22
|
+
expected = Mul.new paren_expr, 6.to_gbs_num
|
23
|
+
expect('(3 + 5) * 6').to be_parsed_as(:expression).and_return(expected)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should parse a nested expressions with many ()" do
|
27
|
+
b = VarName.new 'b'
|
28
|
+
c = VarName.new 'c'
|
29
|
+
or_expr = Or.new b, c
|
30
|
+
a = VarName.new 'a'
|
31
|
+
inner_paren = ParenthesesExpr.new or_expr
|
32
|
+
and_expr = And.new a, inner_paren
|
33
|
+
outer_paren = ParenthesesExpr.new and_expr
|
34
|
+
d = VarName.new 'd'
|
35
|
+
result = And.new outer_paren, d
|
36
|
+
expect('(a && (b || c)) && d').to be_parsed_as(:expression).and_return(result)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
describe Gobstones::Parser, "primitive expressions" do
|
2
|
+
|
3
|
+
describe "variable identifiers" do
|
4
|
+
|
5
|
+
it "should parse valid var names" do
|
6
|
+
expect('v').to be_parsed_as(:expression).and_return(VarName.new('v'))
|
7
|
+
expect('var1').to be_parsed_as(:expression).and_return(VarName.new('var1'))
|
8
|
+
expect('a_var').to be_parsed_as(:expression).and_return(VarName.new('a_var'))
|
9
|
+
expect('vAR').to be_parsed_as(:expression).and_return(VarName.new('vAR'))
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should not parse invalid var names" do
|
13
|
+
expect('1').not_to be_parsed_as(:expression).and_return(VarName.new('1'))
|
14
|
+
expect('_var').to be_parsed_as(:expression).and_fail
|
15
|
+
expect('Var').to be_parsed_as(:expression).and_fail
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should not parse reserved words as var names" do
|
19
|
+
literals = %w{True False Rojo Negro Azul Verde Norte Oeste Este Sur}
|
20
|
+
(RESERVED_IDS - literals).each do |id|
|
21
|
+
expect(id).to be_parsed_as(:expression).and_fail
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "type bounds functions" do
|
28
|
+
|
29
|
+
it "should parse the minBool() function" do
|
30
|
+
expect('minBool()').to be_parsed_as(:expression).and_return(MinBool.new)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should parse the maxBool() function" do
|
34
|
+
expect('maxBool()').to be_parsed_as(:expression).and_return(MaxBool.new)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should parse the minColor() function" do
|
38
|
+
expect('minColor()').to be_parsed_as(:expression).and_return(MinColor.new)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should parse the maxColor() function" do
|
42
|
+
expect('maxColor()').to be_parsed_as(:expression).and_return(MaxColor.new)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should parse the minDir() function" do
|
46
|
+
expect('minDir()').to be_parsed_as(:expression).and_return(MinDir.new)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should parse the maxDir() function" do
|
50
|
+
expect('maxDir()').to be_parsed_as(:expression).and_return(MaxDir.new)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "other type functions" do
|
56
|
+
|
57
|
+
it "should parse the siguiente() function " do
|
58
|
+
arg = VarName.new 'x'
|
59
|
+
func = Siguiente.new arg
|
60
|
+
expect('siguiente(x)').to be_parsed_as(:expression).and_return(func)
|
61
|
+
expect('siguiente(x )').to be_parsed_as(:expression).and_return(func)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should parse the previo() function" do
|
65
|
+
arg = VarName.new 'y'
|
66
|
+
func = Previo.new arg
|
67
|
+
expect('previo(y)').to be_parsed_as(:expression).and_return(func)
|
68
|
+
expect('previo( y )').to be_parsed_as(:expression).and_return(func)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should parse the opuesto() function" do
|
72
|
+
arg = VarName.new 'z'
|
73
|
+
func = Opuesto.new arg
|
74
|
+
expect('opuesto(z)').to be_parsed_as(:expression).and_return(func)
|
75
|
+
expect('opuesto( z )').to be_parsed_as(:expression).and_return(func)
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "board primitive functions" do
|
81
|
+
|
82
|
+
it "should parse the nroBolitas(exp) function" do
|
83
|
+
arg = VarName.new 'color'
|
84
|
+
func = NroBolitas.new arg
|
85
|
+
expect('nroBolitas(color)').to be_parsed_as(:expression).and_return(func)
|
86
|
+
expect('nroBolitas( color )').to be_parsed_as(:expression).and_return(func)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should parse the hayBolitas(exp) function" do
|
90
|
+
arg = VarName.new 'color'
|
91
|
+
func = HayBolitas.new arg
|
92
|
+
expect('hayBolitas(color)').to be_parsed_as(:expression).and_return(func)
|
93
|
+
expect('hayBolitas( color )').to be_parsed_as(:expression).and_return(func)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should parse the puedeMover(exp) function" do
|
97
|
+
arg = VarName.new 'dir'
|
98
|
+
func = PuedeMover.new arg
|
99
|
+
expect('puedeMover(dir)').to be_parsed_as(:expression).and_return(func)
|
100
|
+
expect('puedeMover( dir )').to be_parsed_as(:expression).and_return(func)
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
describe Gobstones::Parser, "procedure calls" do
|
2
|
+
|
3
|
+
it "should parse a procedure call without args" do
|
4
|
+
expect('P1()').to be_parsed_as(:command).and_return(ProcedureCall.new('P1'))
|
5
|
+
end
|
6
|
+
|
7
|
+
it "should not parse a procedure call without a valid identifier" do
|
8
|
+
expect('p1()').to be_parsed_as(:command).and_fail
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should parse a procedure call with one arg" do
|
12
|
+
expected = ProcedureCall.new 'Proc1', [Verde.new]
|
13
|
+
expect('Proc1(Verde)').to be_parsed_as(:command).and_return(expected)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should parse a procedure with many args" do
|
17
|
+
first_arg = 42.to_gbs_num
|
18
|
+
second_arg = NroBolitas.new Verde.new
|
19
|
+
third_arg = Norte.new
|
20
|
+
expected = ProcedureCall.new 'Proc1', [first_arg, second_arg, third_arg]
|
21
|
+
|
22
|
+
expect('Proc1(42, nroBolitas(Verde), Norte)').
|
23
|
+
to be_parsed_as(:command).and_return(expected)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should parse a complex procedure call" do
|
27
|
+
or_expr = Or.new VarName.new('a'), VarName.new('b')
|
28
|
+
paren_expr = ParenthesesExpr.new Div.new(10.to_gbs_num, VarName.new('c'))
|
29
|
+
num_expr = Mul.new 5.to_gbs_num, paren_expr
|
30
|
+
func_call = FunctionCall.new 'func', [Verde.new, Opuesto.new(Norte.new)]
|
31
|
+
proc_call = ProcedureCall.new 'Proc1', [or_expr, num_expr, func_call]
|
32
|
+
expect('Proc1(a || b, 5*(10 div c), func(Verde, opuesto(Norte)))').
|
33
|
+
to be_parsed_as(:command).and_return(proc_call)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
describe Gobstones::Parser, "procedure definitions" do
|
2
|
+
|
3
|
+
let(:body) { CmdBlock.empty }
|
4
|
+
|
5
|
+
it "should parse an empty procedure def without args" do
|
6
|
+
args = VarTuple.new []
|
7
|
+
proc_def = Procedure.new 'MyProc', args, body
|
8
|
+
|
9
|
+
expect('procedure MyProc() {}').
|
10
|
+
to be_parsed_as(:definition).and_return(proc_def)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should parse an empty procedure with some args" do
|
14
|
+
first_arg = VarName.new 'firstArg'
|
15
|
+
second_arg = VarName.new 'secondArg'
|
16
|
+
third_arg = VarName.new 'thirdArg'
|
17
|
+
args = VarTuple.new [first_arg, second_arg, third_arg]
|
18
|
+
proc_def = Procedure.new 'MyProc', args, body
|
19
|
+
|
20
|
+
expect('procedure MyProc (firstArg, secondArg, thirdArg) {}').
|
21
|
+
to be_parsed_as(:definition).and_return(proc_def)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should parse a procedure with some statements" do
|
25
|
+
args = VarTuple.new [VarName.new('arg')]
|
26
|
+
body = CmdBlock.new [Poner.new(Verde.new)]
|
27
|
+
proc_def = Procedure.new 'MyProc', args, body
|
28
|
+
|
29
|
+
expect('procedure MyProc(arg)
|
30
|
+
{
|
31
|
+
Poner(Verde)
|
32
|
+
}').to be_parsed_as(:definition).and_return(proc_def)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should not parse a procedure without a valid identifier" do
|
36
|
+
expect('procedure myWrongProc() {}').to be_parsed_as(:definition).and_fail
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
describe Gobstones::Parser, "repeatWith statements" do
|
2
|
+
|
3
|
+
it "should parse an empty statement" do
|
4
|
+
var_name = VarName.new 'i'
|
5
|
+
min_range, max_range = 1.to_gbs_num, 10.to_gbs_num
|
6
|
+
cmd_block = CmdBlock.empty
|
7
|
+
rw_cmd = RepeatWithCmd.new var_name, min_range, max_range, cmd_block
|
8
|
+
|
9
|
+
expect('repeatWith i in 1..10 {}').to be_parsed_as(:command).and_return(rw_cmd)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should parse an statement with any expressions in the range" do
|
13
|
+
var_name = VarName.new 'myDir'
|
14
|
+
min_range, max_range = MinDir.new, Siguiente.new(Rojo.new)
|
15
|
+
cmd_block = CmdBlock.new [Poner.new(Verde.new)]
|
16
|
+
rw_cmd = RepeatWithCmd.new var_name, min_range, max_range, cmd_block
|
17
|
+
|
18
|
+
expect('repeatWith myDir in minDir() .. siguiente(Rojo) {
|
19
|
+
Poner(Verde)
|
20
|
+
}').to be_parsed_as(:command).and_return(rw_cmd)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'gobstones/lang/commands/ir_al_origen_cmd'
|
2
|
+
require 'gobstones/lang/commands/vaciar_tablero_cmd'
|
3
|
+
|
4
|
+
describe Gobstones::Parser, "simple commands" do
|
5
|
+
|
6
|
+
describe "primitives" do
|
7
|
+
|
8
|
+
it "should parse a Skip cmd" do
|
9
|
+
skip_cmd = Skip.new
|
10
|
+
expect('Skip').to be_parsed_as(:command).and_return(skip_cmd)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should parse a BOOM cmd" do
|
14
|
+
boom_cmd = Boom.new 'the message'
|
15
|
+
expect('BOOM("the message")').to be_parsed_as(:command).and_return(boom_cmd)
|
16
|
+
expect('BOOM ("the message")').to be_parsed_as(:command).and_return(boom_cmd)
|
17
|
+
expect('BOOM( "the message" )').to be_parsed_as(:command).and_return(boom_cmd)
|
18
|
+
end
|
19
|
+
|
20
|
+
['Poner', 'Sacar', 'Mover'].each do |command|
|
21
|
+
|
22
|
+
describe "#{command}() cmd" do
|
23
|
+
|
24
|
+
it "should be parsed ok with a primitive as argument" do
|
25
|
+
cmd = Kernel.const_get(command).new Verde.new
|
26
|
+
expect("#{command}(Verde)").to be_parsed_as(:command).and_return(cmd)
|
27
|
+
expect("#{command} (Verde)").to be_parsed_as(:command).and_return(cmd)
|
28
|
+
expect("#{command}( Verde )").to be_parsed_as(:command).and_return(cmd)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should be parsed ok with a simple expression as argument" do
|
32
|
+
cmd = Kernel.const_get(command).new MinColor.new
|
33
|
+
expect("#{command}(minColor())").
|
34
|
+
to be_parsed_as(:command).and_return(cmd)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should be parsed ok with a complex expression as argument" do
|
38
|
+
func_call = FunctionCall.new 'funcCall', [Norte.new, 42.to_gbs_num]
|
39
|
+
cmd = Kernel.const_get(command).new Opuesto.new(func_call)
|
40
|
+
expect("#{command}(opuesto(funcCall(Norte, 42)))").
|
41
|
+
to be_parsed_as(:command).and_return(cmd)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should parse a IrAlOrigen cmd" do
|
49
|
+
ir_al_origen_cmd = IrAlOrigen.new
|
50
|
+
expect('IrAlOrigen()').to be_parsed_as(:command).
|
51
|
+
and_return(ir_al_origen_cmd)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should parse a VaciarTablero cmd" do
|
55
|
+
vaciar_tablero_cmd = VaciarTablero.new
|
56
|
+
expect('VaciarTablero()').to be_parsed_as(:command).
|
57
|
+
and_return(vaciar_tablero_cmd)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
describe Gobstones::Parser do
|
2
|
+
|
3
|
+
before(:all) { @parser = TreetopParser.new }
|
4
|
+
|
5
|
+
describe "removing comments of a gobstones piece of code" do
|
6
|
+
|
7
|
+
it "should remove a one-line comment with // characters for a single line" do
|
8
|
+
code_with_comments = 'Poner(Verde) // put a green ball on the board'
|
9
|
+
code_without_comments = @parser.remove_comments_from code_with_comments
|
10
|
+
expect(code_without_comments).to eq('Poner(Verde) ')
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should remove many one-line comments with //" do
|
14
|
+
code_with_comments = <<CODE
|
15
|
+
Poner(Verde) // put a green ball on the board
|
16
|
+
Poner(Azul) // and a blue one
|
17
|
+
// and this is just an entire comment line
|
18
|
+
CODE
|
19
|
+
code_without_comments = @parser.remove_comments_from code_with_comments
|
20
|
+
expect(code_without_comments).to eq <<CODE
|
21
|
+
Poner(Verde)
|
22
|
+
Poner(Azul)
|
23
|
+
|
24
|
+
CODE
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should remove a one-line comment with -- for a single line" do
|
28
|
+
code_with_comments = 'Poner(Verde) -- put a green ball on the board'
|
29
|
+
code_without_comments = @parser.remove_comments_from code_with_comments
|
30
|
+
expect(code_without_comments).to eq('Poner(Verde) ')
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should remove many one-line comments with --" do
|
34
|
+
code_with_comments = <<CODE
|
35
|
+
Poner(Verde) -- put a green ball on the board
|
36
|
+
Poner(Azul) -- and a blue one
|
37
|
+
-- and this is just an entire comment line
|
38
|
+
CODE
|
39
|
+
code_without_comments = @parser.remove_comments_from code_with_comments
|
40
|
+
expect(code_without_comments).to eq <<CODE
|
41
|
+
Poner(Verde)
|
42
|
+
Poner(Azul)
|
43
|
+
|
44
|
+
CODE
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should remove many one-line comments with // and --" do
|
48
|
+
code_with_comments = <<CODE
|
49
|
+
Poner(Verde) // put a green ball on the board
|
50
|
+
Poner(Azul) -- and a blue one
|
51
|
+
// and this is just an entire comment line
|
52
|
+
if (puedeMover(Norte)) { Mover(Norte) } -- another -- comment
|
53
|
+
CODE
|
54
|
+
code_without_comments = @parser.remove_comments_from code_with_comments
|
55
|
+
expect(code_without_comments).to eq <<CODE
|
56
|
+
Poner(Verde)
|
57
|
+
Poner(Azul)
|
58
|
+
|
59
|
+
if (puedeMover(Norte)) { Mover(Norte) }
|
60
|
+
CODE
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should remove a multiline comment with {- -}" do
|
64
|
+
code_with_comments = 'Poner(Verde) {- this is a comment -}'
|
65
|
+
code_without_comments = @parser.remove_comments_from code_with_comments
|
66
|
+
expect(code_without_comments).to eq('Poner(Verde) ')
|
67
|
+
|
68
|
+
end
|
69
|
+
it "should remove many multiline comments with {- -}, in same and different lines" do
|
70
|
+
code_with_comments = <<CODE
|
71
|
+
Poner(Verde) {- comment 1 -}
|
72
|
+
Poner(Azul) {- start comment 2
|
73
|
+
// and this is just an entire comment line
|
74
|
+
if (puedeMover(Norte)) { Mover(Norte) -}
|
75
|
+
Poner(Rojo)
|
76
|
+
CODE
|
77
|
+
code_without_comments = @parser.remove_comments_from code_with_comments
|
78
|
+
expect(code_without_comments).to eq <<CODE
|
79
|
+
Poner(Verde)
|
80
|
+
Poner(Azul)
|
81
|
+
Poner(Rojo)
|
82
|
+
CODE
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should remove a multiline comment with /* */" do
|
86
|
+
code_with_comments = 'Poner(Verde) /* this is a comment */'
|
87
|
+
code_without_comments = @parser.remove_comments_from code_with_comments
|
88
|
+
expect(code_without_comments).to eq('Poner(Verde) ')
|
89
|
+
|
90
|
+
end
|
91
|
+
it "should remove many multiline comments with /* */, in same and different lines" do
|
92
|
+
code_with_comments = <<CODE
|
93
|
+
Poner(Verde) /* comment 1 */
|
94
|
+
Poner(Azul) /* start comment 2
|
95
|
+
// and this is just an entire comment line
|
96
|
+
if (puedeMover(Norte)) { Mover(Norte) */
|
97
|
+
Poner(Rojo)
|
98
|
+
CODE
|
99
|
+
code_without_comments = @parser.remove_comments_from code_with_comments
|
100
|
+
expect(code_without_comments).to eq <<CODE
|
101
|
+
Poner(Verde)
|
102
|
+
Poner(Azul)
|
103
|
+
Poner(Rojo)
|
104
|
+
CODE
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|