gobstones 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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