gobstones 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.rubocop.yml +133 -0
- data/.rubocop_todo.yml +75 -0
- data/.simplecov +1 -3
- data/.tool-versions +1 -0
- data/.travis.yml +9 -2
- data/Gemfile +11 -5
- data/Gemfile.lock +65 -39
- data/README.md +8 -1
- data/Rakefile +1 -1
- data/bin/gobstones +1 -1
- data/gobstones.gemspec +12 -11
- data/lib/gobstones/cli/printer.rb +41 -28
- data/lib/gobstones/cli/runner.rb +50 -15
- data/lib/gobstones/extensions/all.rb +1 -1
- data/lib/gobstones/extensions/boolean.rb +1 -5
- data/lib/gobstones/extensions/{fixnum.rb → integer.rb} +2 -4
- data/lib/gobstones/extensions/string.rb +1 -3
- data/lib/gobstones/lang/all.rb +3 -3
- data/lib/gobstones/lang/commands/all.rb +11 -10
- data/lib/gobstones/lang/commands/boom.rb +26 -0
- data/lib/gobstones/lang/commands/command_block.rb +23 -23
- data/lib/gobstones/lang/commands/conditional.rb +26 -0
- data/lib/gobstones/lang/commands/if.rb +13 -0
- data/lib/gobstones/lang/commands/if_then_else.rb +26 -0
- data/lib/gobstones/lang/commands/ir_al_origen.rb +15 -0
- data/lib/gobstones/lang/commands/mover.rb +23 -0
- data/lib/gobstones/lang/commands/multiple_assignment.rb +34 -21
- data/lib/gobstones/lang/commands/poner.rb +31 -0
- data/lib/gobstones/lang/commands/procedure_call.rb +8 -8
- data/lib/gobstones/lang/commands/repeat_with.rb +69 -0
- data/lib/gobstones/lang/commands/sacar.rb +29 -0
- data/lib/gobstones/lang/commands/single_assignment.rb +15 -20
- data/lib/gobstones/lang/commands/skip.rb +15 -0
- data/lib/gobstones/lang/commands/vaciar_tablero.rb +15 -0
- data/lib/gobstones/lang/commands/while.rb +20 -0
- data/lib/gobstones/lang/definitions/definition.rb +16 -23
- data/lib/gobstones/lang/definitions/definition_call.rb +7 -15
- data/lib/gobstones/lang/definitions/function.rb +1 -7
- data/lib/gobstones/lang/definitions/main.rb +1 -8
- data/lib/gobstones/lang/definitions/no_return_statement.rb +2 -8
- data/lib/gobstones/lang/definitions/procedure.rb +1 -7
- data/lib/gobstones/lang/definitions/return_from_function.rb +6 -13
- data/lib/gobstones/lang/definitions/return_from_main.rb +15 -10
- data/lib/gobstones/lang/definitions/var_tuple.rb +10 -12
- data/lib/gobstones/lang/expressions/arithmetic_expressions.rb +17 -27
- data/lib/gobstones/lang/expressions/boolean_expressions.rb +4 -10
- data/lib/gobstones/lang/expressions/comparison_expressions.rb +0 -16
- data/lib/gobstones/lang/expressions/enclosed_by_parens_expression.rb +3 -5
- data/lib/gobstones/lang/expressions/expression.rb +18 -0
- data/lib/gobstones/lang/expressions/function_call.rb +9 -6
- data/lib/gobstones/lang/expressions/one_arg_expression.rb +8 -16
- data/lib/gobstones/lang/expressions/primitive_functions.rb +24 -16
- data/lib/gobstones/lang/expressions/two_arg_expression.rb +9 -16
- data/lib/gobstones/lang/expressions/type_bound_functions.rb +30 -25
- data/lib/gobstones/lang/expressions/var_name.rb +9 -13
- data/lib/gobstones/lang/literals/all.rb +3 -3
- data/lib/gobstones/lang/literals/{booleans.rb → boolean.rb} +24 -22
- data/lib/gobstones/lang/literals/{colors.rb → color.rb} +4 -14
- data/lib/gobstones/lang/literals/{directions.rb → direction.rb} +3 -13
- data/lib/gobstones/lang/literals/literal.rb +35 -27
- data/lib/gobstones/lang/literals/number.rb +6 -8
- data/lib/gobstones/lang/program.rb +9 -16
- data/lib/gobstones/modules/equality_definition.rb +23 -0
- data/lib/gobstones/parser/ast/ast.rb +48 -70
- data/lib/gobstones/parser/parse_error.rb +2 -7
- data/lib/gobstones/parser/treetop_parser.rb +9 -14
- data/lib/gobstones/runner/board.rb +12 -15
- data/lib/gobstones/runner/cell.rb +14 -20
- data/lib/gobstones/runner/errors/all.rb +1 -1
- data/lib/gobstones/runner/errors/boom_error.rb +0 -5
- data/lib/gobstones/runner/errors/definition_not_found_error.rb +7 -7
- data/lib/gobstones/runner/errors/empty_cell_error.rb +0 -5
- data/lib/gobstones/runner/errors/gobstones_runtime_error.rb +0 -5
- data/lib/gobstones/runner/errors/gobstones_type_error.rb +2 -7
- data/lib/gobstones/runner/errors/out_of_board_error.rb +0 -5
- data/lib/gobstones/runner/errors/undefined_variable_error.rb +6 -4
- data/lib/gobstones/runner/errors/wrong_arguments_error.rb +0 -5
- data/lib/gobstones/runner/execution_context.rb +16 -33
- data/lib/gobstones/runner/head.rb +17 -20
- data/lib/gobstones/runner/program_result.rb +12 -0
- data/lib/gobstones/type_check_result.rb +0 -4
- data/spec/lang/commands/boom_spec.rb +7 -0
- data/spec/lang/commands/command_block_spec.rb +15 -0
- data/spec/lang/commands/if_spec.rb +32 -0
- data/spec/lang/commands/if_then_else_spec.rb +19 -0
- data/spec/lang/commands/ir_al_origen_spec.rb +11 -0
- data/spec/lang/commands/mover_spec.rb +30 -0
- data/spec/lang/commands/multiple_assignment_spec.rb +39 -22
- data/spec/lang/commands/poner_spec.rb +27 -0
- data/spec/lang/commands/procedure_call_spec.rb +26 -28
- data/spec/lang/commands/procedure_spec.rb +32 -32
- data/spec/lang/commands/repeat_with_spec.rb +64 -0
- data/spec/lang/commands/sacar_spec.rb +32 -0
- data/spec/lang/commands/single_assignment_spec.rb +5 -6
- data/spec/lang/commands/skip_spec.rb +10 -0
- data/spec/lang/commands/vaciar_tablero_spec.rb +10 -0
- data/spec/lang/commands/while_spec.rb +39 -0
- data/spec/lang/definitions/main_spec.rb +34 -0
- data/spec/lang/definitions/no_return_statement_spec.rb +4 -5
- data/spec/lang/definitions/var_tuple_spec.rb +4 -7
- data/spec/lang/expressions/arithmetic_expressions_spec.rb +37 -64
- data/spec/lang/expressions/boolean_expressions_spec.rb +25 -34
- data/spec/lang/expressions/comparison_expressions_spec.rb +109 -155
- data/spec/lang/expressions/enclosed_by_parens_expression_spec.rb +3 -7
- data/spec/lang/expressions/function_call_spec.rb +24 -20
- data/spec/lang/expressions/primitive_functions_spec.rb +28 -39
- data/spec/lang/expressions/type_bound_functions_spec.rb +10 -18
- data/spec/lang/expressions/var_name_spec.rb +8 -12
- data/spec/lang/literals/{booleans_spec.rb → boolean_spec.rb} +3 -5
- data/spec/lang/literals/color_spec.rb +19 -0
- data/spec/lang/literals/direction_spec.rb +46 -0
- data/spec/lang/literals/{numbers_spec.rb → number_spec.rb} +3 -4
- data/spec/matchers/parse_matcher.rb +9 -11
- data/spec/parser/arithmetic_expressions_spec.rb +51 -61
- data/spec/parser/assignments_spec.rb +21 -31
- data/spec/parser/boolean_expressions_spec.rb +35 -43
- data/spec/parser/command_block_spec.rb +18 -20
- data/spec/parser/data_types_spec.rb +9 -19
- data/spec/parser/function_calls_spec.rb +19 -19
- data/spec/parser/function_definitions_spec.rb +17 -22
- data/spec/parser/gobstones_program_spec.rb +30 -30
- data/spec/parser/if_command_spec.rb +19 -28
- data/spec/parser/main_definition_spec.rb +13 -16
- data/spec/parser/nested_expressions_spec.rb +20 -24
- data/spec/parser/primitive_expressions_spec.rb +33 -38
- data/spec/parser/procedure_calls_spec.rb +17 -18
- data/spec/parser/procedure_definitions_spec.rb +12 -15
- data/spec/parser/repeat_with_command_spec.rb +10 -10
- data/spec/parser/simple_commands_spec.rb +23 -37
- data/spec/parser/treetop_parser_spec.rb +87 -83
- data/spec/parser/var_tuple_spec.rb +8 -12
- data/spec/parser/while_command_spec.rb +11 -14
- data/spec/runner/board_spec.rb +28 -33
- data/spec/runner/cell_spec.rb +21 -28
- data/spec/runner/execution_context_spec.rb +18 -35
- data/spec/runner/head_spec.rb +54 -60
- data/spec/spec_helper.rb +10 -1
- data/spec/support/board_assertions.rb +18 -0
- data/spec/{gobstones_lang_test_objects.rb → support/gobstones_lang_test_objects.rb} +6 -4
- data/spec/type_checker_spec.rb +19 -25
- metadata +80 -56
- data/.ruby-version +0 -1
- data/lib/gobstones/lang/commands/boom_cmd.rb +0 -31
- data/lib/gobstones/lang/commands/conditional_cmd.rb +0 -31
- data/lib/gobstones/lang/commands/if_cmd.rb +0 -38
- data/lib/gobstones/lang/commands/ir_al_origen_cmd.rb +0 -19
- data/lib/gobstones/lang/commands/mover_cmd.rb +0 -27
- data/lib/gobstones/lang/commands/poner_cmd.rb +0 -35
- data/lib/gobstones/lang/commands/repeat_with_cmd.rb +0 -77
- data/lib/gobstones/lang/commands/sacar_cmd.rb +0 -33
- data/lib/gobstones/lang/commands/skip_cmd.rb +0 -19
- data/lib/gobstones/lang/commands/vaciar_tablero_cmd.rb +0 -19
- data/lib/gobstones/lang/commands/while_cmd.rb +0 -25
- data/lib/gobstones/modules/equal_by_class.rb +0 -13
- data/spec/lang/commands/boom_cmd_spec.rb +0 -8
- data/spec/lang/commands/cmd_block_spec.rb +0 -21
- data/spec/lang/commands/if_cmd_spec.rb +0 -50
- data/spec/lang/commands/ir_al_origen_cmd_spec.rb +0 -16
- data/spec/lang/commands/mover_cmd_spec.rb +0 -36
- data/spec/lang/commands/poner_cmd_spec.rb +0 -28
- data/spec/lang/commands/repeat_with_cmd_spec.rb +0 -60
- data/spec/lang/commands/sacar_cmd_spec.rb +0 -35
- data/spec/lang/commands/skip_cmd_spec.rb +0 -12
- data/spec/lang/commands/vaciar_tablero_cmd_spec.rb +0 -14
- data/spec/lang/commands/while_cmd_spec.rb +0 -43
- data/spec/lang/literals/colors_spec.rb +0 -13
- data/spec/lang/literals/directions_spec.rb +0 -45
@@ -1,55 +1,55 @@
|
|
1
|
-
describe Gobstones::Parser,
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
program = Program.new no_definitions, main_def
|
1
|
+
RSpec.describe Gobstones::Parser, 'program definitions' do
|
2
|
+
it 'parses a simple program with a single main' do
|
3
|
+
main_def = Main.new(empty_body, no_return_statement)
|
4
|
+
program = Program.new(no_definitions, main_def)
|
6
5
|
|
7
6
|
expect('procedure Main(){}').to be_parsed_as(:program).and_return(program)
|
8
7
|
end
|
9
8
|
|
10
|
-
it
|
11
|
-
main_def = Main.new
|
12
|
-
proc_1 = Procedure.new
|
13
|
-
proc_2 = Procedure.new
|
14
|
-
program = Program.new
|
9
|
+
it 'parses a program with Main and procedures' do
|
10
|
+
main_def = Main.new(empty_body, no_return_statement)
|
11
|
+
proc_1 = Procedure.new('Procedure1', no_arguments, empty_body)
|
12
|
+
proc_2 = Procedure.new('Procedure2', no_arguments, empty_body)
|
13
|
+
program = Program.new([proc_1, proc_2], main_def)
|
14
|
+
|
15
|
+
gbs_code = <<~GBS
|
16
|
+
procedure Procedure1(){ }
|
15
17
|
|
16
|
-
|
17
|
-
procedure Procedure1(){ }
|
18
|
+
procedure Procedure2 () {}
|
18
19
|
|
19
|
-
procedure
|
20
|
+
procedure Main() {}
|
21
|
+
GBS
|
20
22
|
|
21
|
-
procedure Main() {}
|
22
|
-
GBS
|
23
23
|
expect(gbs_code).to be_parsed_as(:program).and_return(program)
|
24
24
|
end
|
25
25
|
|
26
|
-
it
|
27
|
-
main_def = Main.new
|
28
|
-
proc_1 = Procedure.new
|
29
|
-
func_1 = Function.new
|
30
|
-
proc_2 = Procedure.new
|
31
|
-
program = Program.new
|
32
|
-
gbs_code =
|
33
|
-
procedure Procedure1(){ }
|
26
|
+
it 'parses a program with Main, procedures and functions' do
|
27
|
+
main_def = Main.new(empty_body, no_return_statement)
|
28
|
+
proc_1 = Procedure.new('Procedure1', no_arguments, empty_body)
|
29
|
+
func_1 = Function.new('function1', no_arguments, empty_body, ReturnFromFunction.new([42.to_gbs_num]))
|
30
|
+
proc_2 = Procedure.new('Procedure2', no_arguments, empty_body)
|
31
|
+
program = Program.new([proc_1, func_1, proc_2], main_def)
|
32
|
+
gbs_code = <<~GBS
|
33
|
+
procedure Procedure1(){ }
|
34
34
|
|
35
|
-
function function1() { return (42) }
|
35
|
+
function function1() { return (42) }
|
36
36
|
|
37
|
-
procedure Procedure2 () {}
|
37
|
+
procedure Procedure2 () {}
|
38
|
+
|
39
|
+
procedure Main() {}
|
40
|
+
GBS
|
38
41
|
|
39
|
-
procedure Main() {}
|
40
|
-
GBS
|
41
42
|
expect(gbs_code).to be_parsed_as(:program).and_return(program)
|
42
43
|
end
|
43
44
|
|
44
|
-
it
|
45
|
+
it 'does not parse a program without a Main definition' do
|
45
46
|
expect('procedure Procedure1(){}
|
46
47
|
procedure Procedure2() {}').to be_parsed_as(:program).and_fail
|
47
48
|
end
|
48
49
|
|
49
|
-
it
|
50
|
+
it 'does not parse a program if Main is not the last definition' do
|
50
51
|
expect('procedure Procedure1() {}
|
51
52
|
procedure Main() {}
|
52
53
|
procedure Procedure2() {}').to be_parsed_as(:program).and_fail
|
53
54
|
end
|
54
|
-
|
55
55
|
end
|
@@ -1,9 +1,7 @@
|
|
1
|
-
describe Gobstones::Parser,
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
it "parses a statement with a simple boolean and an empty block" do
|
6
|
-
if_cmd = IfCmd.new true_value, empty_body
|
1
|
+
RSpec.describe Gobstones::Parser, 'if statements' do
|
2
|
+
describe 'if' do
|
3
|
+
it 'parses a statement with a simple boolean and an empty block' do
|
4
|
+
if_cmd = If.new(true_value, empty_body)
|
7
5
|
|
8
6
|
expect('if (True) {}').to be_parsed_as(:command).and_return(if_cmd)
|
9
7
|
expect('if (True) {
|
@@ -12,36 +10,29 @@ describe Gobstones::Parser, "if statements" do
|
|
12
10
|
{}').to be_parsed_as(:command).and_return(if_cmd)
|
13
11
|
end
|
14
12
|
|
15
|
-
it
|
16
|
-
cmd_block = CommandBlock.new
|
17
|
-
if_cmd =
|
13
|
+
it 'parses a statement with a simple boolean and a block with commands' do
|
14
|
+
cmd_block = CommandBlock.new([Poner.new(verde), Skip.new])
|
15
|
+
if_cmd = If.new(false_value, cmd_block)
|
18
16
|
|
19
|
-
expect('if(False){Poner(Verde); Skip}').
|
20
|
-
to be_parsed_as(:command).and_return(if_cmd)
|
17
|
+
expect('if(False){Poner(Verde); Skip}').to be_parsed_as(:command).and_return(if_cmd)
|
21
18
|
end
|
22
19
|
|
23
|
-
it
|
24
|
-
and_expr = And.new
|
25
|
-
inner_and = EnclosedByParensExpression.new
|
26
|
-
exp = Or.new
|
27
|
-
if_cmd =
|
20
|
+
it 'parses a statement with a complex boolean expression' do
|
21
|
+
and_expr = And.new('a'.to_var_name, false_value)
|
22
|
+
inner_and = EnclosedByParensExpression.new(and_expr)
|
23
|
+
exp = Or.new(PuedeMover.new(norte), inner_and)
|
24
|
+
if_cmd = If.new(exp, empty_body)
|
28
25
|
|
29
|
-
expect('if (puedeMover(Norte) || (a && False)) {}').
|
30
|
-
to be_parsed_as(:command).and_return(if_cmd)
|
26
|
+
expect('if (puedeMover(Norte) || (a && False)) {}').to be_parsed_as(:command).and_return(if_cmd)
|
31
27
|
end
|
32
|
-
|
33
28
|
end
|
34
29
|
|
35
|
-
describe
|
30
|
+
describe 'if-else' do
|
31
|
+
it 'parses a statement with an else block' do
|
32
|
+
else_block = CommandBlock.with_just(Mover.new(norte))
|
33
|
+
if_else_cmd = IfThenElse.new(false_value, empty_body, else_block)
|
36
34
|
|
37
|
-
|
38
|
-
else_block = CommandBlock.new [Mover.new(norte)]
|
39
|
-
if_else_cmd = IfElseCmd.new false_value, empty_body, else_block
|
40
|
-
|
41
|
-
expect('if (False) { } else { Mover(Norte) }').
|
42
|
-
to be_parsed_as(:command).and_return(if_else_cmd)
|
35
|
+
expect('if (False) { } else { Mover(Norte) }').to be_parsed_as(:command).and_return(if_else_cmd)
|
43
36
|
end
|
44
|
-
|
45
37
|
end
|
46
|
-
|
47
38
|
end
|
@@ -1,24 +1,22 @@
|
|
1
|
-
describe Gobstones::Parser,
|
1
|
+
RSpec.describe Gobstones::Parser, 'main definition' do
|
2
|
+
let(:return_tuple) { VarTuple.with_names(%w[x y]) }
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
it "parses a valid Main definition without return nor commands" do
|
6
|
-
main = Main.new empty_body, no_return_statement
|
4
|
+
it 'parses a valid Main definition without return nor commands' do
|
5
|
+
main = Main.new(empty_body, no_return_statement)
|
7
6
|
|
8
7
|
expect('procedure Main() {}').to be_parsed_as(:definition).and_fail
|
9
8
|
expect('procedure Main() {}').to be_parsed_as(:main).and_return(main)
|
10
9
|
end
|
11
10
|
|
12
|
-
it
|
13
|
-
main = Main.new
|
11
|
+
it 'parses a valid main procedure with a return of var names' do
|
12
|
+
main = Main.new(empty_body, ReturnFromMain.new(return_tuple))
|
14
13
|
|
15
|
-
expect('procedure Main() { return (x, y); }').
|
16
|
-
to be_parsed_as(:main).and_return(main)
|
14
|
+
expect('procedure Main() { return (x, y); }').to be_parsed_as(:main).and_return(main)
|
17
15
|
end
|
18
16
|
|
19
|
-
it
|
20
|
-
cmd_block = CommandBlock.new
|
21
|
-
main = Main.new
|
17
|
+
it 'parses a valid main procedure with commands and return' do
|
18
|
+
cmd_block = CommandBlock.new([Mover.new(oeste), Skip.new])
|
19
|
+
main = Main.new(cmd_block, ReturnFromMain.new(return_tuple))
|
22
20
|
|
23
21
|
expect('procedure Main() {
|
24
22
|
Mover(Oeste)
|
@@ -27,16 +25,15 @@ describe Gobstones::Parser, "main definition" do
|
|
27
25
|
}').to be_parsed_as(:main).and_return(main)
|
28
26
|
end
|
29
27
|
|
30
|
-
it
|
28
|
+
it 'does not parse a main procedure with an invalid identifier' do
|
31
29
|
expect('procedure NotMain() {}').to be_parsed_as(:main).and_fail
|
32
30
|
end
|
33
31
|
|
34
|
-
it
|
32
|
+
it 'does not parse a main procedure with a return of expressions' do
|
35
33
|
expect('procedure Main() { return (3+4) }').to be_parsed_as(:main).and_fail
|
36
34
|
end
|
37
35
|
|
38
|
-
it
|
36
|
+
it 'does not parse a main procedure with args' do
|
39
37
|
expect('procedure Main(arg1, arg2) {}').to be_parsed_as(:main).and_fail
|
40
38
|
end
|
41
|
-
|
42
39
|
end
|
@@ -1,35 +1,31 @@
|
|
1
|
-
describe Gobstones::Parser,
|
2
|
-
|
3
|
-
|
4
|
-
expect('(
|
5
|
-
|
6
|
-
expect('(
|
7
|
-
and_return(EnclosedByParensExpression.new(true_value))
|
8
|
-
expect('(Rojo )').to be_parsed_as(:expression).
|
9
|
-
and_return(EnclosedByParensExpression.new(rojo))
|
10
|
-
expect('(Verde)').to be_parsed_as(:expression).
|
11
|
-
and_return(EnclosedByParensExpression.new(verde))
|
1
|
+
RSpec.describe Gobstones::Parser, 'nested expressions' do
|
2
|
+
it 'parses literals between ()' do
|
3
|
+
expect('( 42 )').to be_parsed_as(:expression).and_return(EnclosedByParensExpression.new(42.to_gbs_num))
|
4
|
+
expect('(True )').to be_parsed_as(:expression).and_return(EnclosedByParensExpression.new(true_value))
|
5
|
+
expect('(Rojo )').to be_parsed_as(:expression).and_return(EnclosedByParensExpression.new(rojo))
|
6
|
+
expect('(Verde)').to be_parsed_as(:expression).and_return(EnclosedByParensExpression.new(verde))
|
12
7
|
end
|
13
8
|
|
14
|
-
it
|
9
|
+
it 'parses primitive functions between ()' do
|
15
10
|
puede_mover = EnclosedByParensExpression.new(PuedeMover.new(norte))
|
16
|
-
|
17
|
-
|
11
|
+
|
12
|
+
expect('(puedeMover(Norte))').to be_parsed_as(:expression).and_return(puede_mover)
|
18
13
|
end
|
19
14
|
|
20
|
-
it
|
21
|
-
paren_expr = EnclosedByParensExpression.new
|
22
|
-
expected = Mul.new
|
15
|
+
it 'parses nested arithmetic expressions between ()' do
|
16
|
+
paren_expr = EnclosedByParensExpression.new(Add.new(3.to_gbs_num, 5.to_gbs_num))
|
17
|
+
expected = Mul.new(paren_expr, 6.to_gbs_num)
|
18
|
+
|
23
19
|
expect('(3 + 5) * 6').to be_parsed_as(:expression).and_return(expected)
|
24
20
|
end
|
25
21
|
|
26
|
-
it
|
27
|
-
or_expr = Or.new
|
28
|
-
inner_paren = EnclosedByParensExpression.new
|
29
|
-
and_expr = And.new
|
30
|
-
outer_paren = EnclosedByParensExpression.new
|
31
|
-
result = And.new
|
22
|
+
it 'parses a nested expressions with many ()' do
|
23
|
+
or_expr = Or.new('b'.to_var_name, 'c'.to_var_name)
|
24
|
+
inner_paren = EnclosedByParensExpression.new(or_expr)
|
25
|
+
and_expr = And.new('a'.to_var_name, inner_paren)
|
26
|
+
outer_paren = EnclosedByParensExpression.new(and_expr)
|
27
|
+
result = And.new(outer_paren, 'd'.to_var_name)
|
28
|
+
|
32
29
|
expect('(a && (b || c)) && d').to be_parsed_as(:expression).and_return(result)
|
33
30
|
end
|
34
|
-
|
35
31
|
end
|
@@ -1,99 +1,94 @@
|
|
1
|
-
describe Gobstones::Parser,
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
it "parses valid var names" do
|
1
|
+
RSpec.describe Gobstones::Parser, 'primitive expressions' do
|
2
|
+
describe 'variable identifiers' do
|
3
|
+
it 'parses valid var names' do
|
6
4
|
expect('v').to be_parsed_as(:expression).and_return('v'.to_var_name)
|
7
5
|
expect('var1').to be_parsed_as(:expression).and_return('var1'.to_var_name)
|
8
6
|
expect('a_var').to be_parsed_as(:expression).and_return('a_var'.to_var_name)
|
9
7
|
expect('vAR').to be_parsed_as(:expression).and_return('vAR'.to_var_name)
|
10
8
|
end
|
11
9
|
|
12
|
-
it
|
10
|
+
it 'does not parse invalid var names' do
|
13
11
|
expect('1').not_to be_parsed_as(:expression).and_return('1'.to_var_name)
|
14
12
|
expect('_var').to be_parsed_as(:expression).and_fail
|
15
13
|
expect('Var').to be_parsed_as(:expression).and_fail
|
16
14
|
end
|
17
15
|
|
18
|
-
it
|
19
|
-
literals = %w
|
20
|
-
(RESERVED_IDS - literals).each do |id|
|
21
|
-
expect(id).to be_parsed_as(:expression).and_fail
|
22
|
-
end
|
23
|
-
end
|
16
|
+
it 'does not parse reserved words as var names' do
|
17
|
+
literals = %w[True False Rojo Negro Azul Verde Norte Oeste Este Sur]
|
24
18
|
|
19
|
+
expect(RESERVED_IDS - literals).to all(be_parsed_as(:expression).and_fail)
|
20
|
+
end
|
25
21
|
end
|
26
22
|
|
27
|
-
describe
|
28
|
-
|
29
|
-
it "parses the minBool() function" do
|
23
|
+
describe 'type bounds functions' do
|
24
|
+
it 'parses the minBool() function' do
|
30
25
|
expect('minBool()').to be_parsed_as(:expression).and_return(MinBool.new)
|
31
26
|
end
|
32
27
|
|
33
|
-
it
|
28
|
+
it 'parses the maxBool() function' do
|
34
29
|
expect('maxBool()').to be_parsed_as(:expression).and_return(MaxBool.new)
|
35
30
|
end
|
36
31
|
|
37
|
-
it
|
32
|
+
it 'parses the minColor() function' do
|
38
33
|
expect('minColor()').to be_parsed_as(:expression).and_return(MinColor.new)
|
39
34
|
end
|
40
35
|
|
41
|
-
it
|
36
|
+
it 'parses the maxColor() function' do
|
42
37
|
expect('maxColor()').to be_parsed_as(:expression).and_return(MaxColor.new)
|
43
38
|
end
|
44
39
|
|
45
|
-
it
|
40
|
+
it 'parses the minDir() function' do
|
46
41
|
expect('minDir()').to be_parsed_as(:expression).and_return(MinDir.new)
|
47
42
|
end
|
48
43
|
|
49
|
-
it
|
44
|
+
it 'parses the maxDir() function' do
|
50
45
|
expect('maxDir()').to be_parsed_as(:expression).and_return(MaxDir.new)
|
51
46
|
end
|
52
|
-
|
53
47
|
end
|
54
48
|
|
55
|
-
describe
|
49
|
+
describe 'other type functions' do
|
50
|
+
it 'parses the siguiente() function ' do
|
51
|
+
func = Siguiente.new('x'.to_var_name)
|
56
52
|
|
57
|
-
it "parses the siguiente() function " do
|
58
|
-
func = Siguiente.new 'x'.to_var_name
|
59
53
|
expect('siguiente(x)').to be_parsed_as(:expression).and_return(func)
|
60
54
|
expect('siguiente(x )').to be_parsed_as(:expression).and_return(func)
|
61
55
|
end
|
62
56
|
|
63
|
-
it
|
64
|
-
func = Previo.new
|
57
|
+
it 'parses the previo() function' do
|
58
|
+
func = Previo.new('y'.to_var_name)
|
59
|
+
|
65
60
|
expect('previo(y)').to be_parsed_as(:expression).and_return(func)
|
66
61
|
expect('previo( y )').to be_parsed_as(:expression).and_return(func)
|
67
62
|
end
|
68
63
|
|
69
|
-
it
|
70
|
-
func = Opuesto.new
|
64
|
+
it 'parses the opuesto() function' do
|
65
|
+
func = Opuesto.new('z'.to_var_name)
|
66
|
+
|
71
67
|
expect('opuesto(z)').to be_parsed_as(:expression).and_return(func)
|
72
68
|
expect('opuesto( z )').to be_parsed_as(:expression).and_return(func)
|
73
69
|
end
|
74
|
-
|
75
70
|
end
|
76
71
|
|
77
|
-
describe
|
72
|
+
describe 'board primitive functions' do
|
73
|
+
it 'parses the nroBolitas(exp) function' do
|
74
|
+
func = NroBolitas.new('color'.to_var_name)
|
78
75
|
|
79
|
-
it "parses the nroBolitas(exp) function" do
|
80
|
-
func = NroBolitas.new 'color'.to_var_name
|
81
76
|
expect('nroBolitas(color)').to be_parsed_as(:expression).and_return(func)
|
82
77
|
expect('nroBolitas( color )').to be_parsed_as(:expression).and_return(func)
|
83
78
|
end
|
84
79
|
|
85
|
-
it
|
86
|
-
func = HayBolitas.new
|
80
|
+
it 'parses the hayBolitas(exp) function' do
|
81
|
+
func = HayBolitas.new('color'.to_var_name)
|
82
|
+
|
87
83
|
expect('hayBolitas(color)').to be_parsed_as(:expression).and_return(func)
|
88
84
|
expect('hayBolitas( color )').to be_parsed_as(:expression).and_return(func)
|
89
85
|
end
|
90
86
|
|
91
|
-
it
|
92
|
-
func = PuedeMover.new
|
87
|
+
it 'parses the puedeMover(exp) function' do
|
88
|
+
func = PuedeMover.new('dir'.to_var_name)
|
89
|
+
|
93
90
|
expect('puedeMover(dir)').to be_parsed_as(:expression).and_return(func)
|
94
91
|
expect('puedeMover( dir )').to be_parsed_as(:expression).and_return(func)
|
95
92
|
end
|
96
|
-
|
97
93
|
end
|
98
|
-
|
99
94
|
end
|
@@ -1,36 +1,35 @@
|
|
1
|
-
describe Gobstones::Parser,
|
2
|
-
|
3
|
-
it "parses a procedure call without args" do
|
1
|
+
RSpec.describe Gobstones::Parser, 'procedure calls' do
|
2
|
+
it 'parses a procedure call without args' do
|
4
3
|
expect('P1()').to be_parsed_as(:command).and_return(ProcedureCall.new('P1'))
|
5
4
|
end
|
6
5
|
|
7
|
-
it
|
6
|
+
it 'does not parse a procedure call without a valid identifier' do
|
8
7
|
expect('p1()').to be_parsed_as(:command).and_fail
|
9
8
|
end
|
10
9
|
|
11
|
-
it
|
12
|
-
expected = ProcedureCall.new
|
10
|
+
it 'parses a procedure call with one arg' do
|
11
|
+
expected = ProcedureCall.new('Proc1', [verde])
|
12
|
+
|
13
13
|
expect('Proc1(Verde)').to be_parsed_as(:command).and_return(expected)
|
14
14
|
end
|
15
15
|
|
16
|
-
it
|
16
|
+
it 'parses a procedure with many args' do
|
17
17
|
first_arg = 42.to_gbs_num
|
18
|
-
second_arg = NroBolitas.new
|
18
|
+
second_arg = NroBolitas.new(verde)
|
19
19
|
third_arg = norte
|
20
|
-
expected = ProcedureCall.new
|
20
|
+
expected = ProcedureCall.new('Proc1', [first_arg, second_arg, third_arg])
|
21
21
|
|
22
|
-
expect('Proc1(42, nroBolitas(Verde), Norte)').
|
23
|
-
to be_parsed_as(:command).and_return(expected)
|
22
|
+
expect('Proc1(42, nroBolitas(Verde), Norte)').to be_parsed_as(:command).and_return(expected)
|
24
23
|
end
|
25
24
|
|
26
|
-
it
|
27
|
-
or_expr = Or.new
|
28
|
-
paren_expr = EnclosedByParensExpression.new
|
29
|
-
num_expr = Mul.new
|
30
|
-
func_call = FunctionCall.new
|
31
|
-
proc_call = ProcedureCall.new
|
25
|
+
it 'parses a complex procedure call' do
|
26
|
+
or_expr = Or.new('a'.to_var_name, 'b'.to_var_name)
|
27
|
+
paren_expr = EnclosedByParensExpression.new(Div.new(10.to_gbs_num, 'c'.to_var_name))
|
28
|
+
num_expr = Mul.new(5.to_gbs_num, paren_expr)
|
29
|
+
func_call = FunctionCall.new('func', [verde, Opuesto.new(norte)])
|
30
|
+
proc_call = ProcedureCall.new('Proc1', [or_expr, num_expr, func_call])
|
31
|
+
|
32
32
|
expect('Proc1(a || b, 5*(10 div c), func(Verde, opuesto(Norte)))').
|
33
33
|
to be_parsed_as(:command).and_return(proc_call)
|
34
34
|
end
|
35
|
-
|
36
35
|
end
|