gobstones 0.0.1.1 → 0.0.2

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 (128) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -3
  3. data/.ruby-version +1 -1
  4. data/.travis.yml +1 -1
  5. data/CHANGELOG +22 -2
  6. data/Gemfile +3 -3
  7. data/Gemfile.lock +32 -27
  8. data/bin/gobstones +1 -1
  9. data/examples/.gitkeep +0 -0
  10. data/gobstones.gemspec +2 -2
  11. data/lib/gobstones/cli/board_template +1 -1
  12. data/lib/gobstones/cli/printer.rb +1 -1
  13. data/lib/gobstones/cli/runner.rb +8 -2
  14. data/lib/gobstones/extensions/all.rb +2 -1
  15. data/lib/gobstones/extensions/boolean.rb +1 -1
  16. data/lib/gobstones/extensions/fixnum.rb +1 -1
  17. data/lib/gobstones/extensions/string.rb +9 -0
  18. data/lib/gobstones/lang/all.rb +1 -1
  19. data/lib/gobstones/lang/commands/all.rb +3 -2
  20. data/lib/gobstones/lang/commands/boom_cmd.rb +6 -3
  21. data/lib/gobstones/lang/commands/command_block.rb +1 -1
  22. data/lib/gobstones/lang/commands/conditional_cmd.rb +5 -1
  23. data/lib/gobstones/lang/commands/ir_al_origen_cmd.rb +1 -1
  24. data/lib/gobstones/lang/commands/mover_cmd.rb +4 -2
  25. data/lib/gobstones/lang/commands/multiple_assignment.rb +35 -0
  26. data/lib/gobstones/lang/commands/poner_cmd.rb +8 -4
  27. data/lib/gobstones/lang/commands/procedure_call.rb +1 -9
  28. data/lib/gobstones/lang/commands/repeat_with_cmd.rb +10 -6
  29. data/lib/gobstones/lang/commands/sacar_cmd.rb +9 -7
  30. data/lib/gobstones/lang/commands/{assignments.rb → single_assignment.rb} +5 -3
  31. data/lib/gobstones/lang/commands/skip_cmd.rb +2 -2
  32. data/lib/gobstones/lang/commands/vaciar_tablero_cmd.rb +1 -1
  33. data/lib/gobstones/lang/commands/while_cmd.rb +1 -1
  34. data/lib/gobstones/lang/definitions/all.rb +1 -1
  35. data/lib/gobstones/lang/definitions/definition.rb +47 -5
  36. data/lib/gobstones/lang/definitions/definition_call.rb +17 -5
  37. data/lib/gobstones/lang/definitions/function.rb +9 -0
  38. data/lib/gobstones/lang/definitions/main.rb +1 -1
  39. data/lib/gobstones/lang/definitions/no_return_statement.rb +7 -3
  40. data/lib/gobstones/lang/definitions/procedure.rb +5 -20
  41. data/lib/gobstones/lang/definitions/return_from_function.rb +12 -2
  42. data/lib/gobstones/lang/definitions/return_from_main.rb +5 -1
  43. data/lib/gobstones/lang/definitions/var_tuple.rb +13 -1
  44. data/lib/gobstones/lang/expressions/all.rb +1 -1
  45. data/lib/gobstones/lang/expressions/arithmetic_expressions.rb +1 -1
  46. data/lib/gobstones/lang/expressions/boolean_expressions.rb +3 -2
  47. data/lib/gobstones/lang/expressions/enclosed_by_parens_expression.rb +17 -0
  48. data/lib/gobstones/lang/expressions/function_call.rb +1 -1
  49. data/lib/gobstones/lang/expressions/one_arg_expression.rb +16 -4
  50. data/lib/gobstones/lang/expressions/primitive_functions.rb +18 -12
  51. data/lib/gobstones/lang/expressions/two_arg_expression.rb +7 -3
  52. data/lib/gobstones/lang/expressions/type_bound_functions.rb +1 -1
  53. data/lib/gobstones/lang/expressions/var_name.rb +9 -3
  54. data/lib/gobstones/lang/literals/all.rb +1 -1
  55. data/lib/gobstones/lang/literals/colors.rb +1 -1
  56. data/lib/gobstones/lang/literals/literal.rb +31 -21
  57. data/lib/gobstones/lang/literals/number.rb +1 -1
  58. data/lib/gobstones/lang/program.rb +13 -4
  59. data/lib/gobstones/modules/equal_by_class.rb +1 -1
  60. data/lib/gobstones/parser/ast/ast.rb +12 -8
  61. data/lib/gobstones/parser/grammar/gobstones.treetop +4 -4
  62. data/lib/gobstones/parser/parse_error.rb +1 -1
  63. data/lib/gobstones/runner/all.rb +1 -2
  64. data/lib/gobstones/runner/board.rb +13 -4
  65. data/lib/gobstones/runner/cell.rb +10 -0
  66. data/lib/gobstones/runner/errors/all.rb +1 -1
  67. data/lib/gobstones/runner/errors/definition_not_found_error.rb +1 -1
  68. data/lib/gobstones/runner/execution_context.rb +66 -16
  69. data/lib/gobstones/runner/head.rb +17 -3
  70. data/spec/gobstones_lang_test_objects.rb +75 -0
  71. data/spec/lang/commands/boom_cmd_spec.rb +3 -3
  72. data/spec/lang/commands/cmd_block_spec.rb +14 -14
  73. data/spec/lang/commands/if_cmd_spec.rb +21 -20
  74. data/spec/lang/commands/ir_al_origen_cmd_spec.rb +3 -3
  75. data/spec/lang/commands/mover_cmd_spec.rb +12 -14
  76. data/spec/lang/commands/multiple_assignment_spec.rb +37 -0
  77. data/spec/lang/commands/poner_cmd_spec.rb +13 -14
  78. data/spec/lang/commands/procedure_call_spec.rb +19 -24
  79. data/spec/lang/commands/procedure_spec.rb +32 -36
  80. data/spec/lang/commands/repeat_with_cmd_spec.rb +39 -20
  81. data/spec/lang/commands/sacar_cmd_spec.rb +17 -16
  82. data/spec/lang/commands/single_assignment_spec.rb +13 -0
  83. data/spec/lang/commands/skip_cmd_spec.rb +2 -2
  84. data/spec/lang/commands/vaciar_tablero_cmd_spec.rb +7 -6
  85. data/spec/lang/commands/while_cmd_spec.rb +21 -15
  86. data/spec/lang/definitions/no_return_statement_spec.rb +10 -0
  87. data/spec/lang/definitions/var_tuple_spec.rb +16 -0
  88. data/spec/lang/expressions/arithmetic_expressions_spec.rb +15 -15
  89. data/spec/lang/expressions/boolean_expressions_spec.rb +35 -25
  90. data/spec/lang/expressions/comparison_expressions_spec.rb +25 -28
  91. data/spec/lang/expressions/enclosed_by_parens_expression_spec.rb +11 -0
  92. data/spec/lang/expressions/function_call_spec.rb +29 -0
  93. data/spec/lang/expressions/primitive_functions_spec.rb +60 -62
  94. data/spec/lang/expressions/type_bound_functions_spec.rb +13 -13
  95. data/spec/lang/expressions/var_name_spec.rb +20 -8
  96. data/spec/lang/literals/booleans_spec.rb +5 -7
  97. data/spec/lang/literals/colors_spec.rb +4 -4
  98. data/spec/lang/literals/directions_spec.rb +12 -12
  99. data/spec/lang/literals/numbers_spec.rb +2 -2
  100. data/spec/matchers/parse_matcher.rb +9 -10
  101. data/spec/parser/arithmetic_expressions_spec.rb +19 -19
  102. data/spec/parser/assignments_spec.rb +24 -10
  103. data/spec/parser/boolean_expressions_spec.rb +18 -18
  104. data/spec/parser/command_block_spec.rb +17 -19
  105. data/spec/parser/data_types_spec.rb +23 -23
  106. data/spec/parser/function_calls_spec.rb +13 -12
  107. data/spec/parser/function_definitions_spec.rb +13 -18
  108. data/spec/parser/gobstones_program_spec.rb +15 -15
  109. data/spec/parser/if_command_spec.rb +13 -12
  110. data/spec/parser/main_definition_spec.rb +12 -12
  111. data/spec/parser/nested_expressions_spec.rb +16 -20
  112. data/spec/parser/primitive_expressions_spec.rb +27 -33
  113. data/spec/parser/procedure_calls_spec.rb +12 -12
  114. data/spec/parser/procedure_definitions_spec.rb +10 -16
  115. data/spec/parser/repeat_with_command_spec.rb +7 -10
  116. data/spec/parser/simple_commands_spec.rb +10 -10
  117. data/spec/parser/treetop_parser_spec.rb +11 -10
  118. data/spec/parser/var_tuple_spec.rb +7 -11
  119. data/spec/parser/while_command_spec.rb +9 -9
  120. data/spec/runner/board_spec.rb +23 -27
  121. data/spec/runner/cell_spec.rb +34 -38
  122. data/spec/runner/execution_context_spec.rb +38 -24
  123. data/spec/runner/head_spec.rb +54 -63
  124. data/spec/spec_helper.rb +4 -1
  125. data/spec/type_checker_spec.rb +13 -13
  126. metadata +33 -18
  127. data/lib/gobstones/lang/expressions/parentheses_expression.rb +0 -13
  128. data/spec/lang/commands/assignments_spec.rb +0 -13
@@ -1,5 +1,4 @@
1
1
  require 'gobstones/lang/definitions/definition_call'
2
- require 'gobstones/runner/errors/definition_not_found_error'
3
2
 
4
3
  module Gobstones
5
4
 
@@ -9,15 +8,8 @@ module Gobstones
9
8
 
10
9
  include DefinitionCall
11
10
 
12
- def evaluate(context)
13
- evaluated_args = args.map { |arg| arg.evaluate context }
14
- context.program_context.definition_named(name, ->(definition) {
15
- definition.evaluate context, evaluated_args
16
- }, -> { raise Gobstones::Runner::DefinitionNotFound.new name } )
17
- end
18
-
19
11
  end
20
12
 
21
13
  end
22
14
 
23
- end
15
+ end
@@ -1,10 +1,11 @@
1
- require 'gobstones/lang/commands/assignments'
1
+ require 'gobstones/lang/commands/single_assignment'
2
2
  require 'gobstones/lang/commands/command_block'
3
3
  require 'gobstones/lang/commands/while_cmd'
4
4
  require 'gobstones/lang/expressions/comparison_expressions'
5
5
  require 'gobstones/lang/expressions/primitive_functions'
6
6
  require 'gobstones/runner/errors/gobstones_runtime_error'
7
7
  require 'gobstones/runner/errors/gobstones_type_error'
8
+ require 'gobstones/modules/equal_by_class'
8
9
 
9
10
  module Gobstones
10
11
 
@@ -12,6 +13,8 @@ module Gobstones
12
13
 
13
14
  class RepeatWithCmd
14
15
 
16
+ include Gobstones::EqualByClass
17
+
15
18
  attr_reader :var_name, :range_min, :range_max, :cmd_block
16
19
 
17
20
  def initialize(var_name, range_min, range_max, cmd_block)
@@ -22,7 +25,7 @@ module Gobstones
22
25
  end
23
26
 
24
27
  def ==(other)
25
- self.class == other.class &&
28
+ super(other) &&
26
29
  self.var_name == other.var_name &&
27
30
  self.range_min == other.range_min &&
28
31
  self.range_max == other.range_max &&
@@ -56,18 +59,19 @@ module Gobstones
56
59
  #
57
60
  # repeatWith var in min..max block
58
61
  # is equivalent to
59
- # { var := min; while (var < max) { block; var := siguiente(var) }; block }
62
+ # if (min < max) { var := min; while (var < max) { block; var := siguiente(var) }; block }
60
63
  #
61
64
  assign_cmd = SingleAssignment.new var_name, range_min
62
65
  while_cond = LessThan.new var_name, range_max
63
66
  increment = SingleAssignment.new var_name, Siguiente.new(var_name)
64
- while_block = CmdBlock.new [cmd_block, increment]
67
+ while_block = CommandBlock.new [cmd_block, increment]
65
68
  while_cmd = WhileCmd.new while_cond, while_block
66
- CmdBlock.new [assign_cmd, while_cmd, cmd_block]
69
+ if_cond = LessThan.new range_min, range_max
70
+ IfCmd.new if_cond, CommandBlock.new([assign_cmd, while_cmd, cmd_block])
67
71
  end
68
72
 
69
73
  end
70
74
 
71
75
  end
72
76
 
73
- end
77
+ end
@@ -9,23 +9,25 @@ module Gobstones
9
9
  class Sacar < OneArgExpression
10
10
 
11
11
  def evaluate(context)
12
- begin
13
- context.head.take_out arg.evaluate(context)
14
- rescue RuntimeError => e
15
- raise Gobstones::Runner::GobstonesTypeError, e.message
12
+ with_evaluated_argument_in(context) do |result|
13
+ context.head.take_out result
16
14
  end
15
+ rescue RuntimeError => e
16
+ raise Gobstones::Runner::GobstonesTypeError, e.message
17
17
  end
18
18
 
19
19
  def undo(context)
20
- context.head.put arg.evaluate(context)
20
+ with_evaluated_argument_in(context) do |result|
21
+ context.head.put result
22
+ end
21
23
  end
22
24
 
23
25
  def opposite
24
- Poner.new arg
26
+ Poner.new argument
25
27
  end
26
28
 
27
29
  end
28
30
 
29
31
  end
30
32
 
31
- end
33
+ end
@@ -1,9 +1,13 @@
1
+ require 'gobstones/modules/equal_by_class'
2
+
1
3
  module Gobstones
2
4
 
3
5
  module Lang
4
6
 
5
7
  class SingleAssignment
6
8
 
9
+ include Gobstones::EqualByClass
10
+
7
11
  attr_reader :var_name, :expression
8
12
 
9
13
  def initialize(var_name, expression)
@@ -11,7 +15,7 @@ module Gobstones
11
15
  end
12
16
 
13
17
  def ==(other)
14
- self.class == other.class &&
18
+ super(other) &&
15
19
  self.var_name == other.var_name &&
16
20
  self.expression == other.expression
17
21
  end
@@ -22,8 +26,6 @@ module Gobstones
22
26
 
23
27
  end
24
28
 
25
- # TODO implement multiple assignment
26
-
27
29
  end
28
30
 
29
31
  end
@@ -8,7 +8,7 @@ module Gobstones
8
8
 
9
9
  include Gobstones::EqualByClass
10
10
 
11
- def evaluate(context=nil)
11
+ def evaluate(context)
12
12
  # do nothing, that's my job :-)
13
13
  end
14
14
 
@@ -16,4 +16,4 @@ module Gobstones
16
16
 
17
17
  end
18
18
 
19
- end
19
+ end
@@ -16,4 +16,4 @@ module Gobstones
16
16
 
17
17
  end
18
18
 
19
- end
19
+ end
@@ -22,4 +22,4 @@ module Gobstones
22
22
 
23
23
  end
24
24
 
25
- end
25
+ end
@@ -1,4 +1,4 @@
1
1
  require 'gobstones/lang/definitions/function'
2
2
  require 'gobstones/lang/definitions/main'
3
3
  require 'gobstones/lang/definitions/procedure'
4
- require 'gobstones/lang/definitions/var_tuple'
4
+ require 'gobstones/lang/definitions/var_tuple'
@@ -1,22 +1,26 @@
1
+ require 'gobstones/modules/equal_by_class'
2
+
1
3
  module Gobstones
2
4
 
3
5
  module Lang
4
6
 
5
7
  class Definition
6
8
 
7
- attr_reader :name, :args, :body, :return_statement
9
+ include Gobstones::EqualByClass
10
+
11
+ attr_reader :name, :arguments, :body, :return_statement
8
12
 
9
- def initialize(name, args, body, return_statement)
13
+ def initialize(name, arguments, body, return_statement)
10
14
  @name = name
11
- @args = args
15
+ @arguments = arguments
12
16
  @body = body
13
17
  @return_statement = return_statement
14
18
  end
15
19
 
16
20
  def ==(other)
17
- self.class == other.class &&
21
+ super(other) &&
18
22
  self.name == other.name &&
19
- self.args == other.args &&
23
+ self.arguments == other.arguments &&
20
24
  self.body == other.body &&
21
25
  self.return_statement == other.return_statement
22
26
  end
@@ -25,6 +29,44 @@ module Gobstones
25
29
  name == a_name
26
30
  end
27
31
 
32
+ def evaluate(context, calling_arguments=[])
33
+ check_number_of_arguments calling_arguments
34
+ in_definition_context_based_on(context) do |definition_context|
35
+ set_arguments calling_arguments, definition_context
36
+ body.evaluate definition_context
37
+ return return_statement.evaluate definition_context
38
+ end
39
+ end
40
+
41
+ def create_context_based_on(outer_context)
42
+ raise 'subclass responsibility'
43
+ end
44
+
45
+ def definition_type
46
+ raise 'subclass responsibility'
47
+ end
48
+
49
+ private
50
+
51
+ def check_number_of_arguments(calling_arguments)
52
+ raise Gobstones::Runner::WrongArgumentsError, wrong_number_of_arguments_message(calling_arguments) if
53
+ arguments.length != calling_arguments.length
54
+ end
55
+
56
+ def wrong_number_of_arguments_message(calling_arguments)
57
+ "Wrong number of arguments in #{definition_type} '#{name}':" +
58
+ " expected #{arguments.length}, got #{calling_arguments.length}"
59
+ end
60
+
61
+ def in_definition_context_based_on(outer_context, &block)
62
+ yield create_context_based_on(outer_context)
63
+ end
64
+
65
+ def set_arguments(calling_arguments, procedure_context)
66
+ arguments.length.times do |index|
67
+ procedure_context.set arguments.variable_at(index), calling_arguments[index]
68
+ end
69
+ end
28
70
  end
29
71
 
30
72
  end
@@ -1,20 +1,32 @@
1
+ require 'gobstones/modules/equal_by_class'
2
+ require 'gobstones/runner/errors/definition_not_found_error'
3
+
1
4
  module Gobstones
2
5
 
3
6
  module Lang
4
7
 
5
8
  module DefinitionCall
6
9
 
7
- attr_reader :name, :args
10
+ include Gobstones::EqualByClass
11
+
12
+ attr_reader :name, :arguments
8
13
 
9
- def initialize(name, args=[])
14
+ def initialize(name, arguments=[])
10
15
  @name = name
11
- @args = args
16
+ @arguments = arguments
12
17
  end
13
18
 
14
19
  def ==(other)
15
- self.class == other.class &&
20
+ super(other) &&
16
21
  self.name == other.name &&
17
- self.args == other.args
22
+ self.arguments == other.arguments
23
+ end
24
+
25
+ def evaluate(context)
26
+ evaluated_arguments = arguments.map { |argument| argument.evaluate context }
27
+ context.program_context.definition_named(name, ->(definition) {
28
+ definition.evaluate context, evaluated_arguments
29
+ }, -> { raise Gobstones::Runner::DefinitionNotFound.new name } )
18
30
  end
19
31
 
20
32
  end
@@ -1,4 +1,5 @@
1
1
  require 'gobstones/lang/definitions/definition'
2
+ require 'gobstones/runner/execution_context'
2
3
  require 'gobstones/lang/definitions/return_from_function'
3
4
 
4
5
  module Gobstones
@@ -7,6 +8,14 @@ module Gobstones
7
8
 
8
9
  class Function < Definition
9
10
 
11
+ def definition_type
12
+ 'function'
13
+ end
14
+
15
+ def create_context_based_on(outer_context)
16
+ Gobstones::Runner::FunctionExecutionContext.based_on outer_context
17
+ end
18
+
10
19
  end
11
20
 
12
21
  end
@@ -10,7 +10,7 @@ module Gobstones
10
10
  class Main < Definition
11
11
 
12
12
  def initialize(body, return_statement)
13
- super('Main', VarTuple.new([]), body, return_statement)
13
+ super('Main', VarTuple.empty, body, return_statement)
14
14
  end
15
15
 
16
16
  def evaluate(context)
@@ -1,15 +1,19 @@
1
+ require 'gobstones/modules/equal_by_class'
2
+
1
3
  module Gobstones
2
4
 
3
5
  module Lang
4
6
 
5
7
  class NoReturnStatement
6
8
 
7
- def ==(other)
8
- self.class == other.class
9
+ include Gobstones::EqualByClass
10
+
11
+ def evaluate(context)
12
+ # nothing to do
9
13
  end
10
14
 
11
15
  end
12
16
 
13
17
  end
14
18
 
15
- end
19
+ end
@@ -1,7 +1,6 @@
1
1
  require 'gobstones/lang/definitions/definition'
2
2
  require 'gobstones/lang/definitions/no_return_statement'
3
3
  require 'gobstones/runner/execution_context'
4
- require 'gobstones/runner/errors/wrong_arguments_error'
5
4
 
6
5
  module Gobstones
7
6
 
@@ -15,30 +14,16 @@ module Gobstones
15
14
  super(name, args, body, NoReturnStatement.new)
16
15
  end
17
16
 
18
- def evaluate(context, arguments=[])
19
- check_number_of_arguments arguments
20
- procedure_context = Gobstones::Runner::ProcedureExecutionContext.based_on context
21
- set_arguments arguments, procedure_context
22
- body.evaluate procedure_context
17
+ def definition_type
18
+ 'procedure'
23
19
  end
24
20
 
25
- private
26
-
27
- def check_number_of_arguments(arguments)
28
- if args.length != arguments.length
29
- message = "Wrong number of arguments in procedure '#{name}': expected #{args.length}, got #{arguments.length}"
30
- raise Gobstones::Runner::WrongArgumentsError, message
31
- end
32
- end
33
-
34
- def set_arguments(arguments, procedure_context)
35
- args.length.times do |index|
36
- procedure_context.set args.variables[index], arguments[index]
37
- end
21
+ def create_context_based_on(outer_context)
22
+ Gobstones::Runner::ProcedureExecutionContext.based_on outer_context
38
23
  end
39
24
 
40
25
  end
41
26
 
42
27
  end
43
28
 
44
- end
29
+ end
@@ -1,9 +1,13 @@
1
+ require 'gobstones/modules/equal_by_class'
2
+
1
3
  module Gobstones
2
4
 
3
5
  module Lang
4
6
 
5
7
  class ReturnFromFunction
6
8
 
9
+ include Gobstones::EqualByClass
10
+
7
11
  attr_reader :expressions
8
12
 
9
13
  def initialize(expressions)
@@ -11,8 +15,14 @@ module Gobstones
11
15
  end
12
16
 
13
17
  def ==(other)
14
- self.class == other.class &&
15
- self.expressions == other.expressions
18
+ super(other) && self.expressions == other.expressions
19
+ end
20
+
21
+ def evaluate(context)
22
+ # TODO think more the case of gexp tuple, should it be a data type instead of a plain list?
23
+ expressions.size == 1 ?
24
+ expressions.first.evaluate(context) :
25
+ expressions.map { |expression| expression.evaluate context }
16
26
  end
17
27
 
18
28
  end
@@ -1,9 +1,13 @@
1
+ require 'gobstones/modules/equal_by_class'
2
+
1
3
  module Gobstones
2
4
 
3
5
  module Lang
4
6
 
5
7
  class ReturnFromMain
6
8
 
9
+ include Gobstones::EqualByClass
10
+
7
11
  attr_reader :var_tuple
8
12
 
9
13
  def initialize(var_tuple)
@@ -11,7 +15,7 @@ module Gobstones
11
15
  end
12
16
 
13
17
  def ==(other)
14
- self.class == other.class &&
18
+ super(other) &&
15
19
  self.var_tuple == other.var_tuple
16
20
  end
17
21
 
@@ -1,17 +1,25 @@
1
+ require 'gobstones/modules/equal_by_class'
2
+
1
3
  module Gobstones
2
4
 
3
5
  module Lang
4
6
 
5
7
  class VarTuple
6
8
 
9
+ include Gobstones::EqualByClass
10
+
7
11
  attr_reader :variables
8
12
 
13
+ def self.empty
14
+ self.new []
15
+ end
16
+
9
17
  def initialize(variables)
10
18
  @variables = variables
11
19
  end
12
20
 
13
21
  def ==(other)
14
- self.class == other.class &&
22
+ super(other) &&
15
23
  self.variables == other.variables
16
24
  end
17
25
 
@@ -19,6 +27,10 @@ module Gobstones
19
27
  variables.length
20
28
  end
21
29
 
30
+ def variable_at(index)
31
+ variables[index]
32
+ end
33
+
22
34
  end
23
35
 
24
36
  end