gobstones 0.0.2 → 0.0.3
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 +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,24 +1,22 @@
|
|
1
|
-
describe Gobstones::Parser,
|
1
|
+
RSpec.describe Gobstones::Parser, 'procedure definitions' do
|
2
|
+
it 'parses an empty procedure def without args' do
|
3
|
+
proc_def = Procedure.new('MyProc', no_arguments, empty_body)
|
2
4
|
|
3
|
-
|
4
|
-
proc_def = Procedure.new 'MyProc', no_arguments, empty_body
|
5
|
-
|
6
|
-
expect('procedure MyProc() {}').
|
7
|
-
to be_parsed_as(:definition).and_return(proc_def)
|
5
|
+
expect('procedure MyProc() {}').to be_parsed_as(:definition).and_return(proc_def)
|
8
6
|
end
|
9
7
|
|
10
|
-
it
|
11
|
-
args = VarTuple.
|
12
|
-
proc_def = Procedure.new
|
8
|
+
it 'parses an empty procedure with some args' do
|
9
|
+
args = VarTuple.with_names(%w[firstArg secondArg thirdArg])
|
10
|
+
proc_def = Procedure.new('MyProc', args, empty_body)
|
13
11
|
|
14
12
|
expect('procedure MyProc (firstArg, secondArg, thirdArg) {}').
|
15
13
|
to be_parsed_as(:definition).and_return(proc_def)
|
16
14
|
end
|
17
15
|
|
18
|
-
it
|
19
|
-
args = VarTuple.
|
20
|
-
body = CommandBlock.
|
21
|
-
proc_def = Procedure.new
|
16
|
+
it 'parses a procedure with some statements' do
|
17
|
+
args = VarTuple.with_names(%w[arg])
|
18
|
+
body = CommandBlock.with_just(Poner.new(verde))
|
19
|
+
proc_def = Procedure.new('MyProc', args, body)
|
22
20
|
|
23
21
|
expect('procedure MyProc(arg)
|
24
22
|
{
|
@@ -26,8 +24,7 @@ describe Gobstones::Parser, "procedure definitions" do
|
|
26
24
|
}').to be_parsed_as(:definition).and_return(proc_def)
|
27
25
|
end
|
28
26
|
|
29
|
-
it
|
27
|
+
it 'does not parse a procedure without a valid identifier' do
|
30
28
|
expect('procedure myWrongProc() {}').to be_parsed_as(:definition).and_fail
|
31
29
|
end
|
32
|
-
|
33
30
|
end
|
@@ -1,20 +1,20 @@
|
|
1
|
-
describe Gobstones::Parser,
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
rw_cmd =
|
1
|
+
RSpec.describe Gobstones::Parser, 'repeatWith statements' do
|
2
|
+
it 'parses an empty statement' do
|
3
|
+
min_range = 1.to_gbs_num
|
4
|
+
max_range = 10.to_gbs_num
|
5
|
+
rw_cmd = RepeatWith.new('i'.to_var_name, min_range, max_range, empty_body)
|
6
6
|
|
7
7
|
expect('repeatWith i in 1..10 {}').to be_parsed_as(:command).and_return(rw_cmd)
|
8
8
|
end
|
9
9
|
|
10
|
-
it
|
11
|
-
min_range
|
12
|
-
|
13
|
-
|
10
|
+
it 'parses an statement with any expressions in the range' do
|
11
|
+
min_range = MinDir.new
|
12
|
+
max_range = Siguiente.new(rojo)
|
13
|
+
cmd_block = CommandBlock.with_just(Poner.new(verde))
|
14
|
+
rw_cmd = RepeatWith.new('myDir'.to_var_name, min_range, max_range, cmd_block)
|
14
15
|
|
15
16
|
expect('repeatWith myDir in minDir() .. siguiente(Rojo) {
|
16
17
|
Poner(Verde)
|
17
18
|
}').to be_parsed_as(:command).and_return(rw_cmd)
|
18
19
|
end
|
19
|
-
|
20
20
|
end
|
@@ -1,62 +1,48 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
describe "primitives" do
|
7
|
-
|
8
|
-
it "parses a Skip cmd" do
|
9
|
-
skip_cmd = Skip.new
|
10
|
-
expect('Skip').to be_parsed_as(:command).and_return(skip_cmd)
|
1
|
+
RSpec.describe Gobstones::Parser, 'simple commands' do
|
2
|
+
describe 'primitives' do
|
3
|
+
it 'parses a Skip cmd' do
|
4
|
+
expect('Skip').to be_parsed_as(:command).and_return(Skip.new)
|
11
5
|
end
|
12
6
|
|
13
|
-
it
|
14
|
-
boom_cmd = Boom.new
|
7
|
+
it 'parses a BOOM cmd' do
|
8
|
+
boom_cmd = Boom.new('the message')
|
9
|
+
|
15
10
|
expect('BOOM("the message")').to be_parsed_as(:command).and_return(boom_cmd)
|
16
11
|
expect('BOOM ("the message")').to be_parsed_as(:command).and_return(boom_cmd)
|
17
12
|
expect('BOOM( "the message" )').to be_parsed_as(:command).and_return(boom_cmd)
|
18
13
|
end
|
19
14
|
|
20
|
-
[
|
21
|
-
|
15
|
+
%w[Poner Sacar Mover].each do |command|
|
22
16
|
describe "#{command}() cmd" do
|
17
|
+
it 'is parsed ok with a primitive as argument' do
|
18
|
+
cmd = Kernel.const_get(command).new(verde)
|
23
19
|
|
24
|
-
it "is parsed ok with a primitive as argument" do
|
25
|
-
cmd = Kernel.const_get(command).new verde
|
26
20
|
expect("#{command}(Verde)").to be_parsed_as(:command).and_return(cmd)
|
27
21
|
expect("#{command} (Verde)").to be_parsed_as(:command).and_return(cmd)
|
28
22
|
expect("#{command}( Verde )").to be_parsed_as(:command).and_return(cmd)
|
29
23
|
end
|
30
24
|
|
31
|
-
it
|
32
|
-
cmd = Kernel.const_get(command).new
|
33
|
-
expect("#{command}(minColor())").
|
34
|
-
to be_parsed_as(:command).and_return(cmd)
|
35
|
-
end
|
25
|
+
it 'is parsed ok with a simple expression as argument' do
|
26
|
+
cmd = Kernel.const_get(command).new(MinColor.new)
|
36
27
|
|
37
|
-
|
38
|
-
func_call = FunctionCall.new 'funcCall', [norte, 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)
|
28
|
+
expect("#{command}(minColor())").to be_parsed_as(:command).and_return(cmd)
|
42
29
|
end
|
43
30
|
|
44
|
-
|
31
|
+
it 'is parsed ok with a complex expression as argument' do
|
32
|
+
func_call = FunctionCall.new('funcCall', [norte, 42.to_gbs_num])
|
33
|
+
cmd = Kernel.const_get(command).new(Opuesto.new(func_call))
|
45
34
|
|
35
|
+
expect("#{command}(opuesto(funcCall(Norte, 42)))").to be_parsed_as(:command).and_return(cmd)
|
36
|
+
end
|
37
|
+
end
|
46
38
|
end
|
47
39
|
|
48
|
-
it
|
49
|
-
|
50
|
-
expect('IrAlOrigen()').to be_parsed_as(:command).
|
51
|
-
and_return(ir_al_origen_cmd)
|
40
|
+
it 'parses a IrAlOrigen cmd' do
|
41
|
+
expect('IrAlOrigen()').to be_parsed_as(:command).and_return(IrAlOrigen.new)
|
52
42
|
end
|
53
43
|
|
54
|
-
it
|
55
|
-
|
56
|
-
expect('VaciarTablero()').to be_parsed_as(:command).
|
57
|
-
and_return(vaciar_tablero_cmd)
|
44
|
+
it 'parses a VaciarTablero cmd' do
|
45
|
+
expect('VaciarTablero()').to be_parsed_as(:command).and_return(VaciarTablero.new)
|
58
46
|
end
|
59
|
-
|
60
47
|
end
|
61
|
-
|
62
48
|
end
|
@@ -1,110 +1,114 @@
|
|
1
|
-
describe Gobstones::Parser do
|
1
|
+
RSpec.describe Gobstones::Parser do
|
2
|
+
let_it_be(:parser) { TreetopParser.new }
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
describe "removing comments of a gobstones piece of code" do
|
6
|
-
|
7
|
-
it "removes a one-line comment with // characters for a single line" do
|
4
|
+
describe 'removing comments of a gobstones piece of code' do
|
5
|
+
it 'removes a one-line comment with // characters for a single line' do
|
8
6
|
code_with_comments = 'Poner(Verde) // put a green ball on the board'
|
9
|
-
code_without_comments =
|
7
|
+
code_without_comments = parser.remove_comments_from(code_with_comments)
|
8
|
+
|
10
9
|
expect(code_without_comments).to eq('Poner(Verde) ')
|
11
10
|
end
|
12
11
|
|
13
|
-
it
|
14
|
-
code_with_comments =
|
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 =
|
20
|
-
|
21
|
-
|
22
|
-
Poner(
|
23
|
-
|
24
|
-
|
12
|
+
it 'removes many one-line comments with //' do
|
13
|
+
code_with_comments = <<~CODE
|
14
|
+
Poner(Verde) // put a green ball on the board
|
15
|
+
Poner(Azul) // and a blue one
|
16
|
+
// and this is just an entire comment line
|
17
|
+
CODE
|
18
|
+
code_without_comments = parser.remove_comments_from(code_with_comments)
|
19
|
+
|
20
|
+
expect(code_without_comments).to eq <<~CODE
|
21
|
+
Poner(Verde)
|
22
|
+
Poner(Azul)
|
23
|
+
|
24
|
+
CODE
|
25
25
|
end
|
26
26
|
|
27
|
-
it
|
27
|
+
it 'removes a one-line comment with -- for a single line' do
|
28
28
|
code_with_comments = 'Poner(Verde) -- put a green ball on the board'
|
29
|
-
code_without_comments =
|
29
|
+
code_without_comments = parser.remove_comments_from(code_with_comments)
|
30
|
+
|
30
31
|
expect(code_without_comments).to eq('Poner(Verde) ')
|
31
32
|
end
|
32
33
|
|
33
|
-
it
|
34
|
-
code_with_comments =
|
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 =
|
40
|
-
|
41
|
-
|
42
|
-
Poner(
|
43
|
-
|
44
|
-
|
34
|
+
it 'removes many one-line comments with --' do
|
35
|
+
code_with_comments = <<~CODE
|
36
|
+
Poner(Verde) -- put a green ball on the board
|
37
|
+
Poner(Azul) -- and a blue one
|
38
|
+
-- and this is just an entire comment line
|
39
|
+
CODE
|
40
|
+
code_without_comments = parser.remove_comments_from(code_with_comments)
|
41
|
+
|
42
|
+
expect(code_without_comments).to eq <<~CODE
|
43
|
+
Poner(Verde)
|
44
|
+
Poner(Azul)
|
45
|
+
|
46
|
+
CODE
|
45
47
|
end
|
46
48
|
|
47
|
-
it
|
48
|
-
code_with_comments =
|
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 =
|
55
|
-
|
56
|
-
|
57
|
-
Poner(
|
58
|
-
|
59
|
-
|
60
|
-
|
49
|
+
it 'removes many one-line comments with // and --' do
|
50
|
+
code_with_comments = <<~CODE
|
51
|
+
Poner(Verde) // put a green ball on the board
|
52
|
+
Poner(Azul) -- and a blue one
|
53
|
+
// and this is just an entire comment line
|
54
|
+
if (puedeMover(Norte)) { Mover(Norte) } -- another -- comment
|
55
|
+
CODE
|
56
|
+
code_without_comments = parser.remove_comments_from(code_with_comments)
|
57
|
+
|
58
|
+
expect(code_without_comments).to eq <<~CODE
|
59
|
+
Poner(Verde)
|
60
|
+
Poner(Azul)
|
61
|
+
|
62
|
+
if (puedeMover(Norte)) { Mover(Norte) }
|
63
|
+
CODE
|
61
64
|
end
|
62
65
|
|
63
|
-
it
|
66
|
+
it 'removes a multiline comment with {- -}' do
|
64
67
|
code_with_comments = 'Poner(Verde) {- this is a comment -}'
|
65
|
-
code_without_comments =
|
66
|
-
expect(code_without_comments).to eq('Poner(Verde) ')
|
68
|
+
code_without_comments = parser.remove_comments_from(code_with_comments)
|
67
69
|
|
70
|
+
expect(code_without_comments).to eq('Poner(Verde) ')
|
68
71
|
end
|
69
72
|
|
70
|
-
it
|
71
|
-
code_with_comments =
|
72
|
-
Poner(Verde) {- comment 1 -}
|
73
|
-
Poner(Azul) {- start comment 2
|
74
|
-
// and this is just an entire comment line
|
75
|
-
if (puedeMover(Norte)) { Mover(Norte) -}
|
76
|
-
Poner(Rojo)
|
77
|
-
CODE
|
78
|
-
code_without_comments =
|
79
|
-
|
80
|
-
|
81
|
-
Poner(
|
82
|
-
Poner(
|
83
|
-
|
73
|
+
it 'removes many multiline comments with {- -}, in same and different lines' do
|
74
|
+
code_with_comments = <<~CODE
|
75
|
+
Poner(Verde) {- comment 1 -}
|
76
|
+
Poner(Azul) {- start comment 2
|
77
|
+
// and this is just an entire comment line
|
78
|
+
if (puedeMover(Norte)) { Mover(Norte) -}
|
79
|
+
Poner(Rojo)
|
80
|
+
CODE
|
81
|
+
code_without_comments = parser.remove_comments_from(code_with_comments)
|
82
|
+
|
83
|
+
expect(code_without_comments).to eq <<~CODE
|
84
|
+
Poner(Verde)
|
85
|
+
Poner(Azul)
|
86
|
+
Poner(Rojo)
|
87
|
+
CODE
|
84
88
|
end
|
85
89
|
|
86
|
-
it
|
90
|
+
it 'removes a multiline comment with /* */' do
|
87
91
|
code_with_comments = 'Poner(Verde) /* this is a comment */'
|
88
|
-
code_without_comments =
|
89
|
-
expect(code_without_comments).to eq('Poner(Verde) ')
|
92
|
+
code_without_comments = parser.remove_comments_from(code_with_comments)
|
90
93
|
|
91
|
-
|
92
|
-
it "removes many multiline comments with /* */, in same and different lines" do
|
93
|
-
code_with_comments = <<CODE
|
94
|
-
Poner(Verde) /* comment 1 */
|
95
|
-
Poner(Azul) /* start comment 2
|
96
|
-
// and this is just an entire comment line
|
97
|
-
if (puedeMover(Norte)) { Mover(Norte) */
|
98
|
-
Poner(Rojo)
|
99
|
-
CODE
|
100
|
-
code_without_comments = @parser.remove_comments_from code_with_comments
|
101
|
-
expect(code_without_comments).to eq <<CODE
|
102
|
-
Poner(Verde)
|
103
|
-
Poner(Azul)
|
104
|
-
Poner(Rojo)
|
105
|
-
CODE
|
94
|
+
expect(code_without_comments).to eq('Poner(Verde) ')
|
106
95
|
end
|
107
96
|
|
97
|
+
it 'removes many multiline comments with /* */, in same and different lines' do
|
98
|
+
code_with_comments = <<~CODE
|
99
|
+
Poner(Verde) /* comment 1 */
|
100
|
+
Poner(Azul) /* start comment 2
|
101
|
+
// and this is just an entire comment line
|
102
|
+
if (puedeMover(Norte)) { Mover(Norte) */
|
103
|
+
Poner(Rojo)
|
104
|
+
CODE
|
105
|
+
code_without_comments = parser.remove_comments_from(code_with_comments)
|
106
|
+
|
107
|
+
expect(code_without_comments).to eq <<~CODE
|
108
|
+
Poner(Verde)
|
109
|
+
Poner(Azul)
|
110
|
+
Poner(Rojo)
|
111
|
+
CODE
|
112
|
+
end
|
108
113
|
end
|
109
|
-
|
110
114
|
end
|
@@ -1,26 +1,22 @@
|
|
1
|
-
describe Gobstones::Parser,
|
2
|
-
|
3
|
-
it "parses an empty var tuple" do
|
1
|
+
RSpec.describe Gobstones::Parser, 'var tuples' do
|
2
|
+
it 'parses an empty var tuple' do
|
4
3
|
var_tuple = VarTuple.empty
|
5
4
|
|
6
5
|
expect('()').to be_parsed_as(:var_tuple).and_return(var_tuple)
|
7
6
|
expect('( )').to be_parsed_as(:var_tuple).and_return(var_tuple)
|
8
7
|
end
|
9
8
|
|
10
|
-
it
|
11
|
-
var_tuple = VarTuple.
|
9
|
+
it 'parses a var tuple with one arg' do
|
10
|
+
var_tuple = VarTuple.with_names(%w[myVar])
|
12
11
|
|
13
12
|
expect('(myVar)').to be_parsed_as(:var_tuple).and_return(var_tuple)
|
14
13
|
expect('( myVar )').to be_parsed_as(:var_tuple).and_return(var_tuple)
|
15
14
|
end
|
16
15
|
|
17
|
-
it
|
18
|
-
var_tuple = VarTuple.
|
16
|
+
it 'parses a var tuple with many args' do
|
17
|
+
var_tuple = VarTuple.with_names(%w[firstVar secondVar thirdVar])
|
19
18
|
|
20
|
-
expect('(firstVar, secondVar, thirdVar)').
|
21
|
-
|
22
|
-
expect('( firstVar , secondVar,thirdVar )').
|
23
|
-
to be_parsed_as(:var_tuple).and_return(var_tuple)
|
19
|
+
expect('(firstVar, secondVar, thirdVar)').to be_parsed_as(:var_tuple).and_return(var_tuple)
|
20
|
+
expect('( firstVar , secondVar,thirdVar )').to be_parsed_as(:var_tuple).and_return(var_tuple)
|
24
21
|
end
|
25
|
-
|
26
22
|
end
|
@@ -1,7 +1,6 @@
|
|
1
|
-
describe Gobstones::Parser,
|
2
|
-
|
3
|
-
|
4
|
-
while_cmd = WhileCmd.new true_value, empty_body
|
1
|
+
RSpec.describe Gobstones::Parser, 'while statements' do
|
2
|
+
it 'parses a statement with a simple boolean and an empty block' do
|
3
|
+
while_cmd = While.new(true_value, empty_body)
|
5
4
|
|
6
5
|
expect('while (True) {}').to be_parsed_as(:command).and_return(while_cmd)
|
7
6
|
expect('while (True) {
|
@@ -10,21 +9,19 @@ describe Gobstones::Parser, "while statements" do
|
|
10
9
|
{}').to be_parsed_as(:command).and_return(while_cmd)
|
11
10
|
end
|
12
11
|
|
13
|
-
it
|
14
|
-
cmd_block = CommandBlock.new
|
15
|
-
while_cmd =
|
12
|
+
it 'parses a statement with a simple boolean and a block with commands' do
|
13
|
+
cmd_block = CommandBlock.new([Poner.new(verde), Skip.new])
|
14
|
+
while_cmd = While.new(false_value, cmd_block)
|
16
15
|
|
17
|
-
expect('while(False){Poner(Verde); Skip}').
|
18
|
-
to be_parsed_as(:command).and_return(while_cmd)
|
16
|
+
expect('while(False){Poner(Verde); Skip}').to be_parsed_as(:command).and_return(while_cmd)
|
19
17
|
end
|
20
18
|
|
21
|
-
it
|
22
|
-
and_expr = And.new
|
23
|
-
exp = Or.new
|
24
|
-
while_cmd =
|
19
|
+
it 'parses a statement with a complex boolean expression' do
|
20
|
+
and_expr = And.new('a'.to_var_name, false_value)
|
21
|
+
exp = Or.new(PuedeMover.new(norte), EnclosedByParensExpression.new(and_expr))
|
22
|
+
while_cmd = While.new(exp, empty_body)
|
25
23
|
|
26
24
|
expect('while (puedeMover(Norte) || (a && False)) {}').
|
27
25
|
to be_parsed_as(:command).and_return(while_cmd)
|
28
26
|
end
|
29
|
-
|
30
27
|
end
|
data/spec/runner/board_spec.rb
CHANGED
@@ -1,31 +1,29 @@
|
|
1
|
-
describe Board do
|
1
|
+
RSpec.describe Board do
|
2
|
+
it 'can be created with a number of rows and columns' do
|
3
|
+
board = described_class.new(8, 5)
|
2
4
|
|
3
|
-
let(:colors) { [azul, negro, rojo, verde] }
|
4
|
-
|
5
|
-
it "can be created with a number of rows and columns" do
|
6
|
-
board = Board.new 8, 5
|
7
5
|
expect(board.rows).to eq(8)
|
8
6
|
expect(board.columns).to eq(5)
|
9
7
|
end
|
10
8
|
|
11
|
-
it
|
12
|
-
board =
|
9
|
+
it 'has cells in every position' do
|
10
|
+
board = described_class.new(3, 3)
|
13
11
|
|
14
12
|
board.each_cell { |cell| expect(cell).to be_a(Cell) }
|
15
13
|
end
|
16
14
|
|
17
|
-
it
|
18
|
-
board =
|
15
|
+
it 'accesses cells in a x&y dimension' do
|
16
|
+
board = described_class.new(3, 5)
|
19
17
|
|
20
18
|
3.times do |x|
|
21
19
|
5.times do |y|
|
22
|
-
expect(board.cell_at(x, y)).
|
20
|
+
expect(board.cell_at(x, y)).not_to be_nil
|
23
21
|
end
|
24
22
|
end
|
25
23
|
end
|
26
24
|
|
27
|
-
it
|
28
|
-
board =
|
25
|
+
it 'raises errors if it is accessed out of the bounds' do
|
26
|
+
board = described_class.new(9, 6)
|
29
27
|
|
30
28
|
expect { board.cell_at(9, 4) }.to raise_error(OutOfBoardError)
|
31
29
|
expect { board.cell_at(3, 6) }.to raise_error(OutOfBoardError)
|
@@ -33,49 +31,46 @@ describe Board do
|
|
33
31
|
expect { board.cell_at(8, -1) }.to raise_error(OutOfBoardError)
|
34
32
|
end
|
35
33
|
|
36
|
-
it
|
37
|
-
board =
|
34
|
+
it 'puts balls in a given position' do
|
35
|
+
board = described_class.new(5, 5)
|
38
36
|
|
39
37
|
2.times { board.put 0, 0, azul }
|
40
38
|
10.times { board.put 2, 3, rojo }
|
41
39
|
|
42
|
-
expect(board.are_there_balls?(0, 0, azul)).to be
|
40
|
+
expect(board.are_there_balls?(0, 0, azul)).to be(true)
|
43
41
|
expect(board.number_of_balls(0, 0, azul)).to eq(2)
|
44
|
-
expect(board.are_there_balls?(2, 3, rojo)).to be
|
42
|
+
expect(board.are_there_balls?(2, 3, rojo)).to be(true)
|
45
43
|
expect(board.number_of_balls(2, 3, rojo)).to eq(10)
|
46
44
|
end
|
47
45
|
|
48
|
-
it
|
49
|
-
board =
|
46
|
+
it 'puts and takes out balls in a given position' do
|
47
|
+
board = described_class.new(2, 2)
|
50
48
|
|
51
49
|
3.times { board.put 1, 1, verde }
|
52
50
|
3.times { board.take_out 1, 1, verde }
|
53
51
|
|
54
|
-
expect(board.are_there_balls?(1, 1, verde)).to be
|
52
|
+
expect(board.are_there_balls?(1, 1, verde)).to be(false)
|
55
53
|
end
|
56
54
|
|
57
|
-
it
|
58
|
-
board =
|
55
|
+
it 'clears the entire board' do
|
56
|
+
board = described_class.new(3, 4)
|
59
57
|
board.each_cell { |cell| cell.put colors.sample }
|
60
58
|
|
61
59
|
board.empty!
|
62
60
|
|
63
|
-
board.each_cell
|
64
|
-
colors.each do |color|
|
65
|
-
expect(cell.are_there_balls?(color)).to be false
|
66
|
-
end
|
67
|
-
end
|
61
|
+
board.each_cell { |cell| expect_no_balls(*colors, on: cell) }
|
68
62
|
end
|
69
63
|
|
70
|
-
it
|
71
|
-
board =
|
72
|
-
|
64
|
+
it 'is empty if there are no balls' do
|
65
|
+
board = described_class.new(3, 4)
|
66
|
+
|
67
|
+
expect(board).to be_empty
|
73
68
|
end
|
74
69
|
|
75
|
-
it
|
76
|
-
board =
|
70
|
+
it 'is not empty if there are balls' do
|
71
|
+
board = described_class.new(3, 4)
|
77
72
|
board.put 0, 0, negro
|
78
|
-
expect(board.empty?).to be false
|
79
|
-
end
|
80
73
|
|
74
|
+
expect(board).not_to be_empty
|
75
|
+
end
|
81
76
|
end
|