loxxy 0.2.01 → 0.2.06
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 +4 -4
- data/CHANGELOG.md +63 -0
- data/README.md +25 -11
- data/bin/loxxy +9 -5
- data/lib/loxxy/ast/all_lox_nodes.rb +0 -1
- data/lib/loxxy/ast/ast_builder.rb +27 -4
- data/lib/loxxy/ast/ast_visitee.rb +53 -0
- data/lib/loxxy/ast/ast_visitor.rb +2 -10
- data/lib/loxxy/ast/lox_assign_expr.rb +1 -5
- data/lib/loxxy/ast/lox_binary_expr.rb +1 -6
- data/lib/loxxy/ast/lox_block_stmt.rb +1 -5
- data/lib/loxxy/ast/lox_call_expr.rb +1 -5
- data/lib/loxxy/ast/lox_class_stmt.rb +1 -5
- data/lib/loxxy/ast/lox_fun_stmt.rb +1 -5
- data/lib/loxxy/ast/lox_get_expr.rb +1 -6
- data/lib/loxxy/ast/lox_grouping_expr.rb +1 -5
- data/lib/loxxy/ast/lox_if_stmt.rb +2 -6
- data/lib/loxxy/ast/lox_literal_expr.rb +1 -5
- data/lib/loxxy/ast/lox_logical_expr.rb +1 -6
- data/lib/loxxy/ast/lox_node.rb +9 -1
- data/lib/loxxy/ast/lox_print_stmt.rb +1 -5
- data/lib/loxxy/ast/lox_return_stmt.rb +1 -5
- data/lib/loxxy/ast/lox_seq_decl.rb +1 -5
- data/lib/loxxy/ast/lox_set_expr.rb +1 -5
- data/lib/loxxy/ast/lox_super_expr.rb +2 -6
- data/lib/loxxy/ast/lox_this_expr.rb +1 -5
- data/lib/loxxy/ast/lox_unary_expr.rb +1 -6
- data/lib/loxxy/ast/lox_var_stmt.rb +1 -5
- data/lib/loxxy/ast/lox_variable_expr.rb +1 -5
- data/lib/loxxy/ast/lox_while_stmt.rb +2 -6
- data/lib/loxxy/back_end/engine.rb +28 -26
- data/lib/loxxy/back_end/lox_instance.rb +1 -1
- data/lib/loxxy/back_end/resolver.rb +16 -22
- data/lib/loxxy/datatype/number.rb +19 -4
- data/lib/loxxy/error.rb +3 -0
- data/lib/loxxy/front_end/parser.rb +1 -1
- data/lib/loxxy/front_end/scanner.rb +43 -17
- data/lib/loxxy/version.rb +1 -1
- data/spec/front_end/scanner_spec.rb +69 -7
- data/spec/interpreter_spec.rb +36 -0
- metadata +3 -3
- data/lib/loxxy/ast/lox_for_stmt.rb +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cbb2f24e245891baabf20458e5b663784ba7f82ff902ab7892007d9b53d99347
|
4
|
+
data.tar.gz: eab4ede6f48470449f731e3074b2ac2fe72b53449c9471231ea64d0007a873ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8037d3c239e39d47554c4e7f7698e5908cdaa5e460c8972fe8dc5b58ee5fd59647c413db95250ff739c08f9ca891c8f576eb8d78aa63cf40039e8d1b3328e9a2
|
7
|
+
data.tar.gz: 795face50a76140ba2f6be2e6e6c44e671992baaea2ecade980acf1baed173dc59cbe7cd2ce419b509e8593068ffc3e637e0678dab2db72a96250d4e53ef0338
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,66 @@
|
|
1
|
+
## [0.2.06] - 2021-05-04
|
2
|
+
- Nearly passing the 'official' test suite, fixing non-compliant behavior, specialized exceptions for errors
|
3
|
+
|
4
|
+
### New
|
5
|
+
- Module `LoxFileTester` module that hosts methods that simplify the tests of `Lox` source file.
|
6
|
+
|
7
|
+
### Changed
|
8
|
+
- Folder `test_suite` vastly reorganized. Sub-folder `baseline` contains spec files testing the `Lox` files from official implementation
|
9
|
+
- Class `BackEnd::Engine` replaced most `StandardError` by `Loxxy::RuntimeError` exception.
|
10
|
+
- Class `BackEnd::Resolver` replaced most `StandardError` by `Loxxy::RuntimeError` exception.
|
11
|
+
- Method `Datatype::Number#/` now handles correctly expression like `0/0` (integer divide)
|
12
|
+
|
13
|
+
### Fixed
|
14
|
+
- `0/0` expression results in a ZeroDivisionError exception, in Lox this result to a NaN (Not a Number). Now, `Loxxy` is aligned to standard `Lox`
|
15
|
+
- `FrontEnd::Scanner` now always treats expression like `-123` as the unary or binary minus operator applied to a positive number.
|
16
|
+
|
17
|
+
## [0.2.05] - 2021-04-26
|
18
|
+
- `Loxxy` now transforms for loops into while loops (desugaring), fix in Scanner class
|
19
|
+
|
20
|
+
### Changed
|
21
|
+
- Method `Ast::ASTBuilder#reduce_for_stmt` converts 'for' loops into 'while' loops
|
22
|
+
- Method `Ast::ASTBuilder#reduce_for_control takes care of case for(expr1;;expr2) now test expression is set to true
|
23
|
+
|
24
|
+
### Fixed
|
25
|
+
- Method `FrontEnd::Scanner#next_token` keyword recognition was case insensitive
|
26
|
+
|
27
|
+
### Removed
|
28
|
+
- Method `Ast::Visitor#visitor_for_stmt`
|
29
|
+
- Method `BackEnd::Engine#after_for_stmt`
|
30
|
+
- Method `BackEnd::Resolver#before_for_stmt`
|
31
|
+
- Method `BackEnd::Resolver#after_for_stmt`
|
32
|
+
|
33
|
+
|
34
|
+
## [0.2.04] - 2021-04-25
|
35
|
+
- `Loxxy` passes the test suite for `for` statements
|
36
|
+
|
37
|
+
### Fixed
|
38
|
+
- Method `BackEnd::Engine#after_for_stmt` now a for(;;) executes the body once; a for without test will execute forever
|
39
|
+
- Method `BackEnd::Resolver#after_for_stmt now accepts nil test expression
|
40
|
+
|
41
|
+
## [0.2.03] - 2021-04-24
|
42
|
+
- Fixes for the set (field) expressions, `accept` methods for AST nodes are meta-programmed
|
43
|
+
|
44
|
+
### New
|
45
|
+
- Module `Ast::Visitee` provides the `define_accept` method that generate `accept` method with meta-programming
|
46
|
+
|
47
|
+
### Fixed
|
48
|
+
- Method `BackEnd::Engine#before_set_expr` methos method that ensure that the receiver is evaluated first, then the assigned value
|
49
|
+
- Method `BackEnd::Engine#after_set_expr` now pushes the value assigned to the field also onto the stack
|
50
|
+
- Class `BackEnd::Engine` a number of StnadardError exceptions are replaced by Loxxy::RuntimeError
|
51
|
+
|
52
|
+
|
53
|
+
## [0.2.02] - 2021-04-21
|
54
|
+
- Improvements in the scanner class (escape sequence for quotes and newlines), error messages closer to jlox.
|
55
|
+
|
56
|
+
### Changed
|
57
|
+
- File `loxxy` executable doesn't show a stack trace for scanner errors
|
58
|
+
- Class `ScannerError` is now a subclass of `Loxxy::Error`
|
59
|
+
- Class `Scanner` now returns a specific error message for unterminated strings
|
60
|
+
- Class `Scanner` error messages are closer to the ones from jlox
|
61
|
+
- Class `Scanner` supports now escape sequences \" for double quotes, \n for newlines
|
62
|
+
- File `README.md` Reshuffled some text
|
63
|
+
|
1
64
|
## [0.2.01] - 2021-04-18
|
2
65
|
- Minor improvements in CLI, starting re-documenting `README.md`.
|
3
66
|
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
[](https://ci.appveyor.com/project/famished-tiger/loxxy)
|
4
4
|
[](https://github.com/famished-tiger/loxxy/blob/main/LICENSE.txt)
|
5
5
|
|
6
|
-
|
6
|
+
## What is loxxy?
|
7
7
|
A Ruby implementation of the [Lox programming language](https://craftinginterpreters.com/the-lox-language.html ),
|
8
8
|
a simple language defined in Bob Nystrom's excellent online book [Crafting Interpreters](https://craftinginterpreters.com/ ).
|
9
9
|
|
@@ -16,15 +16,34 @@ Although __Lox__ is fairly simple, it is far from being a toy language:
|
|
16
16
|
- Functions and closures
|
17
17
|
- Object-orientation (classes, methods, inheritance).
|
18
18
|
|
19
|
+
### Loxxy gem features
|
20
|
+
- Complete tree-walking interpreter including lexer, parser and resolver
|
21
|
+
- 100% pure Ruby with clean design (not a port from some other language)
|
22
|
+
- Minimal runtime dependency (Rley gem). Won't drag a bunch of gems...
|
23
|
+
- Ruby API for integrating a Lox interpreter with your code.
|
24
|
+
- A command-line interpreter `loxxy`
|
25
|
+
- Open for your language extensions...
|
26
|
+
|
19
27
|
## How to start in 1, 2, 3...?
|
20
28
|
... in less than 3 minutes...
|
21
29
|
|
22
30
|
### 1. Installing
|
23
|
-
|
31
|
+
__Loxxy__'s installation is pretty standard:
|
24
32
|
|
25
33
|
|
26
34
|
$ gem install loxxy
|
27
35
|
|
36
|
+
Alternatively, you can install `loxxy` with Bundler.
|
37
|
+
Add this line to your application's Gemfile:
|
38
|
+
|
39
|
+
gem 'loxxy'
|
40
|
+
|
41
|
+
And then execute:
|
42
|
+
|
43
|
+
$ bundle
|
44
|
+
|
45
|
+
|
46
|
+
|
28
47
|
### 2. Your first `Lox` program
|
29
48
|
Create a text file and enter the following lines:
|
30
49
|
```javascript
|
@@ -42,10 +61,11 @@ Lo and behold! The output device displays the famous greeting:
|
|
42
61
|
Hello, world.
|
43
62
|
|
44
63
|
|
45
|
-
Congrats! You ran your first `Lox` program
|
64
|
+
Congrats! You ran your first `Lox` program thanks __Loxxy__ gem.
|
65
|
+
For a less superficial encounter with the language jump to the next section.
|
46
66
|
|
47
|
-
|
48
|
-
Let's admit it, the hello world example was unimpressive.
|
67
|
+
## So you want something beefier?...
|
68
|
+
Let's admit it, the hello world example was unimpressive.
|
49
69
|
To a get a taste of `Lox` object-oriented capabilities, let's try another `Hello world` variant:
|
50
70
|
|
51
71
|
```javascript
|
@@ -172,12 +192,6 @@ Indeed, an open-source language that misses some features is an invitation for t
|
|
172
192
|
There are already a number of programming languages derived from `Lox`...
|
173
193
|
|
174
194
|
## Why `Loxxy`? What's in it for me?...
|
175
|
-
Features:
|
176
|
-
- Complete tree-walking interpreter including lexer, parser and resolver
|
177
|
-
- 100% pure Ruby with clean design (not a port from some other language)
|
178
|
-
- Ruby API for integrating a Lox interpreter with your code.
|
179
|
-
- Minimal runtime dependency (Rley gem). Won't drag a bunch of gems...
|
180
|
-
|
181
195
|
|
182
196
|
### Purpose of this project:
|
183
197
|
- To deliver an open source example of a programming language fully implemented in Ruby
|
data/bin/loxxy
CHANGED
@@ -17,11 +17,15 @@ class LoxxyRunner
|
|
17
17
|
return if file_names.nil? || file_names.empty?
|
18
18
|
|
19
19
|
lox = Loxxy::Interpreter.new
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
begin
|
21
|
+
file_names.each do |lox_file|
|
22
|
+
fname = validate_filename(lox_file)
|
23
|
+
next unless file_exist?(fname)
|
24
|
+
|
25
|
+
File.open(fname, 'r') { |f| lox.evaluate(f.read) }
|
26
|
+
end
|
27
|
+
rescue Loxxy::ScanError => e
|
28
|
+
$stderr.puts e.message
|
25
29
|
end
|
26
30
|
end
|
27
31
|
|
@@ -19,7 +19,6 @@ require_relative 'lox_while_stmt'
|
|
19
19
|
require_relative 'lox_return_stmt'
|
20
20
|
require_relative 'lox_print_stmt'
|
21
21
|
require_relative 'lox_if_stmt'
|
22
|
-
require_relative 'lox_for_stmt'
|
23
22
|
require_relative 'lox_var_stmt'
|
24
23
|
require_relative 'lox_class_stmt'
|
25
24
|
require_relative 'lox_seq_decl'
|
@@ -225,16 +225,39 @@ module Loxxy
|
|
225
225
|
end
|
226
226
|
|
227
227
|
# rule('forStmt' => 'FOR LEFT_PAREN forControl RIGHT_PAREN statement')
|
228
|
-
def reduce_for_stmt(_production, _range,
|
229
|
-
|
230
|
-
|
228
|
+
def reduce_for_stmt(_production, _range, tokens, theChildren)
|
229
|
+
# Following 'Crafting Interpreters', we replace the for statement by a while loop
|
230
|
+
return theChildren[4] if theChildren[2].compact.empty? # for(;;) => execute body once
|
231
|
+
|
232
|
+
(init, test, update) = theChildren[2]
|
233
|
+
if update
|
234
|
+
new_body = LoxSeqDecl.new(tokens[0].position, [theChildren[4], update])
|
235
|
+
stmt = Ast::LoxBlockStmt.new(tokens[1].position, new_body)
|
236
|
+
else
|
237
|
+
stmt = theChildren[4]
|
238
|
+
end
|
239
|
+
while_stmt = Ast::LoxWhileStmt.new(tokens[0].position, test, stmt)
|
240
|
+
|
241
|
+
if init
|
242
|
+
block_body = LoxSeqDecl.new(tokens[0].position, [init, while_stmt])
|
243
|
+
for_stmt = Ast::LoxBlockStmt.new(tokens[1].position, block_body)
|
244
|
+
else
|
245
|
+
for_stmt = while_stmt
|
246
|
+
end
|
247
|
+
|
231
248
|
for_stmt
|
232
249
|
end
|
233
250
|
|
234
251
|
# rule('forControl' => 'forInitialization forTest forUpdate')
|
235
252
|
def reduce_for_control(_production, _range, tokens, theChildren)
|
236
253
|
(init, test, update) = theChildren
|
237
|
-
|
254
|
+
if test.nil? && update
|
255
|
+
# when test expr is nil but update expr is not, then force test to be true
|
256
|
+
test = LoxLiteralExpr.new(tokens[0].position, Datatype::True.instance)
|
257
|
+
[init, test, update]
|
258
|
+
else
|
259
|
+
theChildren
|
260
|
+
end
|
238
261
|
end
|
239
262
|
|
240
263
|
# rule('forInitialization' => 'SEMICOLON')
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Loxxy
|
4
|
+
module Ast
|
5
|
+
# Mix-in module that relies on meta-programming to add a method
|
6
|
+
# called `accept` to the host class (an AST node).
|
7
|
+
# That method fulfills the expected behavior of the `visitee` in
|
8
|
+
# the Visitor design pattern.
|
9
|
+
module ASTVisitee
|
10
|
+
# Convert the input string into a snake case string.
|
11
|
+
# Example: ClassExpr => class_expr
|
12
|
+
# @param aName [String] input name to convert
|
13
|
+
# @return [String] the name converted into snake case
|
14
|
+
def snake_case(aName)
|
15
|
+
converted = +''
|
16
|
+
down = false
|
17
|
+
aName.each_char do |ch|
|
18
|
+
lower = ch.downcase
|
19
|
+
if lower == ch
|
20
|
+
converted << ch
|
21
|
+
down = true
|
22
|
+
else
|
23
|
+
converted << '_' if down && converted[-1] != '_'
|
24
|
+
converted << lower
|
25
|
+
down = false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
converted
|
30
|
+
end
|
31
|
+
|
32
|
+
# This method adds a method named `accept` that takes a visitor
|
33
|
+
# The visitor is expected to implement a method named:
|
34
|
+
# visit + class name (without the Lox prefix) in snake case
|
35
|
+
# Example: class name = LoxClassStmt => visit method = visit_class_stmt
|
36
|
+
def define_accept
|
37
|
+
return if instance_methods(false).include?(:accept)
|
38
|
+
|
39
|
+
base_name = name.split('::').last
|
40
|
+
name_suffix = snake_case(base_name).sub(/^lox/, '')
|
41
|
+
accept_body = <<-MTH_END
|
42
|
+
# Part of the 'visitee' role in Visitor design pattern.
|
43
|
+
# @param visitor [Ast::ASTVisitor] the visitor
|
44
|
+
def accept(aVisitor)
|
45
|
+
aVisitor.visit#{name_suffix}(self)
|
46
|
+
end
|
47
|
+
MTH_END
|
48
|
+
|
49
|
+
class_eval(accept_body)
|
50
|
+
end
|
51
|
+
end # module
|
52
|
+
end # module
|
53
|
+
end # module
|
@@ -75,14 +75,6 @@ module Loxxy
|
|
75
75
|
broadcast(:after_class_stmt, aClassStmt, self)
|
76
76
|
end
|
77
77
|
|
78
|
-
# Visit event. The visitor is about to visit a for statement.
|
79
|
-
# @param aForStmt [AST::LOXForStmt] the for statement node to visit
|
80
|
-
def visit_for_stmt(aForStmt)
|
81
|
-
broadcast(:before_for_stmt, aForStmt)
|
82
|
-
traverse_subnodes(aForStmt) # The condition is visited/evaluated here...
|
83
|
-
broadcast(:after_for_stmt, aForStmt, self)
|
84
|
-
end
|
85
|
-
|
86
78
|
# Visit event. The visitor is about to visit a if statement.
|
87
79
|
# @param anIfStmt [AST::LOXIfStmt] the if statement node to visit
|
88
80
|
def visit_if_stmt(anIfStmt)
|
@@ -111,7 +103,7 @@ module Loxxy
|
|
111
103
|
# @param aWhileStmt [AST::LOXWhileStmt] the while statement node to visit
|
112
104
|
def visit_while_stmt(aWhileStmt)
|
113
105
|
broadcast(:before_while_stmt, aWhileStmt)
|
114
|
-
traverse_subnodes(aWhileStmt) # The condition is visited/evaluated here...
|
106
|
+
traverse_subnodes(aWhileStmt) if aWhileStmt.condition # The condition is visited/evaluated here...
|
115
107
|
broadcast(:after_while_stmt, aWhileStmt, self)
|
116
108
|
end
|
117
109
|
|
@@ -133,7 +125,7 @@ module Loxxy
|
|
133
125
|
|
134
126
|
# @param aSetExpr [AST::LOXGetExpr] the get expression node to visit
|
135
127
|
def visit_set_expr(aSetExpr)
|
136
|
-
broadcast(:before_set_expr, aSetExpr)
|
128
|
+
broadcast(:before_set_expr, aSetExpr, self)
|
137
129
|
traverse_subnodes(aSetExpr)
|
138
130
|
broadcast(:after_set_expr, aSetExpr, self)
|
139
131
|
end
|
@@ -17,11 +17,7 @@ module Loxxy
|
|
17
17
|
@name = aName
|
18
18
|
end
|
19
19
|
|
20
|
-
#
|
21
|
-
# @param visitor [Ast::ASTVisitor] the visitor
|
22
|
-
def accept(visitor)
|
23
|
-
visitor.visit_assign_expr(self)
|
24
|
-
end
|
20
|
+
define_accept # Add `accept` method as found in Visitor design pattern
|
25
21
|
end # class
|
26
22
|
end # module
|
27
23
|
end # module
|
@@ -16,12 +16,7 @@ module Loxxy
|
|
16
16
|
@operator = anOperator
|
17
17
|
end
|
18
18
|
|
19
|
-
#
|
20
|
-
# @param visitor [Ast::ASTVisitor] the visitor
|
21
|
-
def accept(visitor)
|
22
|
-
visitor.visit_binary_expr(self)
|
23
|
-
end
|
24
|
-
|
19
|
+
define_accept # Add `accept` method as found in Visitor design pattern
|
25
20
|
alias operands subnodes
|
26
21
|
end # class
|
27
22
|
end # module
|
@@ -15,11 +15,7 @@ module Loxxy
|
|
15
15
|
subnodes.size == 1 && subnodes[0].nil?
|
16
16
|
end
|
17
17
|
|
18
|
-
#
|
19
|
-
# @param visitor [Ast::ASTVisitor] the visitor
|
20
|
-
def accept(visitor)
|
21
|
-
visitor.visit_block_stmt(self)
|
22
|
-
end
|
18
|
+
define_accept # Add `accept` method as found in Visitor design pattern
|
23
19
|
end # class
|
24
20
|
end # module
|
25
21
|
end # module
|
@@ -15,11 +15,7 @@ module Loxxy
|
|
15
15
|
@arguments = argList
|
16
16
|
end
|
17
17
|
|
18
|
-
#
|
19
|
-
# @param visitor [Ast::ASTVisitor] the visitor
|
20
|
-
def accept(visitor)
|
21
|
-
visitor.visit_call_expr(self)
|
22
|
-
end
|
18
|
+
define_accept # Add `accept` method as found in Visitor design pattern
|
23
19
|
end # class
|
24
20
|
end # module
|
25
21
|
end # module
|
@@ -24,11 +24,7 @@ module Loxxy
|
|
24
24
|
@body = theMethods
|
25
25
|
end
|
26
26
|
|
27
|
-
#
|
28
|
-
# @param visitor [Ast::ASTVisitor] the visitor
|
29
|
-
def accept(visitor)
|
30
|
-
visitor.visit_class_stmt(self)
|
31
|
-
end
|
27
|
+
define_accept # Add `accept` method as found in Visitor design pattern
|
32
28
|
end # class
|
33
29
|
end # module
|
34
30
|
end # module
|
@@ -23,11 +23,7 @@ module Loxxy
|
|
23
23
|
@is_method = false
|
24
24
|
end
|
25
25
|
|
26
|
-
#
|
27
|
-
# @param visitor [Ast::ASTVisitor] the visitor
|
28
|
-
def accept(visitor)
|
29
|
-
visitor.visit_fun_stmt(self)
|
30
|
-
end
|
26
|
+
define_accept # Add `accept` method as found in Visitor design pattern
|
31
27
|
end # class
|
32
28
|
# rubocop: enable Style/AccessorGrouping
|
33
29
|
end # module
|
@@ -18,12 +18,7 @@ module Loxxy
|
|
18
18
|
@property = aPropertyName
|
19
19
|
end
|
20
20
|
|
21
|
-
#
|
22
|
-
# @param visitor [ASTVisitor] the visitor
|
23
|
-
def accept(visitor)
|
24
|
-
visitor.visit_get_expr(self)
|
25
|
-
end
|
26
|
-
|
21
|
+
define_accept # Add `accept` method as found in Visitor design pattern
|
27
22
|
alias callee= object=
|
28
23
|
end # class
|
29
24
|
end # module
|
@@ -11,11 +11,7 @@ module Loxxy
|
|
11
11
|
super(aPosition, [subExpr])
|
12
12
|
end
|
13
13
|
|
14
|
-
#
|
15
|
-
# @param visitor [Ast::ASTVisitor] the visitor
|
16
|
-
def accept(visitor)
|
17
|
-
visitor.visit_grouping_expr(self)
|
18
|
-
end
|
14
|
+
define_accept # Add `accept` method as found in Visitor design pattern
|
19
15
|
end # class
|
20
16
|
end # module
|
21
17
|
end # module
|
@@ -21,17 +21,13 @@ module Loxxy
|
|
21
21
|
@else_stmt = elseStmt
|
22
22
|
end
|
23
23
|
|
24
|
-
# Part of the 'visitee' role in Visitor design pattern.
|
25
|
-
# @param visitor [Ast::ASTVisitor] the visitor
|
26
|
-
def accept(visitor)
|
27
|
-
visitor.visit_if_stmt(self)
|
28
|
-
end
|
29
|
-
|
30
24
|
# Accessor to the condition expression
|
31
25
|
# @return [LoxNode]
|
32
26
|
def condition
|
33
27
|
subnodes[0]
|
34
28
|
end
|
29
|
+
|
30
|
+
define_accept # Add `accept` method as found in Visitor design pattern
|
35
31
|
end # class
|
36
32
|
end # module
|
37
33
|
end # module
|