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.
Files changed (168) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +133 -0
  3. data/.rubocop_todo.yml +75 -0
  4. data/.simplecov +1 -3
  5. data/.tool-versions +1 -0
  6. data/.travis.yml +9 -2
  7. data/Gemfile +11 -5
  8. data/Gemfile.lock +65 -39
  9. data/README.md +8 -1
  10. data/Rakefile +1 -1
  11. data/bin/gobstones +1 -1
  12. data/gobstones.gemspec +12 -11
  13. data/lib/gobstones/cli/printer.rb +41 -28
  14. data/lib/gobstones/cli/runner.rb +50 -15
  15. data/lib/gobstones/extensions/all.rb +1 -1
  16. data/lib/gobstones/extensions/boolean.rb +1 -5
  17. data/lib/gobstones/extensions/{fixnum.rb → integer.rb} +2 -4
  18. data/lib/gobstones/extensions/string.rb +1 -3
  19. data/lib/gobstones/lang/all.rb +3 -3
  20. data/lib/gobstones/lang/commands/all.rb +11 -10
  21. data/lib/gobstones/lang/commands/boom.rb +26 -0
  22. data/lib/gobstones/lang/commands/command_block.rb +23 -23
  23. data/lib/gobstones/lang/commands/conditional.rb +26 -0
  24. data/lib/gobstones/lang/commands/if.rb +13 -0
  25. data/lib/gobstones/lang/commands/if_then_else.rb +26 -0
  26. data/lib/gobstones/lang/commands/ir_al_origen.rb +15 -0
  27. data/lib/gobstones/lang/commands/mover.rb +23 -0
  28. data/lib/gobstones/lang/commands/multiple_assignment.rb +34 -21
  29. data/lib/gobstones/lang/commands/poner.rb +31 -0
  30. data/lib/gobstones/lang/commands/procedure_call.rb +8 -8
  31. data/lib/gobstones/lang/commands/repeat_with.rb +69 -0
  32. data/lib/gobstones/lang/commands/sacar.rb +29 -0
  33. data/lib/gobstones/lang/commands/single_assignment.rb +15 -20
  34. data/lib/gobstones/lang/commands/skip.rb +15 -0
  35. data/lib/gobstones/lang/commands/vaciar_tablero.rb +15 -0
  36. data/lib/gobstones/lang/commands/while.rb +20 -0
  37. data/lib/gobstones/lang/definitions/definition.rb +16 -23
  38. data/lib/gobstones/lang/definitions/definition_call.rb +7 -15
  39. data/lib/gobstones/lang/definitions/function.rb +1 -7
  40. data/lib/gobstones/lang/definitions/main.rb +1 -8
  41. data/lib/gobstones/lang/definitions/no_return_statement.rb +2 -8
  42. data/lib/gobstones/lang/definitions/procedure.rb +1 -7
  43. data/lib/gobstones/lang/definitions/return_from_function.rb +6 -13
  44. data/lib/gobstones/lang/definitions/return_from_main.rb +15 -10
  45. data/lib/gobstones/lang/definitions/var_tuple.rb +10 -12
  46. data/lib/gobstones/lang/expressions/arithmetic_expressions.rb +17 -27
  47. data/lib/gobstones/lang/expressions/boolean_expressions.rb +4 -10
  48. data/lib/gobstones/lang/expressions/comparison_expressions.rb +0 -16
  49. data/lib/gobstones/lang/expressions/enclosed_by_parens_expression.rb +3 -5
  50. data/lib/gobstones/lang/expressions/expression.rb +18 -0
  51. data/lib/gobstones/lang/expressions/function_call.rb +9 -6
  52. data/lib/gobstones/lang/expressions/one_arg_expression.rb +8 -16
  53. data/lib/gobstones/lang/expressions/primitive_functions.rb +24 -16
  54. data/lib/gobstones/lang/expressions/two_arg_expression.rb +9 -16
  55. data/lib/gobstones/lang/expressions/type_bound_functions.rb +30 -25
  56. data/lib/gobstones/lang/expressions/var_name.rb +9 -13
  57. data/lib/gobstones/lang/literals/all.rb +3 -3
  58. data/lib/gobstones/lang/literals/{booleans.rb → boolean.rb} +24 -22
  59. data/lib/gobstones/lang/literals/{colors.rb → color.rb} +4 -14
  60. data/lib/gobstones/lang/literals/{directions.rb → direction.rb} +3 -13
  61. data/lib/gobstones/lang/literals/literal.rb +35 -27
  62. data/lib/gobstones/lang/literals/number.rb +6 -8
  63. data/lib/gobstones/lang/program.rb +9 -16
  64. data/lib/gobstones/modules/equality_definition.rb +23 -0
  65. data/lib/gobstones/parser/ast/ast.rb +48 -70
  66. data/lib/gobstones/parser/parse_error.rb +2 -7
  67. data/lib/gobstones/parser/treetop_parser.rb +9 -14
  68. data/lib/gobstones/runner/board.rb +12 -15
  69. data/lib/gobstones/runner/cell.rb +14 -20
  70. data/lib/gobstones/runner/errors/all.rb +1 -1
  71. data/lib/gobstones/runner/errors/boom_error.rb +0 -5
  72. data/lib/gobstones/runner/errors/definition_not_found_error.rb +7 -7
  73. data/lib/gobstones/runner/errors/empty_cell_error.rb +0 -5
  74. data/lib/gobstones/runner/errors/gobstones_runtime_error.rb +0 -5
  75. data/lib/gobstones/runner/errors/gobstones_type_error.rb +2 -7
  76. data/lib/gobstones/runner/errors/out_of_board_error.rb +0 -5
  77. data/lib/gobstones/runner/errors/undefined_variable_error.rb +6 -4
  78. data/lib/gobstones/runner/errors/wrong_arguments_error.rb +0 -5
  79. data/lib/gobstones/runner/execution_context.rb +16 -33
  80. data/lib/gobstones/runner/head.rb +17 -20
  81. data/lib/gobstones/runner/program_result.rb +12 -0
  82. data/lib/gobstones/type_check_result.rb +0 -4
  83. data/spec/lang/commands/boom_spec.rb +7 -0
  84. data/spec/lang/commands/command_block_spec.rb +15 -0
  85. data/spec/lang/commands/if_spec.rb +32 -0
  86. data/spec/lang/commands/if_then_else_spec.rb +19 -0
  87. data/spec/lang/commands/ir_al_origen_spec.rb +11 -0
  88. data/spec/lang/commands/mover_spec.rb +30 -0
  89. data/spec/lang/commands/multiple_assignment_spec.rb +39 -22
  90. data/spec/lang/commands/poner_spec.rb +27 -0
  91. data/spec/lang/commands/procedure_call_spec.rb +26 -28
  92. data/spec/lang/commands/procedure_spec.rb +32 -32
  93. data/spec/lang/commands/repeat_with_spec.rb +64 -0
  94. data/spec/lang/commands/sacar_spec.rb +32 -0
  95. data/spec/lang/commands/single_assignment_spec.rb +5 -6
  96. data/spec/lang/commands/skip_spec.rb +10 -0
  97. data/spec/lang/commands/vaciar_tablero_spec.rb +10 -0
  98. data/spec/lang/commands/while_spec.rb +39 -0
  99. data/spec/lang/definitions/main_spec.rb +34 -0
  100. data/spec/lang/definitions/no_return_statement_spec.rb +4 -5
  101. data/spec/lang/definitions/var_tuple_spec.rb +4 -7
  102. data/spec/lang/expressions/arithmetic_expressions_spec.rb +37 -64
  103. data/spec/lang/expressions/boolean_expressions_spec.rb +25 -34
  104. data/spec/lang/expressions/comparison_expressions_spec.rb +109 -155
  105. data/spec/lang/expressions/enclosed_by_parens_expression_spec.rb +3 -7
  106. data/spec/lang/expressions/function_call_spec.rb +24 -20
  107. data/spec/lang/expressions/primitive_functions_spec.rb +28 -39
  108. data/spec/lang/expressions/type_bound_functions_spec.rb +10 -18
  109. data/spec/lang/expressions/var_name_spec.rb +8 -12
  110. data/spec/lang/literals/{booleans_spec.rb → boolean_spec.rb} +3 -5
  111. data/spec/lang/literals/color_spec.rb +19 -0
  112. data/spec/lang/literals/direction_spec.rb +46 -0
  113. data/spec/lang/literals/{numbers_spec.rb → number_spec.rb} +3 -4
  114. data/spec/matchers/parse_matcher.rb +9 -11
  115. data/spec/parser/arithmetic_expressions_spec.rb +51 -61
  116. data/spec/parser/assignments_spec.rb +21 -31
  117. data/spec/parser/boolean_expressions_spec.rb +35 -43
  118. data/spec/parser/command_block_spec.rb +18 -20
  119. data/spec/parser/data_types_spec.rb +9 -19
  120. data/spec/parser/function_calls_spec.rb +19 -19
  121. data/spec/parser/function_definitions_spec.rb +17 -22
  122. data/spec/parser/gobstones_program_spec.rb +30 -30
  123. data/spec/parser/if_command_spec.rb +19 -28
  124. data/spec/parser/main_definition_spec.rb +13 -16
  125. data/spec/parser/nested_expressions_spec.rb +20 -24
  126. data/spec/parser/primitive_expressions_spec.rb +33 -38
  127. data/spec/parser/procedure_calls_spec.rb +17 -18
  128. data/spec/parser/procedure_definitions_spec.rb +12 -15
  129. data/spec/parser/repeat_with_command_spec.rb +10 -10
  130. data/spec/parser/simple_commands_spec.rb +23 -37
  131. data/spec/parser/treetop_parser_spec.rb +87 -83
  132. data/spec/parser/var_tuple_spec.rb +8 -12
  133. data/spec/parser/while_command_spec.rb +11 -14
  134. data/spec/runner/board_spec.rb +28 -33
  135. data/spec/runner/cell_spec.rb +21 -28
  136. data/spec/runner/execution_context_spec.rb +18 -35
  137. data/spec/runner/head_spec.rb +54 -60
  138. data/spec/spec_helper.rb +10 -1
  139. data/spec/support/board_assertions.rb +18 -0
  140. data/spec/{gobstones_lang_test_objects.rb → support/gobstones_lang_test_objects.rb} +6 -4
  141. data/spec/type_checker_spec.rb +19 -25
  142. metadata +80 -56
  143. data/.ruby-version +0 -1
  144. data/lib/gobstones/lang/commands/boom_cmd.rb +0 -31
  145. data/lib/gobstones/lang/commands/conditional_cmd.rb +0 -31
  146. data/lib/gobstones/lang/commands/if_cmd.rb +0 -38
  147. data/lib/gobstones/lang/commands/ir_al_origen_cmd.rb +0 -19
  148. data/lib/gobstones/lang/commands/mover_cmd.rb +0 -27
  149. data/lib/gobstones/lang/commands/poner_cmd.rb +0 -35
  150. data/lib/gobstones/lang/commands/repeat_with_cmd.rb +0 -77
  151. data/lib/gobstones/lang/commands/sacar_cmd.rb +0 -33
  152. data/lib/gobstones/lang/commands/skip_cmd.rb +0 -19
  153. data/lib/gobstones/lang/commands/vaciar_tablero_cmd.rb +0 -19
  154. data/lib/gobstones/lang/commands/while_cmd.rb +0 -25
  155. data/lib/gobstones/modules/equal_by_class.rb +0 -13
  156. data/spec/lang/commands/boom_cmd_spec.rb +0 -8
  157. data/spec/lang/commands/cmd_block_spec.rb +0 -21
  158. data/spec/lang/commands/if_cmd_spec.rb +0 -50
  159. data/spec/lang/commands/ir_al_origen_cmd_spec.rb +0 -16
  160. data/spec/lang/commands/mover_cmd_spec.rb +0 -36
  161. data/spec/lang/commands/poner_cmd_spec.rb +0 -28
  162. data/spec/lang/commands/repeat_with_cmd_spec.rb +0 -60
  163. data/spec/lang/commands/sacar_cmd_spec.rb +0 -35
  164. data/spec/lang/commands/skip_cmd_spec.rb +0 -12
  165. data/spec/lang/commands/vaciar_tablero_cmd_spec.rb +0 -14
  166. data/spec/lang/commands/while_cmd_spec.rb +0 -43
  167. data/spec/lang/literals/colors_spec.rb +0 -13
  168. data/spec/lang/literals/directions_spec.rb +0 -45
@@ -0,0 +1,64 @@
1
+ RSpec.describe RepeatWith do
2
+ let(:context) { clean_context }
3
+ let(:var_name) { 'var'.to_var_name }
4
+
5
+ it 'iterates over numbers when evaluating' do
6
+ command_block = CommandBlock.with_just(Poner.new(rojo))
7
+ repeat_with = described_class.new(var_name, 1.to_gbs_num, 10.to_gbs_num, command_block)
8
+
9
+ repeat_with.evaluate context
10
+
11
+ expect(context.head.number_of_balls(rojo)).to eq(10)
12
+ end
13
+
14
+ it 'raises an error if the range values have not the same type' do
15
+ repeat_with = described_class.new(var_name, 1.to_gbs_num, este, empty_body)
16
+
17
+ expect { repeat_with.evaluate context }.
18
+ to raise_error(GobstonesTypeError, /types don't match in range values/)
19
+ end
20
+
21
+ it 'raises an error if the index variable is previously defined' do
22
+ repeat_with = described_class.new(var_name, 1.to_gbs_num, 5.to_gbs_num, empty_body)
23
+
24
+ context.set var_name, 42.to_gbs_num
25
+
26
+ expect { repeat_with.evaluate context }.
27
+ to raise_error(GobstonesRuntimeError, /index variable can't be used because it's already defined/)
28
+ end
29
+
30
+ it 'removes the index variable assignment after execution' do
31
+ repeat_with = described_class.new(var_name, azul, verde, empty_body)
32
+
33
+ repeat_with.evaluate context
34
+
35
+ expect(context.has_variable_named?('var')).to be(false)
36
+ end
37
+
38
+ it 'allows to use the index variable inside the command block' do
39
+ cmd_block = CommandBlock.with_just(Poner.new(var_name))
40
+ repeat_with = described_class.new(var_name, azul, verde, cmd_block)
41
+
42
+ repeat_with.evaluate context
43
+
44
+ expect_balls(azul, negro, rojo, verde)
45
+ end
46
+
47
+ it 'does exactly one iteration if range values are the same' do
48
+ cmd_block = CommandBlock.with_just(Poner.new(verde))
49
+ repeat_with = described_class.new(var_name, 1.to_gbs_num, 1.to_gbs_num, cmd_block)
50
+
51
+ repeat_with.evaluate context
52
+
53
+ expect_balls(verde)
54
+ end
55
+
56
+ it 'does no iterations if the from is higher than the to' do
57
+ cmd_block = CommandBlock.with_just(Poner.new(verde))
58
+ repeat_with = described_class.new(var_name, 8.to_gbs_num, 4.to_gbs_num, cmd_block)
59
+
60
+ repeat_with.evaluate context
61
+
62
+ expect_no_balls(verde)
63
+ end
64
+ end
@@ -0,0 +1,32 @@
1
+ RSpec.describe Sacar do
2
+ let(:context) { clean_context }
3
+
4
+ it 'takes off balls from the board when evaluating' do
5
+ 3.times { context.head.put rojo }
6
+
7
+ described_class.new(rojo).evaluate context
8
+
9
+ expect(context.head.number_of_balls(rojo)).to eq(2)
10
+ end
11
+
12
+ it 'undoes a command' do
13
+ described_class.new(rojo).undo context
14
+
15
+ expect(context.head.number_of_balls(rojo)).to eq(1)
16
+ end
17
+
18
+ it 'returns the opposite command' do
19
+ opposite_command = described_class.new(rojo).opposite
20
+
21
+ expect(opposite_command).to eq(Poner.new(rojo))
22
+ end
23
+
24
+ it 'fails if there are no balls in the board' do
25
+ expect { described_class.new(rojo).evaluate(context) }.to raise_error(EmptyCellError)
26
+ end
27
+
28
+ it 'fails if the argument is not a color' do
29
+ expect { described_class.new(true_value).evaluate(context) }.
30
+ to raise_error(GobstonesTypeError, /is not a color/)
31
+ end
32
+ end
@@ -1,13 +1,12 @@
1
- describe SingleAssignment do
2
-
1
+ RSpec.describe SingleAssignment do
3
2
  let(:context) { clean_context }
4
3
  let(:a) { 'a'.to_var_name }
5
4
 
6
- it "evaluates the associated expression to the var name" do
7
- assign = SingleAssignment.new a, Add.new(3.to_gbs_num, 4.to_gbs_num)
5
+ it 'evaluates the associated expression to the var name' do
6
+ assign = described_class.new(a, Add.new(3.to_gbs_num, 4.to_gbs_num))
8
7
  assign.evaluate context
9
- expect(context.has_variable_named?('a')).to be true
8
+
9
+ expect(context.has_variable_named?('a')).to be(true)
10
10
  expect(context.get(a)).to eq(7.to_gbs_num)
11
11
  end
12
-
13
12
  end
@@ -0,0 +1,10 @@
1
+ RSpec.describe Skip do
2
+ let(:context) { clean_context }
3
+
4
+ it 'evaluates and does nothing' do
5
+ described_class.new.evaluate(context)
6
+
7
+ expect_positioned_at(0, 0)
8
+ expect(context.head.board).to be_empty
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ RSpec.describe VaciarTablero do
2
+ let(:context) { clean_context }
3
+
4
+ it 'empties the board in the context' do
5
+ context.head.put(rojo)
6
+ described_class.new.evaluate(context)
7
+
8
+ expect(context.board).to be_empty
9
+ end
10
+ end
@@ -0,0 +1,39 @@
1
+ RSpec.describe While do
2
+ let(:context) { clean_context }
3
+ let(:while_block) { CommandBlock.with_just(Poner.new(verde)) }
4
+
5
+ def stub_condition(times)
6
+ instance_double(Boolean).tap do |condition|
7
+ expected_values = [true_value] * times + [false_value]
8
+ allow(condition).to receive(:evaluate).and_return(*expected_values)
9
+ end
10
+ end
11
+
12
+ it 'evaluates the command block until the condition is not satisfied' do
13
+ while_cmd = described_class.new(stub_condition(3), while_block)
14
+
15
+ while_cmd.evaluate context
16
+
17
+ expect(context.head.number_of_balls(verde)).to eq(3)
18
+ end
19
+
20
+ it 'does not evaluate the command block if the condition is false' do
21
+ while_cmd = described_class.new(stub_condition(0), while_block)
22
+
23
+ while_cmd.evaluate context
24
+
25
+ expect_no_balls(verde)
26
+ end
27
+
28
+ it 'fails with type error if the condition is not boolean' do
29
+ while_cmd = described_class.new(sur, while_block)
30
+
31
+ expect { while_cmd.evaluate context }.to raise_error(GobstonesTypeError, /is not a boolean/)
32
+ end
33
+
34
+ it 'fails with stack overflow if the condition is always true' do
35
+ while_cmd = described_class.new(true_value, while_block)
36
+
37
+ expect { while_cmd.evaluate context }.to raise_error(GobstonesRuntimeError, /stack overflow/)
38
+ end
39
+ end
@@ -0,0 +1,34 @@
1
+ RSpec.describe Main do
2
+ subject(:if_evaluation) { main.evaluate(context) }
3
+
4
+ let(:context) { clean_context }
5
+ let(:return_tuple) { VarTuple.with_names(%w[x y]) }
6
+ let(:return_from_main) { ReturnFromMain.new(return_tuple) }
7
+ let(:assign_x) { SingleAssignment.new('x'.to_var_name, 42.to_gbs_num) }
8
+ let(:assign_y) { SingleAssignment.new('y'.to_var_name, verde) }
9
+ let(:command_block) { CommandBlock.new([assign_x, assign_y]) }
10
+ let(:main) { described_class.new(command_block, return_from_main) }
11
+
12
+ it 'evaluates the body' do
13
+ if_evaluation
14
+
15
+ %w[x y].each { |var_name| expect(context).to have_variable_named(var_name) }
16
+ end
17
+
18
+ context 'with return statement' do
19
+ it 'returns its return value, if there is one' do
20
+ expect(if_evaluation).to eq(
21
+ 'x'.to_var_name => 42.to_gbs_num,
22
+ 'y'.to_var_name => verde,
23
+ )
24
+ end
25
+ end
26
+
27
+ context 'without return statement' do
28
+ let(:return_from_main) { no_return_statement }
29
+
30
+ it 'returns an empty result when no return statement is present' do
31
+ expect(if_evaluation).to be_empty
32
+ end
33
+ end
34
+ end
@@ -1,10 +1,9 @@
1
- describe NoReturnStatement do
1
+ RSpec.describe NoReturnStatement do
2
+ subject(:no_return_statement) { described_class.new }
2
3
 
3
4
  let(:context) { clean_context }
4
- let(:no_return_statement) { NoReturnStatement.new }
5
5
 
6
- it "does nothing when evaluating on a context" do
7
- expect { no_return_statement.evaluate context }.not_to change { context.head }
6
+ it 'does nothing when evaluating on a context' do
7
+ expect { no_return_statement.evaluate(context) }.not_to change(context, :head)
8
8
  end
9
-
10
9
  end
@@ -1,16 +1,13 @@
1
- describe VarTuple do
1
+ RSpec.describe VarTuple do
2
+ let(:var_tuple) { described_class.with_names(%w[a b c]) }
2
3
 
3
- let (:var_tuple) { VarTuple.new ['a'.to_var_name, 'b'.to_var_name, 'c'.to_var_name] }
4
-
5
- it "returns its length" do
4
+ it 'returns its length' do
6
5
  expect(var_tuple.length).to eq(3)
7
6
  end
8
7
 
9
- it "returns a variable at a given index" do
8
+ it 'returns a variable at a given index' do
10
9
  expect(var_tuple.variable_at(0)).to eq('a'.to_var_name)
11
10
  expect(var_tuple.variable_at(1)).to eq('b'.to_var_name)
12
11
  expect(var_tuple.variable_at(2)).to eq('c'.to_var_name)
13
-
14
12
  end
15
-
16
13
  end
@@ -1,108 +1,81 @@
1
- describe "arithmetic expressions" do
2
-
1
+ RSpec.describe 'arithmetic expressions' do
3
2
  describe Add do
4
-
5
- it "evaluates with two numbers" do
6
- add = Add.new(42.to_gbs_num, 23.to_gbs_num)
7
- expect(add.evaluate).to eq(65.to_gbs_num)
3
+ it 'evaluates with two numbers' do
4
+ expect(described_class.numbers(42, 23).evaluate).to eq(65.to_gbs_num)
8
5
  end
9
6
 
10
- it "evaluates nested add expressions" do
11
- add_4_8 = Add.new 4.to_gbs_num, 8.to_gbs_num
12
- add_12_15 = Add.new add_4_8, 15.to_gbs_num
13
- add_27_16 = Add.new add_12_15, 16.to_gbs_num
14
- add_43_23 = Add.new add_27_16, 23.to_gbs_num
15
- add_66_42 = Add.new add_43_23, 42.to_gbs_num
7
+ it 'evaluates nested add expressions' do
8
+ add_4_8 = described_class.numbers(4, 8)
9
+ add_12_15 = described_class.new(add_4_8, 15.to_gbs_num)
10
+ add_27_16 = described_class.new(add_12_15, 16.to_gbs_num)
11
+ add_43_23 = described_class.new(add_27_16, 23.to_gbs_num)
12
+ add_66_42 = described_class.new(add_43_23, 42.to_gbs_num)
16
13
 
17
14
  expect(add_66_42.evaluate).to eq(108.to_gbs_num)
18
15
  end
19
-
20
16
  end
21
17
 
22
18
  describe Sub do
23
-
24
- it "evaluates with two numbers" do
25
- sub = Sub.new(42.to_gbs_num, 15.to_gbs_num)
26
- expect(sub.evaluate).to eq(27.to_gbs_num)
19
+ it 'evaluates with two numbers' do
20
+ expect(described_class.numbers(42, 15).evaluate).to eq(27.to_gbs_num)
27
21
  end
28
22
 
29
- it "evaluates returning a negative result" do
30
- sub = Sub.new(15.to_gbs_num, 42.to_gbs_num)
31
- expect(sub.evaluate).to eq(-27.to_gbs_num)
23
+ it 'evaluates returning a negative result' do
24
+ expect(described_class.numbers(15, 42).evaluate).to eq(-27.to_gbs_num)
32
25
  end
33
26
 
34
- it "evaluates nested sub expressions" do
35
- sub_n1_n2 = Sub.new 42.to_gbs_num, 15.to_gbs_num
36
- sub = Sub.new sub_n1_n2, 8.to_gbs_num
27
+ it 'evaluates nested sub expressions' do
28
+ sub_n1_n2 = described_class.numbers(42, 15)
29
+ sub = described_class.new(sub_n1_n2, 8.to_gbs_num)
37
30
 
38
31
  expect(sub.evaluate).to eq(19.to_gbs_num)
39
32
  end
40
-
41
33
  end
42
34
 
43
35
  describe Mul do
44
-
45
- it "evaluates a simple mul" do
46
- mul = Mul.new(4.to_gbs_num, 8.to_gbs_num)
47
- expect(mul.evaluate).to eq(32.to_gbs_num)
36
+ it 'evaluates a simple mul' do
37
+ expect(described_class.numbers(4, 8).evaluate).to eq(32.to_gbs_num)
48
38
  end
49
39
 
50
- it "evaluates a nested mul expression" do
51
- mul = Mul.new(-2.to_gbs_num, 4.to_gbs_num)
52
- expect(Mul.new(mul, 5.to_gbs_num).evaluate).to eq(-40.to_gbs_num)
53
- end
40
+ it 'evaluates a nested mul expression' do
41
+ mul = described_class.numbers(-2, 4)
54
42
 
43
+ expect(described_class.new(mul, 5.to_gbs_num).evaluate).to eq(-40.to_gbs_num)
44
+ end
55
45
  end
56
46
 
57
47
  describe Div do
58
-
59
- it "evaluates a simple div" do
60
- div = Div.new(12.to_gbs_num, 3.to_gbs_num)
61
- expect(div.evaluate).to eq(4.to_gbs_num)
48
+ it 'evaluates a simple div' do
49
+ expect(described_class.numbers(12, 3).evaluate).to eq(4.to_gbs_num)
62
50
  end
63
51
 
64
- it "evaluates to an integer division" do
65
- div = Div.new(10.to_gbs_num, 3.to_gbs_num)
66
- expect(div.evaluate).to eq(3.to_gbs_num)
52
+ it 'evaluates to an integer division' do
53
+ expect(described_class.numbers(10, 3).evaluate).to eq(3.to_gbs_num)
67
54
  end
68
55
 
69
- it "raises an error when dividing by zero" do
70
- expect {
71
- Div.new(42.to_gbs_num, 0.to_gbs_num).evaluate
72
- }.to raise_error(GobstonesRuntimeError, 'zero division')
56
+ it 'raises an error when dividing by zero' do
57
+ expect { described_class.numbers(42, 0).evaluate }.to raise_error(GobstonesRuntimeError, 'zero division')
73
58
  end
74
-
75
59
  end
76
60
 
77
61
  describe Mod do
78
-
79
- it "evaluates a mod with result 0" do
80
- mod = Mod.new(4.to_gbs_num, 4.to_gbs_num)
81
- expect(mod.evaluate).to eq(0.to_gbs_num)
62
+ it 'evaluates a mod with result 0' do
63
+ expect(described_class.numbers(4, 4).evaluate).to eq(0.to_gbs_num)
82
64
  end
83
65
 
84
- it "evaluates a mod with result > 0" do
85
- mod = Mod.new(10.to_gbs_num, 3.to_gbs_num)
86
- expect(mod.evaluate).to eq(1.to_gbs_num)
66
+ it 'evaluates a mod with result > 0' do
67
+ expect(described_class.numbers(10, 3).evaluate).to eq(1.to_gbs_num)
87
68
  end
88
-
89
69
  end
90
70
 
91
71
  describe Pow do
92
-
93
- it "returns 1 as a result if the power is 0" do
94
- pow_1 = Pow.new(1.to_gbs_num, 0.to_gbs_num)
95
- pow_42 = Pow.new(42.to_gbs_num, 0.to_gbs_num)
96
-
97
- expect(pow_1.evaluate).to eq(1.to_gbs_num)
98
- expect(pow_42.evaluate).to eq(1.to_gbs_num)
72
+ it 'returns 1 as a result if the power is 0' do
73
+ expect(described_class.numbers(1, 0).evaluate).to eq(1.to_gbs_num)
74
+ expect(described_class.numbers(42, 0).evaluate).to eq(1.to_gbs_num)
99
75
  end
100
76
 
101
- it "evaluates 2 raised to 4" do
102
- pow = Pow.new(2.to_gbs_num, 4.to_gbs_num)
103
- expect(pow.evaluate).to eq(16.to_gbs_num)
77
+ it 'evaluates 2 raised to 4' do
78
+ expect(described_class.numbers(2, 4).evaluate).to eq(16.to_gbs_num)
104
79
  end
105
-
106
80
  end
107
-
108
81
  end
@@ -1,66 +1,57 @@
1
1
  # TODO test/implement short-circuit?
2
- describe "boolean expressions" do
3
-
2
+ RSpec.describe 'evaluating boolean expressions' do
4
3
  let(:context) { clean_context }
5
4
 
6
5
  describe And do
7
-
8
- it "evaluates a simple and expression" do
9
- expect(And.new(false_value, false_value).evaluate(context)).to eq(false_value)
10
- expect(And.new(false_value, true_value).evaluate(context)).to eq(false_value)
11
- expect(And.new(true_value, false_value).evaluate(context)).to eq(false_value)
12
- expect(And.new(true_value, true_value).evaluate(context)).to eq(true_value)
6
+ it 'evaluates a simple and expression' do
7
+ expect(described_class.new(false_value, false_value).evaluate(context)).to eq(false_value)
8
+ expect(described_class.new(false_value, true_value).evaluate(context)).to eq(false_value)
9
+ expect(described_class.new(true_value, false_value).evaluate(context)).to eq(false_value)
10
+ expect(described_class.new(true_value, true_value).evaluate(context)).to eq(true_value)
13
11
  end
14
-
15
12
  end
16
13
 
17
14
  describe Or do
18
-
19
- it "evaluates a simple or expression" do
20
- expect(Or.new(false_value, false_value).evaluate(context)).to eq(false_value)
21
- expect(Or.new(false_value, true_value).evaluate(context)).to eq(true_value)
22
- expect(Or.new(true_value, false_value).evaluate(context)).to eq(true_value)
23
- expect(Or.new(true_value, true_value).evaluate(context)).to eq(true_value)
15
+ it 'evaluates a simple or expression' do
16
+ expect(described_class.new(false_value, false_value).evaluate(context)).to eq(false_value)
17
+ expect(described_class.new(false_value, true_value).evaluate(context)).to eq(true_value)
18
+ expect(described_class.new(true_value, false_value).evaluate(context)).to eq(true_value)
19
+ expect(described_class.new(true_value, true_value).evaluate(context)).to eq(true_value)
24
20
  end
25
-
26
21
  end
27
22
 
28
23
  describe Not do
29
-
30
- it "evaluates a simple not expression" do
31
- expect(Not.new(false_value).evaluate(context)).to eq(true_value)
32
- expect(Not.new(true_value).evaluate(context)).to eq(false_value)
24
+ it 'evaluates a simple not expression' do
25
+ expect(described_class.new(false_value).evaluate(context)).to eq(true_value)
26
+ expect(described_class.new(true_value).evaluate(context)).to eq(false_value)
33
27
  end
34
28
 
35
- it "evaluates a double negated expression" do
36
- expect(Not.new(Not.new(false_value)).evaluate(context)).to eq(false_value)
37
- expect(Not.new(Not.new(true_value)).evaluate(context)).to eq(true_value)
29
+ it 'evaluates a double negated expression' do
30
+ expect(described_class.new(described_class.new(false_value)).evaluate(context)).to eq(false_value)
31
+ expect(described_class.new(described_class.new(true_value)).evaluate(context)).to eq(true_value)
38
32
  end
39
33
 
40
- it "fails if the argument is not a boolean" do
41
- expect { Not.new(42.to_gbs_num).evaluate(context) }.
34
+ it 'fails if the argument is not a boolean' do
35
+ expect { described_class.new(42.to_gbs_num).evaluate(context) }.
42
36
  to raise_error(GobstonesTypeError, /is not a boolean/)
43
- expect { Not.new(azul).evaluate(context) }.
37
+ expect { described_class.new(azul).evaluate(context) }.
44
38
  to raise_error(GobstonesTypeError, /is not a boolean/)
45
- expect { Not.new(oeste).evaluate(context) }.
39
+ expect { described_class.new(oeste).evaluate(context) }.
46
40
  to raise_error(GobstonesTypeError, /is not a boolean/)
47
41
  end
48
-
49
42
  end
50
43
 
51
- describe "nested" do
52
-
44
+ describe 'nested' do
53
45
  it "evaluates and's and or's" do
54
- expression = And.new Or.new(false_value, true_value), true_value
46
+ expression = And.new(Or.new(false_value, true_value), true_value)
55
47
 
56
48
  expect(expression.evaluate(context)).to eq(true_value)
57
49
  end
58
50
 
59
51
  it "evaluates and's, or's, and not's" do
60
- expression = Not.new Or.new(false_value, And.new(true_value, true_value))
52
+ expression = Not.new(Or.new(false_value, And.new(true_value, true_value)))
53
+
61
54
  expect(expression.evaluate(context)).to eq(false_value)
62
55
  end
63
-
64
56
  end
65
-
66
57
  end