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.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/.simplecov +3 -0
- data/.travis.yml +4 -0
- data/CHANGELOG +4 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +47 -0
- data/LICENSE +675 -0
- data/README.md +17 -0
- data/Rakefile +4 -0
- data/bin/gobstones +12 -0
- data/gobstones.gemspec +24 -0
- data/lib/gobstones/cli/board_template +39 -0
- data/lib/gobstones/cli/printer.rb +106 -0
- data/lib/gobstones/cli/runner.rb +52 -0
- data/lib/gobstones/extensions/all.rb +2 -0
- data/lib/gobstones/extensions/boolean.rb +17 -0
- data/lib/gobstones/extensions/fixnum.rb +9 -0
- data/lib/gobstones/lang/all.rb +5 -0
- data/lib/gobstones/lang/commands/all.rb +13 -0
- data/lib/gobstones/lang/commands/assignments.rb +29 -0
- data/lib/gobstones/lang/commands/boom_cmd.rb +28 -0
- data/lib/gobstones/lang/commands/command_block.rb +37 -0
- data/lib/gobstones/lang/commands/conditional_cmd.rb +27 -0
- data/lib/gobstones/lang/commands/if_cmd.rb +38 -0
- data/lib/gobstones/lang/commands/ir_al_origen_cmd.rb +19 -0
- data/lib/gobstones/lang/commands/mover_cmd.rb +25 -0
- data/lib/gobstones/lang/commands/poner_cmd.rb +31 -0
- data/lib/gobstones/lang/commands/procedure_call.rb +23 -0
- data/lib/gobstones/lang/commands/repeat_with_cmd.rb +73 -0
- data/lib/gobstones/lang/commands/sacar_cmd.rb +31 -0
- data/lib/gobstones/lang/commands/skip_cmd.rb +19 -0
- data/lib/gobstones/lang/commands/vaciar_tablero_cmd.rb +19 -0
- data/lib/gobstones/lang/commands/while_cmd.rb +25 -0
- data/lib/gobstones/lang/definitions/all.rb +4 -0
- data/lib/gobstones/lang/definitions/definition.rb +32 -0
- data/lib/gobstones/lang/definitions/definition_call.rb +24 -0
- data/lib/gobstones/lang/definitions/function.rb +14 -0
- data/lib/gobstones/lang/definitions/main.rb +26 -0
- data/lib/gobstones/lang/definitions/no_return_statement.rb +15 -0
- data/lib/gobstones/lang/definitions/procedure.rb +44 -0
- data/lib/gobstones/lang/definitions/return_from_function.rb +22 -0
- data/lib/gobstones/lang/definitions/return_from_main.rb +22 -0
- data/lib/gobstones/lang/definitions/var_tuple.rb +26 -0
- data/lib/gobstones/lang/expressions/all.rb +8 -0
- data/lib/gobstones/lang/expressions/arithmetic_expressions.rb +52 -0
- data/lib/gobstones/lang/expressions/boolean_expressions.rb +29 -0
- data/lib/gobstones/lang/expressions/comparison_expressions.rb +45 -0
- data/lib/gobstones/lang/expressions/function_call.rb +15 -0
- data/lib/gobstones/lang/expressions/one_arg_expression.rb +21 -0
- data/lib/gobstones/lang/expressions/parentheses_expression.rb +13 -0
- data/lib/gobstones/lang/expressions/primitive_functions.rb +68 -0
- data/lib/gobstones/lang/expressions/two_arg_expression.rb +34 -0
- data/lib/gobstones/lang/expressions/type_bound_functions.rb +66 -0
- data/lib/gobstones/lang/expressions/var_name.rb +31 -0
- data/lib/gobstones/lang/literals/all.rb +4 -0
- data/lib/gobstones/lang/literals/booleans.rb +109 -0
- data/lib/gobstones/lang/literals/colors.rb +94 -0
- data/lib/gobstones/lang/literals/directions.rb +137 -0
- data/lib/gobstones/lang/literals/literal.rb +63 -0
- data/lib/gobstones/lang/literals/number.rb +49 -0
- data/lib/gobstones/lang/program.rb +32 -0
- data/lib/gobstones/modules/equal_by_class.rb +13 -0
- data/lib/gobstones/parser/ast/ast.rb +210 -0
- data/lib/gobstones/parser/grammar/gobstones.treetop +316 -0
- data/lib/gobstones/parser/parse_error.rb +17 -0
- data/lib/gobstones/parser/treetop_parser.rb +73 -0
- data/lib/gobstones/runner/all.rb +6 -0
- data/lib/gobstones/runner/board.rb +57 -0
- data/lib/gobstones/runner/cell.rb +60 -0
- data/lib/gobstones/runner/errors/all.rb +8 -0
- data/lib/gobstones/runner/errors/boom_error.rb +11 -0
- data/lib/gobstones/runner/errors/definition_not_found_error.rb +19 -0
- data/lib/gobstones/runner/errors/empty_cell_error.rb +11 -0
- data/lib/gobstones/runner/errors/gobstones_runtime_error.rb +11 -0
- data/lib/gobstones/runner/errors/gobstones_type_error.rb +11 -0
- data/lib/gobstones/runner/errors/out_of_board_error.rb +11 -0
- data/lib/gobstones/runner/errors/undefined_variable_error.rb +11 -0
- data/lib/gobstones/runner/errors/wrong_arguments_error.rb +11 -0
- data/lib/gobstones/runner/execution_context.rb +89 -0
- data/lib/gobstones/runner/head.rb +101 -0
- data/lib/gobstones/type_check_result.rb +16 -0
- data/spec/lang/commands/assignments_spec.rb +13 -0
- data/spec/lang/commands/boom_cmd_spec.rb +8 -0
- data/spec/lang/commands/cmd_block_spec.rb +21 -0
- data/spec/lang/commands/if_cmd_spec.rb +49 -0
- data/spec/lang/commands/ir_al_origen_cmd_spec.rb +16 -0
- data/spec/lang/commands/mover_cmd_spec.rb +38 -0
- data/spec/lang/commands/poner_cmd_spec.rb +29 -0
- data/spec/lang/commands/procedure_call_spec.rb +44 -0
- data/spec/lang/commands/procedure_spec.rb +67 -0
- data/spec/lang/commands/repeat_with_cmd_spec.rb +41 -0
- data/spec/lang/commands/sacar_cmd_spec.rb +34 -0
- data/spec/lang/commands/skip_cmd_spec.rb +12 -0
- data/spec/lang/commands/vaciar_tablero_cmd_spec.rb +13 -0
- data/spec/lang/commands/while_cmd_spec.rb +37 -0
- data/spec/lang/expressions/arithmetic_expressions_spec.rb +108 -0
- data/spec/lang/expressions/boolean_expressions_spec.rb +56 -0
- data/spec/lang/expressions/comparison_expressions_spec.rb +285 -0
- data/spec/lang/expressions/primitive_functions_spec.rb +126 -0
- data/spec/lang/expressions/type_bound_functions_spec.rb +39 -0
- data/spec/lang/expressions/var_name_spec.rb +16 -0
- data/spec/lang/literals/booleans_spec.rb +13 -0
- data/spec/lang/literals/colors_spec.rb +13 -0
- data/spec/lang/literals/directions_spec.rb +45 -0
- data/spec/lang/literals/numbers_spec.rb +8 -0
- data/spec/matchers/parse_matcher.rb +84 -0
- data/spec/parser/arithmetic_expressions_spec.rb +129 -0
- data/spec/parser/assignments_spec.rb +39 -0
- data/spec/parser/boolean_expressions_spec.rb +111 -0
- data/spec/parser/command_block_spec.rb +50 -0
- data/spec/parser/data_types_spec.rb +67 -0
- data/spec/parser/function_calls_spec.rb +37 -0
- data/spec/parser/function_definitions_spec.rb +50 -0
- data/spec/parser/gobstones_program_spec.rb +55 -0
- data/spec/parser/if_command_spec.rb +46 -0
- data/spec/parser/main_definition_spec.rb +42 -0
- data/spec/parser/nested_expressions_spec.rb +39 -0
- data/spec/parser/primitive_expressions_spec.rb +105 -0
- data/spec/parser/procedure_calls_spec.rb +36 -0
- data/spec/parser/procedure_definitions_spec.rb +39 -0
- data/spec/parser/repeat_with_command_spec.rb +23 -0
- data/spec/parser/simple_commands_spec.rb +62 -0
- data/spec/parser/treetop_parser_spec.rb +109 -0
- data/spec/parser/var_tuple_spec.rb +30 -0
- data/spec/parser/while_command_spec.rb +30 -0
- data/spec/runner/board_spec.rb +85 -0
- data/spec/runner/cell_spec.rb +72 -0
- data/spec/runner/execution_context_spec.rb +64 -0
- data/spec/runner/head_spec.rb +139 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/type_checker_spec.rb +37 -0
- metadata +242 -0
@@ -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,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,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,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,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
|