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,32 @@
1
+ require 'gobstones/runner/execution_context'
2
+
3
+ module Gobstones
4
+
5
+ module Lang
6
+
7
+ class Program
8
+
9
+ attr_reader :definitions, :main_definition
10
+
11
+ def initialize(definitions, main_definition)
12
+ @definitions = definitions
13
+ @main_definition = main_definition
14
+ end
15
+
16
+ def ==(other)
17
+ self.class == other.class &&
18
+ self.definitions == other.definitions &&
19
+ self.main_definition == other.main_definition
20
+ end
21
+
22
+ def evaluate
23
+ context = Gobstones::Runner::ProgramExecutionContext.for self
24
+ main_definition.evaluate context
25
+ context
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,13 @@
1
+ module Gobstones
2
+
3
+ module EqualByClass
4
+
5
+ def ==(other)
6
+ self.class == other.class
7
+ end
8
+
9
+ alias_method :eql?, :==
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,210 @@
1
+ require 'gobstones/lang/all'
2
+
3
+ module Gobstones
4
+
5
+ # TODO divide into smaller modules
6
+ module Parser
7
+
8
+ include Gobstones::Lang
9
+
10
+ RESERVED_IDS = %w(
11
+ if else not True False case of while Skip repeatWith in procedure function
12
+ return Mover Sacar Poner BOOM IrAlOrigen VaciarTablero div mod hayBolitas
13
+ nroBolitas puedeMover Norte Sur Este Oeste minBool maxBool minDir maxDir
14
+ minColor maxColor siguiente previo opuesto Verde Rojo Azul Negro Main
15
+ )
16
+
17
+ def self.ast_node(name, &value_block)
18
+ # TODO check if it is better to have classes
19
+ mod = Module.new do
20
+ define_method :value do
21
+ instance_eval(&value_block)
22
+ end
23
+ end
24
+ const_set name, mod
25
+ end
26
+
27
+ ast_node(:IntegerLiteral) { Number.new text_value.to_i }
28
+ ast_node(:BooleanLiteral) { Kernel.const_get(text_value).new }
29
+ ast_node(:ColorLiteral) { Kernel.const_get(text_value).new }
30
+ ast_node(:DirectionLiteral) { Kernel.const_get(text_value).new }
31
+
32
+ ast_node(:MinBoolFuncNode) { MinBool.new }
33
+ ast_node(:MaxBoolFuncNode) { MaxBool.new }
34
+ ast_node(:MinColorFuncNode) { MinColor.new }
35
+ ast_node(:MaxColorFuncNode) { MaxColor.new }
36
+ ast_node(:MinDirFuncNode) { MinDir.new }
37
+ ast_node(:MaxDirFuncNode) { MaxDir.new }
38
+
39
+ ast_node(:VarNameNode) { VarName.new text_value }
40
+
41
+ ast_node(:NroBolitasFuncNode) { NroBolitas.new gexp.value }
42
+ ast_node(:HayBolitasFuncNode) { HayBolitas.new gexp.value }
43
+ ast_node(:PuedeMoverFuncNode) { PuedeMover.new gexp.value }
44
+ ast_node(:SiguienteFuncNode) { Siguiente.new gexp.value }
45
+ ast_node(:PrevioFuncNode) { Previo.new gexp.value }
46
+ ast_node(:OpuestoFuncNode) { Opuesto.new gexp.value }
47
+
48
+ ast_node :NopExprNode do
49
+ if sub_exps.empty?
50
+ left.value
51
+ else
52
+ # it is a nested exp
53
+ sub_exps.elements.inject(left.value) do |memo, node|
54
+ case node.op.text_value
55
+ when '+'
56
+ memo = Add.new memo, node.right.value
57
+ when '-'
58
+ memo = Sub.new memo, node.right.value
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ ast_node :MulExprNode do
65
+ if sub_exps.empty?
66
+ left.value
67
+ else
68
+ # it is a nested exp
69
+ sub_exps.elements.inject(left.value) do |memo, node|
70
+ memo = Mul.new memo, node.right.value
71
+ end
72
+ end
73
+ end
74
+
75
+ ast_node :DivModExprNode do
76
+ case op.text_value
77
+ when 'div'
78
+ Div.new left.value, right.value
79
+ when 'mod'
80
+ Mod.new left.value, right.value
81
+ end
82
+ end
83
+
84
+ ast_node :PowExprNode do
85
+ if sub_exps.empty?
86
+ left.value
87
+ else
88
+ # it is a nested exp
89
+ sub_exps.elements.inject(left.value) do |memo, node|
90
+ memo = Pow.new memo, node.right.value
91
+ end
92
+ end
93
+ end
94
+
95
+ ast_node :RopExprNode do
96
+ classes = {
97
+ '==' => Equal, '/=' => NotEqual,
98
+ '<' => LessThan, '>' => GreaterThan,
99
+ '<=' => LessEqual, '>=' => GreaterEqual
100
+ }
101
+ classes[rop.text_value].new left.value, right.value
102
+ end
103
+
104
+ ast_node(:NotExprNode) { Not.new exp.value }
105
+ ast_node(:AndExprNode) { And.new left.value, right.value }
106
+ ast_node(:OrExprNode) { Or.new left.value, right.value }
107
+
108
+ ast_node(:ParenthesesExprNode) { ParenthesesExpr.new gexp.value }
109
+ ast_node(:FuncCallNode) do
110
+ FunctionCall.new func_name.text_value, gexp_tuple.value
111
+ end
112
+ ast_node(:TupleExprNode) { exps.empty? ? [] : exps.value }
113
+
114
+ ast_node :GexpsNode do
115
+ if elements.length == 2
116
+ [elements[0].value]
117
+ else
118
+ [exp.value] + exps.value
119
+ end
120
+ end
121
+
122
+ ast_node(:SkipCmdNode) { Skip.new }
123
+ ast_node(:BoomCmdNode) { Boom.new string.text_value[1..-2] }
124
+
125
+ ast_node(:PonerCmdNode) { Poner.new gexp.value }
126
+ ast_node(:SacarCmdNode) { Sacar.new gexp.value }
127
+ ast_node(:MoverCmdNode) { Mover.new gexp.value }
128
+
129
+ ast_node(:IrAlOrigenCmdNode) { IrAlOrigen.new }
130
+ ast_node(:VaciarTableroCmdNode) { VaciarTablero.new }
131
+
132
+ ast_node :ProcCallNode do
133
+ ProcedureCall.new proc_name.text_value, gexp_tuple.value
134
+ end
135
+
136
+ ast_node :SingleAssignmentNode do
137
+ SingleAssignment.new var_name.value, gexp.value
138
+ end
139
+
140
+ ast_node :CmdBlockNode do
141
+ CmdBlock.new create_commands(commands)
142
+ end
143
+
144
+ ast_node :IfCmdNode do
145
+ if else_clause.empty?
146
+ IfCmd.new gexp.value, then_block.value
147
+ else
148
+ IfElseCmd.new gexp.value, then_block.value, else_clause.else_block.value
149
+ end
150
+ end
151
+
152
+ ast_node(:WhileCmdNode) { WhileCmd.new gexp.value, cmd_block.value }
153
+
154
+ ast_node :RepeatWithCmdNode do
155
+ RepeatWithCmd.new var_name.value, range_min.value,
156
+ range_max.value, cmd_block.value
157
+ end
158
+
159
+ # TODO abstract duplication, very similar to GexpsNode
160
+ ast_node(:VarNamesNode) do
161
+ if elements.length == 2
162
+ # TODO check why it is needed to create a VarName
163
+ # instead of having already a VarName in elements[0]
164
+ [VarName.new(elements[0].text_value)]
165
+ else
166
+ [vn.value] + vns.value
167
+ end
168
+ end
169
+
170
+ ast_node(:VarTupleNode) do
171
+ variables = vns.empty? ? [] : vns.value
172
+ VarTuple.new variables
173
+ end
174
+
175
+ ast_node(:ProcedureNode) do
176
+ Procedure.new proc_name.text_value, var_tuple.value, cmd_block.value
177
+ end
178
+
179
+ ast_node(:FunctionNode) do
180
+ cmd_block = CmdBlock.new create_commands(commands)
181
+ Function.new func_name.text_value, var_tuple.value,
182
+ cmd_block, func_return.value
183
+ end
184
+
185
+ ast_node(:FuncReturnNode) do
186
+ ReturnFromFunction.new gexp_tuple_1.value
187
+ end
188
+
189
+ ast_node(:MainReturnNode) do
190
+ ReturnFromMain.new var_tuple.value
191
+ end
192
+
193
+ ast_node(:MainDefNode) do
194
+ cmd_block = CmdBlock.new create_commands(commands)
195
+ return_st = ret.empty? ? NoReturnStatement.new : ret.value
196
+ Main.new cmd_block, return_st
197
+ end
198
+
199
+ ast_node(:ProgramNode) do
200
+ defs = definitions.elements.map { |node| node.definition.value }
201
+ Program.new defs, main_def.value
202
+ end
203
+
204
+ def create_commands(commands)
205
+ commands.elements.map { |node| node.command.value }
206
+ end
207
+
208
+ end
209
+
210
+ end
@@ -0,0 +1,316 @@
1
+ # TODO modularize when possible
2
+ grammar Gobstones
3
+
4
+ # TOP RULE: program
5
+
6
+ rule program
7
+ definitions main_def space* <ProgramNode>
8
+ end
9
+
10
+ # DEFINITIONS: main, procedures, functions
11
+
12
+ rule definitions
13
+ (space* definition space*)*
14
+ end
15
+
16
+ rule definition
17
+ procedure_def / function_def
18
+ end
19
+
20
+ rule main_def
21
+ 'procedure' space+ 'Main' space* '(' space* ')' space*
22
+ '{' space* commands ret:main_return? space* '}' <MainDefNode>
23
+ end
24
+
25
+ rule main_return
26
+ 'return' space* var_tuple space* ';'? <MainReturnNode>
27
+ end
28
+
29
+ rule procedure_def
30
+ 'procedure' space+ proc_name space*
31
+ var_tuple space* cmd_block <ProcedureNode>
32
+ end
33
+
34
+ rule function_def
35
+ 'function' space+ func_name space* var_tuple space*
36
+ '{' space* commands func_return space* '}' <FunctionNode>
37
+ end
38
+
39
+ rule func_return
40
+ 'return' space* gexp_tuple_1 space* ';'? <FuncReturnNode>
41
+ end
42
+
43
+ # COMMANDS
44
+
45
+ rule commands
46
+ (command space* ';'? space*)*
47
+ end
48
+
49
+ rule command
50
+ simple_cmd / complex_cmd
51
+ end
52
+
53
+ rule simple_cmd
54
+ skip_cmd / boom_cmd / poner_cmd / sacar_cmd / mover_cmd /
55
+ ir_al_origen_cmd / vaciar_tablero_cmd / proc_call /
56
+ cmd_block / single_assignment # / multiple_assignment
57
+ end
58
+
59
+ rule skip_cmd
60
+ 'Skip' <SkipCmdNode>
61
+ end
62
+
63
+ rule boom_cmd
64
+ 'BOOM' space* '(' space* string space* ')' <BoomCmdNode>
65
+ end
66
+
67
+ rule poner_cmd
68
+ 'Poner' space* '(' space* gexp space* ')' <PonerCmdNode>
69
+ end
70
+
71
+ rule sacar_cmd
72
+ 'Sacar' space* '(' space* gexp space* ')' <SacarCmdNode>
73
+ end
74
+
75
+ rule mover_cmd
76
+ 'Mover' space* '(' space* gexp space* ')' <MoverCmdNode>
77
+ end
78
+
79
+ rule ir_al_origen_cmd
80
+ 'IrAlOrigen' space* '(' space* ')' <IrAlOrigenCmdNode>
81
+ end
82
+
83
+ rule vaciar_tablero_cmd
84
+ 'VaciarTablero' space* '(' space* ')' <VaciarTableroCmdNode>
85
+ end
86
+
87
+ rule proc_call
88
+ proc_name space* gexp_tuple <ProcCallNode>
89
+ end
90
+
91
+ rule cmd_block
92
+ '{' space* commands space* '}' <CmdBlockNode>
93
+ end
94
+
95
+ rule single_assignment
96
+ var_name space* ':=' space* gexp <SingleAssignmentNode>
97
+ end
98
+
99
+ # TODO implement
100
+ # rule multiple_assignment
101
+ # end
102
+
103
+ rule complex_cmd
104
+ if_cmd / while_cmd / repeat_with_cmd # / case_cmd
105
+ end
106
+
107
+ rule if_cmd
108
+ 'if' space* '(' space* gexp space* ')'
109
+ space* then_block:cmd_block
110
+ else_clause:(space* 'else' space* else_block:cmd_block)?
111
+ <IfCmdNode>
112
+ end
113
+
114
+ rule while_cmd
115
+ 'while' space* '(' space* gexp space* ')' space* cmd_block <WhileCmdNode>
116
+ end
117
+
118
+ rule repeat_with_cmd
119
+ 'repeatWith' space+ var_name space+ 'in' space+
120
+ range_min:gexp space* '..' space* range_max:gexp space*
121
+ cmd_block <RepeatWithCmdNode>
122
+ end
123
+
124
+ # TODO implement
125
+ # rule case_cmd
126
+ # end
127
+
128
+ # EXPRESSIONS
129
+
130
+ rule gexp
131
+ bexp
132
+ end
133
+
134
+ rule bexp
135
+ left:bterm space* '||' space* right:bexp <OrExprNode> / bterm
136
+ end
137
+
138
+ rule bterm
139
+ left:bfact space* '&&' space* right:bterm <AndExprNode> / bfact
140
+ end
141
+
142
+ rule bfact
143
+ 'not' space+ exp:batom <NotExprNode> / batom
144
+ end
145
+
146
+ rule batom
147
+ left:nexp space* rop space* right:nexp <RopExprNode> / nexp
148
+ end
149
+
150
+ rule rop
151
+ '==' / '/=' / '<=' / '>=' / '<' / '>'
152
+ end
153
+
154
+ rule nexp
155
+ left:nterm sub_exps:(space* op:[+-] space* right:nterm)* <NopExprNode>
156
+ end
157
+
158
+ rule nterm
159
+ left:nfactH sub_exps:(space* '*' space* right:nfactH)* <MulExprNode>
160
+ end
161
+
162
+ rule nfactH
163
+ left:nfactL space+ op:mop space+ right:nfactL <DivModExprNode> / nfactL
164
+ end
165
+
166
+ rule mop
167
+ 'div' / 'mod'
168
+ end
169
+
170
+ rule nfactL
171
+ left:natom sub_exps:(space* '^' space* right:natom)* <PowExprNode>
172
+ end
173
+
174
+ rule natom
175
+ literal / type_bound_func / primitive_func /
176
+ paren_expr / func_call / var_name
177
+ end
178
+
179
+ rule type_bound_func
180
+ bool_type_bound_func / color_type_bound_func / direction_type_bound_func
181
+ end
182
+
183
+ rule bool_type_bound_func
184
+ 'minBool()' <MinBoolFuncNode> / 'maxBool()' <MaxBoolFuncNode>
185
+ end
186
+
187
+ rule color_type_bound_func
188
+ 'minColor()' <MinColorFuncNode> / 'maxColor()' <MaxColorFuncNode>
189
+ end
190
+
191
+ rule direction_type_bound_func
192
+ 'minDir()' <MinDirFuncNode> / 'maxDir()' <MaxDirFuncNode>
193
+ end
194
+
195
+ rule primitive_func
196
+ nro_bolitas_func / hay_bolitas_func / puede_mover_func /
197
+ siguiente_func / previo_func / opuesto_func
198
+ end
199
+
200
+ rule nro_bolitas_func
201
+ 'nroBolitas' space* '(' space* gexp space* ')' <NroBolitasFuncNode>
202
+ end
203
+
204
+ rule hay_bolitas_func
205
+ 'hayBolitas' space* '(' space* gexp space* ')' <HayBolitasFuncNode>
206
+ end
207
+
208
+ rule puede_mover_func
209
+ 'puedeMover' space* '(' space* gexp space* ')' <PuedeMoverFuncNode>
210
+ end
211
+
212
+ rule siguiente_func
213
+ 'siguiente' space* '(' space* gexp space* ')' <SiguienteFuncNode>
214
+ end
215
+
216
+ rule previo_func
217
+ 'previo' space* '(' space* gexp space* ')' <PrevioFuncNode>
218
+ end
219
+
220
+ rule opuesto_func
221
+ 'opuesto' space* '(' space* gexp space* ')' <OpuestoFuncNode>
222
+ end
223
+
224
+ rule paren_expr
225
+ '(' space* gexp space* ')' <ParenthesesExprNode>
226
+ end
227
+
228
+ rule func_call
229
+ func_name space* gexp_tuple <FuncCallNode>
230
+ end
231
+
232
+ rule var_name
233
+ lower_id &{ |id| id[0].is_not_reserved } <VarNameNode>
234
+ end
235
+
236
+ # LITERALS
237
+
238
+ rule literal
239
+ number / boolean / color / direction
240
+ end
241
+
242
+ rule number
243
+ '-'? [0-9] [0-9]* <IntegerLiteral>
244
+ end
245
+
246
+ rule boolean
247
+ ('True' / 'False') <BooleanLiteral>
248
+ end
249
+
250
+ rule color
251
+ ('Azul' / 'Negro' / 'Rojo' / 'Verde') <ColorLiteral>
252
+ end
253
+
254
+ rule direction
255
+ ('Norte' / 'Este' / 'Sur' / 'Oeste') <DirectionLiteral>
256
+ end
257
+
258
+ # AUX DEFINITIONS: identifiers, tuples
259
+
260
+ rule proc_name
261
+ upper_id &{ |id| id[0].is_not_reserved }
262
+ end
263
+
264
+ rule func_name
265
+ lower_id &{ |id| id[0].is_not_reserved }
266
+ end
267
+
268
+ rule var_tuple
269
+ '(' space* vns:var_names? space* ')' <VarTupleNode>
270
+ end
271
+
272
+ rule var_names
273
+ ((vn:var_name space* ',' space* vns:var_names) / var_name) <VarNamesNode>
274
+ end
275
+
276
+ rule gexp_tuple
277
+ '(' space* exps:gexps? space* ')' <TupleExprNode>
278
+ end
279
+
280
+ rule gexp_tuple_1
281
+ '(' space* exps:gexps space* ')' <TupleExprNode>
282
+ end
283
+
284
+ rule gexps
285
+ ((exp:gexp space* ',' space* exps:gexps) / gexp) <GexpsNode>
286
+ end
287
+
288
+ rule lower_id
289
+ [a-z] char* {
290
+ def is_not_reserved
291
+ !Gobstones::Parser::RESERVED_IDS.include? text_value
292
+ end
293
+ }
294
+ end
295
+
296
+ rule upper_id
297
+ [A-Z] char* {
298
+ def is_not_reserved
299
+ !Gobstones::Parser::RESERVED_IDS.include? text_value
300
+ end
301
+ }
302
+ end
303
+
304
+ rule char
305
+ [a-zA-Z0-9'_]
306
+ end
307
+
308
+ rule string
309
+ '"' ('\"' / !'"' .)* '"'
310
+ end
311
+
312
+ rule space
313
+ [\s]
314
+ end
315
+
316
+ end