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,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
|