gobstones 0.0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/README.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
## gobstones-rb
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/ngarbezza/gobstones-rb.png?branch=master)](https://travis-ci.org/ngarbezza/gobstones-rb)
|
4
|
+
[![Dependency Status](https://gemnasium.com/ngarbezza/gobstones-rb.png)](https://gemnasium.com/ngarbezza/gobstones-rb)
|
5
|
+
[![Coverage Status](https://coveralls.io/repos/ngarbezza/gobstones-rb/badge.png?branch=master)](https://coveralls.io/r/ngarbezza/gobstones-rb?branch=master)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/ngarbezza/gobstones-rb.png)](https://codeclimate.com/github/ngarbezza/gobstones-rb)
|
7
|
+
|
8
|
+
Ruby implementation of the Gobstones programming language.
|
9
|
+
[Haskell](http://sourceforge.net/projects/gobstones/) and
|
10
|
+
[Python](https://bitbucket.org/foones/gobstones) implementations.
|
11
|
+
|
12
|
+
Gobstones is a programming language designed for teaching the fundamental
|
13
|
+
abstractions for algorithmic problem solving.
|
14
|
+
|
15
|
+
## Status
|
16
|
+
|
17
|
+
In progress
|
data/Rakefile
ADDED
data/bin/gobstones
ADDED
data/gobstones.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
lib = File.expand_path '../lib/', __FILE__
|
2
|
+
$:.unshift lib unless $:.include?(lib)
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = 'gobstones'
|
6
|
+
spec.version = '0.0.1.1'
|
7
|
+
spec.licenses = ['GPLv3']
|
8
|
+
spec.authors = ['Nahuel Garbezza']
|
9
|
+
spec.email = ['n.garbezza@gmail.com']
|
10
|
+
spec.homepage = 'http://nahuelgarbezza.com.ar/gobstones-rb/'
|
11
|
+
spec.summary = %q{Ruby implementation of the Gobstones programming language}
|
12
|
+
spec.description = %q{Ruby implementation of the Gobstones programming language}
|
13
|
+
|
14
|
+
spec.required_ruby_version = '>= 1.9.3'
|
15
|
+
spec.required_rubygems_version = '>= 1.3.6'
|
16
|
+
|
17
|
+
spec.add_development_dependency 'rspec', '~> 2'
|
18
|
+
|
19
|
+
spec.files = `git ls-files`.split $/
|
20
|
+
spec.test_files = spec.files.grep %r{^spec/}
|
21
|
+
|
22
|
+
spec.executables = %w(gobstones)
|
23
|
+
spec.require_paths = %w(lib)
|
24
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
0 1 2 3 4 5 6 7 8
|
2
|
+
+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
3
|
+
| | | | | | | | | |
|
4
|
+
8 | | | | | | | | | | 8
|
5
|
+
| | | | | | | | | |
|
6
|
+
+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
7
|
+
| | | | | | | | | |
|
8
|
+
7 | | | | | | | | | | 7
|
9
|
+
| | | | | | | | | |
|
10
|
+
+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
11
|
+
| | | | | | | | | |
|
12
|
+
6 | | | | | | | | | | 6
|
13
|
+
| | | | | | | | | |
|
14
|
+
+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
15
|
+
| | | | | | | | | |
|
16
|
+
5 | | | | | | | | | | 5
|
17
|
+
| | | | | | | | | |
|
18
|
+
+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
19
|
+
| | | | | | | | | |
|
20
|
+
4 | | | | | | | | | | 4
|
21
|
+
| | | | | | | | | |
|
22
|
+
+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
23
|
+
| | | | | | | | | |
|
24
|
+
3 | | | | | | | | | | 3
|
25
|
+
| | | | | | | | | |
|
26
|
+
+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
27
|
+
| | | | | | | | | |
|
28
|
+
2 | | | | | | | | | | 2
|
29
|
+
| | | | | | | | | |
|
30
|
+
+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
31
|
+
| | | | | | | | | |
|
32
|
+
1 | | | | | | | | | | 1
|
33
|
+
| | | | | | | | | |
|
34
|
+
+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
35
|
+
| | | | | | | | | |
|
36
|
+
0 | | | | | | | | | | 0
|
37
|
+
| | | | | | | | | |
|
38
|
+
+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
39
|
+
0 1 2 3 4 5 6 7 8
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'gobstones/lang/literals/colors'
|
2
|
+
|
3
|
+
module Gobstones
|
4
|
+
|
5
|
+
module CLI
|
6
|
+
|
7
|
+
class Printer
|
8
|
+
|
9
|
+
TEMPLATE = File.read(File.dirname(__FILE__) + '/board_template')
|
10
|
+
|
11
|
+
def initialize(context)
|
12
|
+
@context = context
|
13
|
+
@board = TEMPLATE
|
14
|
+
end
|
15
|
+
|
16
|
+
def print
|
17
|
+
highlight_current_cell
|
18
|
+
put_ball_values
|
19
|
+
puts @board
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def highlight_current_cell
|
25
|
+
char = 'X'
|
26
|
+
x = @context.head.x_pos
|
27
|
+
y = @context.head.y_pos
|
28
|
+
highlight_row x, y, char
|
29
|
+
highlight_row x, y - 1, char
|
30
|
+
highlight_column x, y, char
|
31
|
+
highlight_column x + 1, y, char
|
32
|
+
end
|
33
|
+
|
34
|
+
def put_ball_values
|
35
|
+
total_rows.times do |x|
|
36
|
+
total_columns.times do |y|
|
37
|
+
put_ball_value @context.board.number_of_balls(x, y, Gobstones::Lang::Negro.new), 'N', x, y, 2, 1
|
38
|
+
put_ball_value @context.board.number_of_balls(x, y, Gobstones::Lang::Azul.new) , 'A', x, y, 6, 1
|
39
|
+
put_ball_value @context.board.number_of_balls(x, y, Gobstones::Lang::Verde.new), 'V', x, y, 2, 3
|
40
|
+
put_ball_value @context.board.number_of_balls(x, y, Gobstones::Lang::Rojo.new) , 'R', x, y, 6, 3
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def put_ball_value(number, char, x, y, x_offset, y_offset)
|
46
|
+
unless number.zero?
|
47
|
+
corner = cell_top_left_corner x, y
|
48
|
+
pos = corner + (y_offset * line_length) + x_offset
|
49
|
+
if number < 10
|
50
|
+
@board[pos] = ' '
|
51
|
+
@board[pos+1] = number.to_s
|
52
|
+
else
|
53
|
+
@board[pos] = number.to_s[0]
|
54
|
+
@board[pos+1] = number.to_s[1]
|
55
|
+
end
|
56
|
+
@board[pos+2] = char
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def highlight_row(x, y, char)
|
61
|
+
corner = cell_top_left_corner x, y
|
62
|
+
(cell_width - 1).times do |index|
|
63
|
+
@board[corner + index + 1] = char
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def highlight_column(x, y, char)
|
68
|
+
corner = cell_top_left_corner x, y
|
69
|
+
(cell_height - 1).times do |index|
|
70
|
+
@board[corner + ((index + 1) * line_length)] = char
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def line_length
|
75
|
+
98
|
76
|
+
end
|
77
|
+
|
78
|
+
def cell_height
|
79
|
+
4
|
80
|
+
end
|
81
|
+
|
82
|
+
def cell_width
|
83
|
+
10
|
84
|
+
end
|
85
|
+
|
86
|
+
def cell_top_left_corner(x, y)
|
87
|
+
head_lines = 1
|
88
|
+
head_chars = 4
|
89
|
+
y_to_go = (total_columns - 1 - y) * cell_height + head_lines
|
90
|
+
x_to_go = x * cell_width + head_chars
|
91
|
+
(y_to_go * line_length) + x_to_go
|
92
|
+
end
|
93
|
+
|
94
|
+
def total_columns
|
95
|
+
9
|
96
|
+
end
|
97
|
+
|
98
|
+
def total_rows
|
99
|
+
9
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'gobstones/parser/treetop_parser'
|
2
|
+
require 'gobstones/parser/parse_error'
|
3
|
+
require 'gobstones/cli/printer'
|
4
|
+
|
5
|
+
include Gobstones::Parser
|
6
|
+
|
7
|
+
module Gobstones
|
8
|
+
|
9
|
+
module CLI
|
10
|
+
|
11
|
+
class Runner
|
12
|
+
|
13
|
+
def self.run(file_name)
|
14
|
+
new(File.read(file_name)).run
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(code)
|
18
|
+
@code = code
|
19
|
+
@parser = Gobstones::Parser::TreetopParser.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def run
|
23
|
+
print_program_result parse_program.evaluate
|
24
|
+
rescue Gobstones::Parser::ParseError => parse_error
|
25
|
+
handle_parse_error parse_error
|
26
|
+
rescue Exception => e
|
27
|
+
# TODO handle more gobstones exceptions
|
28
|
+
raise e
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def print_program_result(context)
|
34
|
+
Printer.new(context).print
|
35
|
+
end
|
36
|
+
|
37
|
+
def parse_program
|
38
|
+
@parser.parse(@code)
|
39
|
+
end
|
40
|
+
|
41
|
+
def handle_parse_error(parse_error)
|
42
|
+
parse_error.parser.failure_reason =~ /^(Expected .+) after/m
|
43
|
+
puts "#{$1.gsub("\n", '$NEWLINE')}:"
|
44
|
+
puts parse_error.code.lines.to_a[parse_error.parser.failure_line - 1]
|
45
|
+
puts "#{'~' * (parse_error.parser.failure_column - 1)}^"
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'gobstones/lang/commands/assignments'
|
2
|
+
require 'gobstones/lang/commands/boom_cmd'
|
3
|
+
require 'gobstones/lang/commands/command_block'
|
4
|
+
require 'gobstones/lang/commands/if_cmd'
|
5
|
+
require 'gobstones/lang/commands/ir_al_origen_cmd'
|
6
|
+
require 'gobstones/lang/commands/mover_cmd'
|
7
|
+
require 'gobstones/lang/commands/poner_cmd'
|
8
|
+
require 'gobstones/lang/commands/procedure_call'
|
9
|
+
require 'gobstones/lang/commands/repeat_with_cmd'
|
10
|
+
require 'gobstones/lang/commands/sacar_cmd'
|
11
|
+
require 'gobstones/lang/commands/skip_cmd'
|
12
|
+
require 'gobstones/lang/commands/vaciar_tablero_cmd'
|
13
|
+
require 'gobstones/lang/commands/while_cmd'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Gobstones
|
2
|
+
|
3
|
+
module Lang
|
4
|
+
|
5
|
+
class SingleAssignment
|
6
|
+
|
7
|
+
attr_reader :var_name, :expression
|
8
|
+
|
9
|
+
def initialize(var_name, expression)
|
10
|
+
@var_name, @expression = var_name, expression
|
11
|
+
end
|
12
|
+
|
13
|
+
def ==(other)
|
14
|
+
self.class == other.class &&
|
15
|
+
self.var_name == other.var_name &&
|
16
|
+
self.expression == other.expression
|
17
|
+
end
|
18
|
+
|
19
|
+
def evaluate(context)
|
20
|
+
context.set var_name, expression.evaluate(context)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
# TODO implement multiple assignment
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'gobstones/runner/errors/boom_error'
|
2
|
+
|
3
|
+
module Gobstones
|
4
|
+
|
5
|
+
module Lang
|
6
|
+
|
7
|
+
class Boom
|
8
|
+
|
9
|
+
attr_reader :message
|
10
|
+
|
11
|
+
def initialize(message)
|
12
|
+
@message = message
|
13
|
+
end
|
14
|
+
|
15
|
+
def ==(other)
|
16
|
+
self.class == other.class &&
|
17
|
+
self.message == other.message
|
18
|
+
end
|
19
|
+
|
20
|
+
def evaluate(context=nil)
|
21
|
+
raise Gobstones::Runner::BoomError, message
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'gobstones/modules/equal_by_class'
|
2
|
+
|
3
|
+
module Gobstones
|
4
|
+
|
5
|
+
module Lang
|
6
|
+
|
7
|
+
class CmdBlock
|
8
|
+
|
9
|
+
include Gobstones::EqualByClass
|
10
|
+
|
11
|
+
attr_reader :commands
|
12
|
+
|
13
|
+
def self.empty
|
14
|
+
self.new []
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(commands)
|
18
|
+
@commands = commands
|
19
|
+
end
|
20
|
+
|
21
|
+
def ==(other)
|
22
|
+
super(other) && self.commands == other.commands
|
23
|
+
end
|
24
|
+
|
25
|
+
def empty?
|
26
|
+
commands.empty?
|
27
|
+
end
|
28
|
+
|
29
|
+
def evaluate(context)
|
30
|
+
commands.each { |command| command.evaluate context }
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Gobstones
|
2
|
+
|
3
|
+
module Lang
|
4
|
+
|
5
|
+
class ConditionalCmd
|
6
|
+
|
7
|
+
attr_reader :condition, :then_block
|
8
|
+
|
9
|
+
def initialize(condition, then_block)
|
10
|
+
@condition, @then_block = condition, then_block
|
11
|
+
end
|
12
|
+
|
13
|
+
def ==(other)
|
14
|
+
self.class == other.class &&
|
15
|
+
self.condition == other.condition &&
|
16
|
+
self.then_block == other.then_block
|
17
|
+
end
|
18
|
+
|
19
|
+
def evaluate_condition(context)
|
20
|
+
condition.evaluate context
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'gobstones/lang/commands/conditional_cmd'
|
2
|
+
|
3
|
+
module Gobstones
|
4
|
+
|
5
|
+
module Lang
|
6
|
+
|
7
|
+
class IfCmd < ConditionalCmd
|
8
|
+
|
9
|
+
def evaluate(context)
|
10
|
+
evaluate_condition(context).if_true(then_block, context)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
class IfElseCmd < IfCmd
|
16
|
+
|
17
|
+
attr_reader :else_block
|
18
|
+
|
19
|
+
def initialize(condition, then_block, else_block)
|
20
|
+
super(condition, then_block)
|
21
|
+
@else_block = else_block
|
22
|
+
end
|
23
|
+
|
24
|
+
def ==(other)
|
25
|
+
super(other) && self.else_block == other.else_block
|
26
|
+
end
|
27
|
+
|
28
|
+
def evaluate(context)
|
29
|
+
cond = evaluate_condition context
|
30
|
+
cond.if_true then_block, context
|
31
|
+
cond.if_false else_block, context
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|