gobstones 0.0.1.1

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 (135) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/.rspec +3 -0
  4. data/.ruby-version +1 -0
  5. data/.simplecov +3 -0
  6. data/.travis.yml +4 -0
  7. data/CHANGELOG +4 -0
  8. data/Gemfile +12 -0
  9. data/Gemfile.lock +47 -0
  10. data/LICENSE +675 -0
  11. data/README.md +17 -0
  12. data/Rakefile +4 -0
  13. data/bin/gobstones +12 -0
  14. data/gobstones.gemspec +24 -0
  15. data/lib/gobstones/cli/board_template +39 -0
  16. data/lib/gobstones/cli/printer.rb +106 -0
  17. data/lib/gobstones/cli/runner.rb +52 -0
  18. data/lib/gobstones/extensions/all.rb +2 -0
  19. data/lib/gobstones/extensions/boolean.rb +17 -0
  20. data/lib/gobstones/extensions/fixnum.rb +9 -0
  21. data/lib/gobstones/lang/all.rb +5 -0
  22. data/lib/gobstones/lang/commands/all.rb +13 -0
  23. data/lib/gobstones/lang/commands/assignments.rb +29 -0
  24. data/lib/gobstones/lang/commands/boom_cmd.rb +28 -0
  25. data/lib/gobstones/lang/commands/command_block.rb +37 -0
  26. data/lib/gobstones/lang/commands/conditional_cmd.rb +27 -0
  27. data/lib/gobstones/lang/commands/if_cmd.rb +38 -0
  28. data/lib/gobstones/lang/commands/ir_al_origen_cmd.rb +19 -0
  29. data/lib/gobstones/lang/commands/mover_cmd.rb +25 -0
  30. data/lib/gobstones/lang/commands/poner_cmd.rb +31 -0
  31. data/lib/gobstones/lang/commands/procedure_call.rb +23 -0
  32. data/lib/gobstones/lang/commands/repeat_with_cmd.rb +73 -0
  33. data/lib/gobstones/lang/commands/sacar_cmd.rb +31 -0
  34. data/lib/gobstones/lang/commands/skip_cmd.rb +19 -0
  35. data/lib/gobstones/lang/commands/vaciar_tablero_cmd.rb +19 -0
  36. data/lib/gobstones/lang/commands/while_cmd.rb +25 -0
  37. data/lib/gobstones/lang/definitions/all.rb +4 -0
  38. data/lib/gobstones/lang/definitions/definition.rb +32 -0
  39. data/lib/gobstones/lang/definitions/definition_call.rb +24 -0
  40. data/lib/gobstones/lang/definitions/function.rb +14 -0
  41. data/lib/gobstones/lang/definitions/main.rb +26 -0
  42. data/lib/gobstones/lang/definitions/no_return_statement.rb +15 -0
  43. data/lib/gobstones/lang/definitions/procedure.rb +44 -0
  44. data/lib/gobstones/lang/definitions/return_from_function.rb +22 -0
  45. data/lib/gobstones/lang/definitions/return_from_main.rb +22 -0
  46. data/lib/gobstones/lang/definitions/var_tuple.rb +26 -0
  47. data/lib/gobstones/lang/expressions/all.rb +8 -0
  48. data/lib/gobstones/lang/expressions/arithmetic_expressions.rb +52 -0
  49. data/lib/gobstones/lang/expressions/boolean_expressions.rb +29 -0
  50. data/lib/gobstones/lang/expressions/comparison_expressions.rb +45 -0
  51. data/lib/gobstones/lang/expressions/function_call.rb +15 -0
  52. data/lib/gobstones/lang/expressions/one_arg_expression.rb +21 -0
  53. data/lib/gobstones/lang/expressions/parentheses_expression.rb +13 -0
  54. data/lib/gobstones/lang/expressions/primitive_functions.rb +68 -0
  55. data/lib/gobstones/lang/expressions/two_arg_expression.rb +34 -0
  56. data/lib/gobstones/lang/expressions/type_bound_functions.rb +66 -0
  57. data/lib/gobstones/lang/expressions/var_name.rb +31 -0
  58. data/lib/gobstones/lang/literals/all.rb +4 -0
  59. data/lib/gobstones/lang/literals/booleans.rb +109 -0
  60. data/lib/gobstones/lang/literals/colors.rb +94 -0
  61. data/lib/gobstones/lang/literals/directions.rb +137 -0
  62. data/lib/gobstones/lang/literals/literal.rb +63 -0
  63. data/lib/gobstones/lang/literals/number.rb +49 -0
  64. data/lib/gobstones/lang/program.rb +32 -0
  65. data/lib/gobstones/modules/equal_by_class.rb +13 -0
  66. data/lib/gobstones/parser/ast/ast.rb +210 -0
  67. data/lib/gobstones/parser/grammar/gobstones.treetop +316 -0
  68. data/lib/gobstones/parser/parse_error.rb +17 -0
  69. data/lib/gobstones/parser/treetop_parser.rb +73 -0
  70. data/lib/gobstones/runner/all.rb +6 -0
  71. data/lib/gobstones/runner/board.rb +57 -0
  72. data/lib/gobstones/runner/cell.rb +60 -0
  73. data/lib/gobstones/runner/errors/all.rb +8 -0
  74. data/lib/gobstones/runner/errors/boom_error.rb +11 -0
  75. data/lib/gobstones/runner/errors/definition_not_found_error.rb +19 -0
  76. data/lib/gobstones/runner/errors/empty_cell_error.rb +11 -0
  77. data/lib/gobstones/runner/errors/gobstones_runtime_error.rb +11 -0
  78. data/lib/gobstones/runner/errors/gobstones_type_error.rb +11 -0
  79. data/lib/gobstones/runner/errors/out_of_board_error.rb +11 -0
  80. data/lib/gobstones/runner/errors/undefined_variable_error.rb +11 -0
  81. data/lib/gobstones/runner/errors/wrong_arguments_error.rb +11 -0
  82. data/lib/gobstones/runner/execution_context.rb +89 -0
  83. data/lib/gobstones/runner/head.rb +101 -0
  84. data/lib/gobstones/type_check_result.rb +16 -0
  85. data/spec/lang/commands/assignments_spec.rb +13 -0
  86. data/spec/lang/commands/boom_cmd_spec.rb +8 -0
  87. data/spec/lang/commands/cmd_block_spec.rb +21 -0
  88. data/spec/lang/commands/if_cmd_spec.rb +49 -0
  89. data/spec/lang/commands/ir_al_origen_cmd_spec.rb +16 -0
  90. data/spec/lang/commands/mover_cmd_spec.rb +38 -0
  91. data/spec/lang/commands/poner_cmd_spec.rb +29 -0
  92. data/spec/lang/commands/procedure_call_spec.rb +44 -0
  93. data/spec/lang/commands/procedure_spec.rb +67 -0
  94. data/spec/lang/commands/repeat_with_cmd_spec.rb +41 -0
  95. data/spec/lang/commands/sacar_cmd_spec.rb +34 -0
  96. data/spec/lang/commands/skip_cmd_spec.rb +12 -0
  97. data/spec/lang/commands/vaciar_tablero_cmd_spec.rb +13 -0
  98. data/spec/lang/commands/while_cmd_spec.rb +37 -0
  99. data/spec/lang/expressions/arithmetic_expressions_spec.rb +108 -0
  100. data/spec/lang/expressions/boolean_expressions_spec.rb +56 -0
  101. data/spec/lang/expressions/comparison_expressions_spec.rb +285 -0
  102. data/spec/lang/expressions/primitive_functions_spec.rb +126 -0
  103. data/spec/lang/expressions/type_bound_functions_spec.rb +39 -0
  104. data/spec/lang/expressions/var_name_spec.rb +16 -0
  105. data/spec/lang/literals/booleans_spec.rb +13 -0
  106. data/spec/lang/literals/colors_spec.rb +13 -0
  107. data/spec/lang/literals/directions_spec.rb +45 -0
  108. data/spec/lang/literals/numbers_spec.rb +8 -0
  109. data/spec/matchers/parse_matcher.rb +84 -0
  110. data/spec/parser/arithmetic_expressions_spec.rb +129 -0
  111. data/spec/parser/assignments_spec.rb +39 -0
  112. data/spec/parser/boolean_expressions_spec.rb +111 -0
  113. data/spec/parser/command_block_spec.rb +50 -0
  114. data/spec/parser/data_types_spec.rb +67 -0
  115. data/spec/parser/function_calls_spec.rb +37 -0
  116. data/spec/parser/function_definitions_spec.rb +50 -0
  117. data/spec/parser/gobstones_program_spec.rb +55 -0
  118. data/spec/parser/if_command_spec.rb +46 -0
  119. data/spec/parser/main_definition_spec.rb +42 -0
  120. data/spec/parser/nested_expressions_spec.rb +39 -0
  121. data/spec/parser/primitive_expressions_spec.rb +105 -0
  122. data/spec/parser/procedure_calls_spec.rb +36 -0
  123. data/spec/parser/procedure_definitions_spec.rb +39 -0
  124. data/spec/parser/repeat_with_command_spec.rb +23 -0
  125. data/spec/parser/simple_commands_spec.rb +62 -0
  126. data/spec/parser/treetop_parser_spec.rb +109 -0
  127. data/spec/parser/var_tuple_spec.rb +30 -0
  128. data/spec/parser/while_command_spec.rb +30 -0
  129. data/spec/runner/board_spec.rb +85 -0
  130. data/spec/runner/cell_spec.rb +72 -0
  131. data/spec/runner/execution_context_spec.rb +64 -0
  132. data/spec/runner/head_spec.rb +139 -0
  133. data/spec/spec_helper.rb +15 -0
  134. data/spec/type_checker_spec.rb +37 -0
  135. metadata +242 -0
@@ -0,0 +1,19 @@
1
+ require 'gobstones/modules/equal_by_class'
2
+
3
+ module Gobstones
4
+
5
+ module Lang
6
+
7
+ class IrAlOrigen
8
+
9
+ include Gobstones::EqualByClass
10
+
11
+ def evaluate(context)
12
+ context.head.go_to_origin
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,25 @@
1
+ require 'gobstones/lang/expressions/one_arg_expression'
2
+
3
+ module Gobstones
4
+
5
+ module Lang
6
+
7
+ class Mover < OneArgExpression
8
+
9
+ def evaluate(context)
10
+ context.head.move arg.evaluate(context)
11
+ end
12
+
13
+ def undo(context)
14
+ opposite.evaluate context
15
+ end
16
+
17
+ def opposite
18
+ Mover.new arg.opposite
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,31 @@
1
+ require 'gobstones/lang/expressions/one_arg_expression'
2
+ require 'gobstones/lang/commands/sacar_cmd'
3
+ require 'gobstones/runner/errors/gobstones_type_error'
4
+
5
+ module Gobstones
6
+
7
+ module Lang
8
+
9
+ class Poner < OneArgExpression
10
+
11
+ def evaluate(context)
12
+ context.head.put arg.evaluate(context)
13
+ rescue RuntimeError => e
14
+ raise Gobstones::Runner::GobstonesTypeError, e.message
15
+ end
16
+
17
+ def undo(context)
18
+ # TODO maybe the command should use the original context
19
+ # instead of this one (when it was executed)
20
+ context.head.take_out arg.evaluate(context)
21
+ end
22
+
23
+ def opposite
24
+ Sacar.new arg
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,23 @@
1
+ require 'gobstones/lang/definitions/definition_call'
2
+ require 'gobstones/runner/errors/definition_not_found_error'
3
+
4
+ module Gobstones
5
+
6
+ module Lang
7
+
8
+ class ProcedureCall
9
+
10
+ include DefinitionCall
11
+
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
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,73 @@
1
+ require 'gobstones/lang/commands/assignments'
2
+ require 'gobstones/lang/commands/command_block'
3
+ require 'gobstones/lang/commands/while_cmd'
4
+ require 'gobstones/lang/expressions/comparison_expressions'
5
+ require 'gobstones/lang/expressions/primitive_functions'
6
+ require 'gobstones/runner/errors/gobstones_runtime_error'
7
+ require 'gobstones/runner/errors/gobstones_type_error'
8
+
9
+ module Gobstones
10
+
11
+ module Lang
12
+
13
+ class RepeatWithCmd
14
+
15
+ attr_reader :var_name, :range_min, :range_max, :cmd_block
16
+
17
+ def initialize(var_name, range_min, range_max, cmd_block)
18
+ @var_name = var_name
19
+ @range_min = range_min
20
+ @range_max = range_max
21
+ @cmd_block = cmd_block
22
+ end
23
+
24
+ def ==(other)
25
+ self.class == other.class &&
26
+ self.var_name == other.var_name &&
27
+ self.range_min == other.range_min &&
28
+ self.range_max == other.range_max &&
29
+ self.cmd_block == other.cmd_block
30
+ end
31
+
32
+ def evaluate(context)
33
+ validate_range_values context
34
+ validate_index_variable_not_defined context
35
+ while_based_equivalent_cmd.evaluate context
36
+ clear_index_variable_from context
37
+ end
38
+
39
+ private
40
+
41
+ def clear_index_variable_from(context)
42
+ context.clear var_name
43
+ end
44
+
45
+ def validate_range_values(context)
46
+ raise Gobstones::Runner::GobstonesTypeError, "types don't match in range values" \
47
+ unless range_min.evaluate(context).same_type_as(range_max.evaluate(context))
48
+ end
49
+
50
+ def validate_index_variable_not_defined(context)
51
+ raise Gobstones::Runner::GobstonesRuntimeError, "index variable can't be used because it's already defined" \
52
+ if context.has_variable_named?(var_name.name)
53
+ end
54
+
55
+ def while_based_equivalent_cmd
56
+ #
57
+ # repeatWith var in min..max block
58
+ # is equivalent to
59
+ # { var := min; while (var < max) { block; var := siguiente(var) }; block }
60
+ #
61
+ assign_cmd = SingleAssignment.new var_name, range_min
62
+ while_cond = LessThan.new var_name, range_max
63
+ increment = SingleAssignment.new var_name, Siguiente.new(var_name)
64
+ while_block = CmdBlock.new [cmd_block, increment]
65
+ while_cmd = WhileCmd.new while_cond, while_block
66
+ CmdBlock.new [assign_cmd, while_cmd, cmd_block]
67
+ end
68
+
69
+ end
70
+
71
+ end
72
+
73
+ end
@@ -0,0 +1,31 @@
1
+ require 'gobstones/lang/expressions/one_arg_expression'
2
+ require 'gobstones/lang/commands/poner_cmd'
3
+ require 'gobstones/runner/errors/gobstones_type_error'
4
+
5
+ module Gobstones
6
+
7
+ module Lang
8
+
9
+ class Sacar < OneArgExpression
10
+
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
16
+ end
17
+ end
18
+
19
+ def undo(context)
20
+ context.head.put arg.evaluate(context)
21
+ end
22
+
23
+ def opposite
24
+ Poner.new arg
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,19 @@
1
+ require 'gobstones/modules/equal_by_class'
2
+
3
+ module Gobstones
4
+
5
+ module Lang
6
+
7
+ class Skip
8
+
9
+ include Gobstones::EqualByClass
10
+
11
+ def evaluate(context=nil)
12
+ # do nothing, that's my job :-)
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'gobstones/modules/equal_by_class'
2
+
3
+ module Gobstones
4
+
5
+ module Lang
6
+
7
+ class VaciarTablero
8
+
9
+ include Gobstones::EqualByClass
10
+
11
+ def evaluate(context)
12
+ context.board.empty!
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,25 @@
1
+ require 'gobstones/lang/commands/conditional_cmd'
2
+ require 'gobstones/runner/errors/gobstones_runtime_error'
3
+
4
+ module Gobstones
5
+
6
+ module Lang
7
+
8
+ class WhileCmd < ConditionalCmd
9
+
10
+ STACK_LIMIT = 10000
11
+
12
+ def evaluate(context)
13
+ stack_acc = 0
14
+ while evaluate_condition(context).is_true?
15
+ raise Gobstones::Runner::GobstonesRuntimeError, 'stack overflow' if stack_acc == STACK_LIMIT
16
+ then_block.evaluate context
17
+ stack_acc += 1
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+
25
+ end
@@ -0,0 +1,4 @@
1
+ require 'gobstones/lang/definitions/function'
2
+ require 'gobstones/lang/definitions/main'
3
+ require 'gobstones/lang/definitions/procedure'
4
+ require 'gobstones/lang/definitions/var_tuple'
@@ -0,0 +1,32 @@
1
+ module Gobstones
2
+
3
+ module Lang
4
+
5
+ class Definition
6
+
7
+ attr_reader :name, :args, :body, :return_statement
8
+
9
+ def initialize(name, args, body, return_statement)
10
+ @name = name
11
+ @args = args
12
+ @body = body
13
+ @return_statement = return_statement
14
+ end
15
+
16
+ def ==(other)
17
+ self.class == other.class &&
18
+ self.name == other.name &&
19
+ self.args == other.args &&
20
+ self.body == other.body &&
21
+ self.return_statement == other.return_statement
22
+ end
23
+
24
+ def named?(a_name)
25
+ name == a_name
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,24 @@
1
+ module Gobstones
2
+
3
+ module Lang
4
+
5
+ module DefinitionCall
6
+
7
+ attr_reader :name, :args
8
+
9
+ def initialize(name, args=[])
10
+ @name = name
11
+ @args = args
12
+ end
13
+
14
+ def ==(other)
15
+ self.class == other.class &&
16
+ self.name == other.name &&
17
+ self.args == other.args
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,14 @@
1
+ require 'gobstones/lang/definitions/definition'
2
+ require 'gobstones/lang/definitions/return_from_function'
3
+
4
+ module Gobstones
5
+
6
+ module Lang
7
+
8
+ class Function < Definition
9
+
10
+ end
11
+
12
+ end
13
+
14
+ end
@@ -0,0 +1,26 @@
1
+ require 'gobstones/lang/definitions/definition'
2
+ require 'gobstones/lang/definitions/var_tuple'
3
+ require 'gobstones/lang/definitions/no_return_statement'
4
+ require 'gobstones/lang/definitions/return_from_main'
5
+
6
+ module Gobstones
7
+
8
+ module Lang
9
+
10
+ class Main < Definition
11
+
12
+ def initialize(body, return_statement)
13
+ super('Main', VarTuple.new([]), body, return_statement)
14
+ end
15
+
16
+ def evaluate(context)
17
+ # evaluate body
18
+ body.evaluate context
19
+ # evaluate return
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,15 @@
1
+ module Gobstones
2
+
3
+ module Lang
4
+
5
+ class NoReturnStatement
6
+
7
+ def ==(other)
8
+ self.class == other.class
9
+ end
10
+
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,44 @@
1
+ require 'gobstones/lang/definitions/definition'
2
+ require 'gobstones/lang/definitions/no_return_statement'
3
+ require 'gobstones/runner/execution_context'
4
+ require 'gobstones/runner/errors/wrong_arguments_error'
5
+
6
+ module Gobstones
7
+
8
+ module Lang
9
+
10
+ class Procedure < Definition
11
+
12
+ # TODO rename args to a better name, args_tuple?
13
+
14
+ def initialize(name, args, body)
15
+ super(name, args, body, NoReturnStatement.new)
16
+ end
17
+
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
23
+ end
24
+
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
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+
44
+ end