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,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
@@ -0,0 +1,4 @@
1
+ require 'rspec/core/rake_task'
2
+ RSpec::Core::RakeTask.new('spec')
3
+
4
+ task :default => :spec
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.dirname(__FILE__) + '/lib'
4
+
5
+ require 'gobstones/cli/runner'
6
+
7
+ gbs_file = ARGV[0]
8
+ if gbs_file
9
+ Gobstones::CLI::Runner.run(gbs_file)
10
+ else
11
+ puts 'No Gobstones program specified'
12
+ end
@@ -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,2 @@
1
+ require 'gobstones/extensions/fixnum'
2
+ require 'gobstones/extensions/boolean'
@@ -0,0 +1,17 @@
1
+ require 'gobstones/lang/literals/booleans'
2
+
3
+ class TrueClass
4
+
5
+ def to_gbs_bool
6
+ Gobstones::Lang::True.new
7
+ end
8
+
9
+ end
10
+
11
+ class FalseClass
12
+
13
+ def to_gbs_bool
14
+ Gobstones::Lang::False.new
15
+ end
16
+
17
+ end
@@ -0,0 +1,9 @@
1
+ require 'gobstones/lang/literals/number'
2
+
3
+ class Fixnum
4
+
5
+ def to_gbs_num
6
+ Gobstones::Lang::Number.new self
7
+ end
8
+
9
+ end
@@ -0,0 +1,5 @@
1
+ require 'gobstones/lang/literals/all'
2
+ require 'gobstones/lang/expressions/all'
3
+ require 'gobstones/lang/commands/all'
4
+ require 'gobstones/lang/definitions/all'
5
+ require 'gobstones/lang/program'
@@ -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