loxxy 0.0.15 → 0.0.20

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7624afc97e5e8d3cee171dc9fbbe7a45c45698595109a5281d9f58fcaebd73ec
4
- data.tar.gz: 67ec959b7758245f414314ea9c8b0a2bbf40a5e01133f17325fa40ab720858f0
3
+ metadata.gz: e6628d902c258d0aa2d589fd0960ab812addbfe8f0fbf162cfb627a90fbc1a40
4
+ data.tar.gz: c1fe1f5ce4b3dc7109c70783b78953fd72ffbbd837d58f8350d2a03615f80222
5
5
  SHA512:
6
- metadata.gz: adcb9cf6b353b09cf623df330fbdff35255571f8781dfd0b46ea6ab32c02cf55bd0130f94414cd91aa8cb798b1ea7cd4aef4844acc556147b5e4b387d099b8c0
7
- data.tar.gz: 47230281481b965fe1dddd74f763568a0ca125454800984c41fb29629d26c37ae8f7fa0320a38ca784abe605dfb5dc14f4a9c26b0d269240ea07c5e2feb6241b
6
+ metadata.gz: 301160cc1a00e819cc13cfb3273985b6af1ddadd94b236e4e7be0b346744355327be69d3b2d338ece3b6148a905d10a91dc3f6ef828912b7750efcdb0f4e5238
7
+ data.tar.gz: cc5bb436b6e487d7752180d42d046d5a09a6817878428d757b65b26f2955133985598b55e7d63c13d249ebef110914a3a2b8292777a2857b15dcba885c74c106
@@ -250,7 +250,7 @@ Style/IfUnlessModifier:
250
250
  Enabled: false
251
251
 
252
252
  Style/InverseMethods:
253
- Enabled: true
253
+ Enabled: false
254
254
 
255
255
  Style/MissingRespondToMissing:
256
256
  Enabled: false
@@ -1,3 +1,71 @@
1
+ ## [0.0.20] - 2021-01-15
2
+ - The interpreter supports the `if` ... `else` statement.
3
+
4
+ ## Added
5
+ - Class `Ast::LoxItStmt`, AST node specific for `if` `else` statements
6
+ - Method `Ast::ASTBuilder#reduce_if_stmt` as semantic action for if ... else
7
+ - Method `Ast::ASTVisitor#visit_if_stmt` for visiting `LoxIfStmt` nodes
8
+ - Method `Engine::after_if_stmt` implementation of the control flow
9
+
10
+ ## [0.0.19] - 2021-01-14
11
+ - The interpreter supports expressions between parentheses (grouping).
12
+
13
+ ## Added
14
+ - Class `Ast::LoxLogicalExpr`
15
+ - Method `Ast::ASTBuilder#reduce_grouping_expr` as semantic action for grouping expression
16
+ - Method `Ast::ASTVisitor#visit_grouping_expr` for visiting grouping expressions
17
+ - Method `Engine::after_grouping_expr`for the evaluation of grouping expressions
18
+
19
+ ## Changed
20
+ - File `grammar.rb` rules for if ... else were given names in order to activate semantic actions.
21
+ - File `README.md` updated with little `if ... else` documentation.
22
+
23
+ ## [0.0.18] - 2021-01-13
24
+ - The interpreter can evaluate `and`, `or`expressions.
25
+
26
+ ## Added
27
+ - Class `Ast::LoxLogicalExpr`
28
+ - Method `Ast::ASTBuilder#reduce_logical_expr` for the semantic action require for `and`, `or`
29
+ - Method `Ast::ASTVisitor#visit_logical_expr` for visiting logical expressions
30
+ - Method `Backend::Engine#after_logical_expr` implements the evaluation of the logical expressions
31
+
32
+ ## [0.0.17] - 2021-01-12
33
+ - The interpreter can evaluate all arithmetic and comparison operations.
34
+ - It implements `==`, `!=` and the unary operations `!`, `-`
35
+
36
+ ## Added
37
+ - Class `Ast::LoxUnaryExpr`
38
+ - Method `Ast::ASTBuilder#reduce_unary_expr` to support the evaluation of `!` and ``-@`
39
+ - Method `Ast::ASTVisitor#visit_unnary_expr` for visiting unary expressions
40
+ - Method `Backend::Engine#after_unary_expr` evaluating an unary expression
41
+ - In class `Datatype::BuiltinDatatype` the methods `falsey?`, `truthy?`, `!`, `!=`
42
+ - In class `Datatype::Number`the methods `<`, `<=`, ´>´, `>=` and `-@`
43
+
44
+ ## Changed
45
+ - File `README.md` updated.
46
+
47
+ ## [0.0.16] - 2021-01-11
48
+ - The interpreter can evaluate product and division of two numbers.
49
+ - It also implements equality `==` and inequality `!=` operators
50
+
51
+ ## Added
52
+ - Method `Datatype::False#==` for equality testing
53
+ - Method `Datatype::False#!=` for inequality testing
54
+ - Method `Datatype::LXString#==` for equality testing
55
+ - Method `Datatype::LXString#!=` for inequality testing
56
+ - Method `Datatype::Nil#==` for equality testing
57
+ - Method `Datatype::Nil#!=` for inequality testing
58
+ - Method `Datatype::Number#==` for equality testing
59
+ - Method `Datatype::Number#!=` for inequality testing
60
+ - Method `Datatype::Number#*` for multiply operator
61
+ - Method `Datatype::Number#/` for divide operator
62
+ - Method `Datatype::True#==` for equality testing
63
+ - Method `Datatype::True#!=` for inequality testing
64
+
65
+ ## Changed
66
+ - Method `BackEnd::Engine#after_binary_expr` to allow `*`, `/`, `==`, `!=` operators
67
+ - File `README.md` updated for the newly implemented operators
68
+
1
69
  ## [0.0.15] - 2021-01-11
2
70
  - The interpreter can evaluate substraction between two numbers.
3
71
 
@@ -14,7 +82,7 @@
14
82
  - The interpreter can evaluate addition of numbers and string concatenation
15
83
 
16
84
  ## Added
17
- - Method `Ast::ASTVisitor::visit_binary_expr` for visiting binary expressions
85
+ - Method `Ast::ASTVisitor#visit_binary_expr` for visiting binary expressions
18
86
  - Method `Ast::LoxBinaryExpr#accept` for visitor pattern
19
87
  - Method `BackEnd::Engine#after_binary_expr` to trigger execution of binary operator
20
88
  - `Boolean` class hierarchy: added methos `true?` and `false?` to ease spec test writing
data/README.md CHANGED
@@ -128,16 +128,20 @@ program
128
128
  ```
129
129
 
130
130
  ## Suppported Lox language features
131
- Although the interpreter should parse almost any valid Lox program,
132
- it currently can evaluate a tiny set of AST node (AST = Abstract Syntax Tree).
131
+ On one hand, the parser covers the complete Lox grammar and should therefore, in principle,
132
+ parse any valid Lox program.
133
+
134
+ On the other hand, the interpreter is under development and currently it can evaluate only a tiny subset of __Lox__.
135
+ But the situation is changing almost daily, stay tuned...
133
136
 
134
137
  Here are the language features currently supported by the interpreter:
135
138
 
136
139
  - [Comments](#comments)
137
140
  - [Keywords](#keywords)
138
- - [Operators and Special Chars](#operators-and-special-chars)
139
141
  - [Datatypes](#datatypes)
140
- - [Statements](#statements)
142
+ - [Statements](#statements)
143
+ -[Expressions](#expressions)
144
+ -[Print Statement](#print-statement)
141
145
 
142
146
  ### Comments
143
147
 
@@ -148,38 +152,10 @@ Loxxy supports single line C-style comments.
148
152
  ```
149
153
 
150
154
  ### Keywords
151
-
152
- The parser knows all the __Lox__ reserved keywords:
155
+ Loxxy implements the following __Lox__ reserved keywords:
153
156
  ```lang-none
154
- and, class, else, false, fun, for, if, nil, or,
155
- print, return, super, this, true, var, while
157
+ and, false, nil, or, print, true
156
158
  ```
157
- Of these, the interpreter implements: `false`, `nil`, `true`
158
-
159
- ### Operators and Special Chars
160
- #### Operators
161
- The parser recognizes all the __Lox__ operators, delimiters and separators:
162
- - Arithmetic operators: `+`, `-`, `*`, `/`
163
- - Comparison operators: `>`, `>=`, `<`, `<=`
164
- - Equality operators: `==`, `!=`
165
-
166
- Of these, the interpreter implements:
167
- `+` (addition of two numbers or string concatenation)
168
- `-` (difference between two numbers)
169
-
170
- #### Delimiters
171
- The parser knows all the __Lox__ grouping delimiters:
172
- (`, ), `{`, `}`
173
-
174
- These aren't yet implemented in the interpreter.
175
-
176
- The other characters that have a special meaning in __Lox__ are:
177
- - `,` Used in parameter list
178
- - `.` For the dot notation (i.e. calling a method)
179
- - `;` The semicolon is used to terminates expressions
180
- - `=` Assignment
181
-
182
- The parser recognizes them all but the interpreter accepts the semicolons only.
183
159
 
184
160
  ### Datatypes
185
161
 
@@ -189,22 +165,138 @@ loxxy supports all the standard __Lox__ datatypes:
189
165
  - `String`: Sequence of characters surrounded by `"`. For example: `"Hello!"`
190
166
  - `Nil`: Used to define a null value, denoted by the `nil` keyword
191
167
 
192
- ## Statements
193
- ### Implemented expressions
194
- Loxxy implements expressions:
195
- - Plain literals only; or,
196
- - Addition of two numbers; or,
197
- - Subtraction of two numbers; or,
198
- - Concatenation of two strings
168
+ ### Statements
169
+
170
+ Loxxy supports the following statements:
171
+ -[Expressions](#expressions)
172
+ -[Arithmetic expressions](#arithmetic-expressions)
173
+ -[String concatenation](#string-concatenation)
174
+ -[Comparison expressions](#comparison-expressions)
175
+ -[Logical expressions](#logical-expressions)
176
+ -[Grouping expressions](#grouping-expressions)
177
+ -[If Statement](#if-statement)
178
+ -[Print Statement](#print-statement)
179
+
180
+ #### Expressions
181
+
182
+ ##### Arithmetic expressions
183
+ Loxxy supports the following operators for arithmetic expressions:
184
+
185
+ - `+`: Adds of two numbers. Both operands must be of the type Number
186
+ E.g. `37 + 5; // => 42`
187
+ `7 + -3; // => 4`
188
+ - `-`: (Binary) Subtracts right operand from left operand. Both operands must be numbers.
189
+ E.g. `47 - 5; // => 42`
190
+ - `-`: (Unary) Negates (= changes the sign) of the given number operand.
191
+ E.g. `- -3; // => 3`
192
+ - `*`: Multiplies two numbers
193
+ E.g. `2 * 3; // => 6`
194
+ - `/`: Divides two numbers
195
+ E.g. `8 / 2; // => 4`
196
+ `5 / 2; // => 2.5`
197
+
198
+ ##### String concatenation
199
+ - `+`: Concatenates two strings. Both operands must be of the String type.
200
+ E.g. `"Hello" + ", " + "world! // => "Hello, world!"`
201
+
202
+ ##### Comparison expressions
203
+
204
+ - `==`: Returns `true` if left operand is equal to right operand, otherwise `false`
205
+ E.g. `false == false; // => true`
206
+ `5 + 2 == 3 + 4; // => true`
207
+ `"" == ""; // => true`
208
+ - `!=`: Returns `true` if left operand is not equal to right operand, otherwise `false`
209
+ E.g. `false != "false"; // => true`
210
+ `5 + 2 != 4 + 3; // => false`
211
+ - `<`: Returns `true` if left operand is less than right operand, otherwise `false`. Both operands must be numbers
212
+ E.g. `1 < 3; // => true`
213
+ `1 < 0; // => false`
214
+ `2 < 2; // => false`
215
+ - `<=`: Returns `true` if left operand is equal to right operand, otherwise `false`. Both operands must be numbers
216
+ E.g. `1 <= 3; // => true`
217
+ `1 <= 0; // => false`
218
+ `2 <= 2; // => true`
219
+ - `>`: Returns `true` if left operand is equal to right operand, otherwise `false`. Both operands must be numbers
220
+ E.g. `1 > 3; // => false`
221
+ `1 > 0; // => true`
222
+ `2 > 2; // => false`
223
+ - `>=`: Returns `true` if left operand is equal to right operand, otherwise `false`. Both operands must be numbers
224
+ E.g. `1 > 3; // => false`
225
+ `1 > 0; // => true`
226
+ `2 > 2; // => false`
227
+
228
+ ##### Logical expressions
229
+
230
+ REMINDER: In __Lox__, `false` and `nil` are considered falsey, everything else is truthy.
231
+
232
+ - `and`: When both operands are booleans, then returns `true` if both left and right operands are truthy, otherwise `false`.
233
+ If at least one operand isn't a boolean then returns first falsey operand else (both operands are truthy) returns the second operand.
234
+ truthy returns the second operand.
235
+ E.g. `false and true; // => false`
236
+ `true and nil; // => nil`
237
+ `0 and true and ""; // => ""`
238
+ - `or`: When both operands are booleans, then returns `true` if left or right operands are truthy, otherwise `false`.
239
+ If at least one operand isn't a boolean then returns first truthy operand else (both operands are truthy) returns the second operand.
240
+ E.g. `false or true; // => true`
241
+ `true or nil; // => nil`
242
+ `false or nil; // => nil`
243
+ `0 or true or ""; // => 0`
244
+ - `!`: Performs a logical negation on its operand
245
+ E.g. `!false; // => true`
246
+ `!!true; // => true`
247
+ `!0; // => false`
248
+
249
+ #### Grouping expressions
250
+ Use parentheses `(` `)` for a better control in expression/operator precedence.
251
+
252
+ ``` javascript
253
+ print 3 + 4 * 5; // => 23
254
+ print (3 + 4) * 5; // => 35
255
+ ```
199
256
 
200
- ### Implemented statements
201
- Loxxy implements the following statements:
202
- - Expressions (see above sub-section)
203
- - Print statement
257
+ #### If statement
258
+
259
+ Based on a given condition, an if statement executes one of two statements:
260
+ ``` javascript
261
+ if (condition) {
262
+ print "then-branch";
263
+ } else {
264
+ print "else-branch";
265
+ }
266
+ ```
267
+
268
+ As for other languages, the `else` part is optional.
269
+ ##### Warning: nested `if`...`else`
270
+ Call it a bug ... Nested `if` `else` control flow structure aren't yet supported by __Loxxy__.
271
+ The culprit has a name: [the dangling else](https://en.wikipedia.org/wiki/Dangling_else).
272
+
273
+ The problem in a nutshell: in a nested if ... else ... statement like this:
274
+ ``` javascript
275
+ 'if (true) if (false) print "bad"; else print "good";
276
+ ```
277
+ ... there is an ambiguity. Indeed, according to the __Lox__ grammar, the `else` could be bound
278
+ either to the first `if` or to the second one.
279
+ This ambiguity is usually lifted by applying an ad-hoc rule: an `else` is aways bound to the most
280
+ recent (rightmost) `if`.
281
+ Being a generic parsing library, `Rley` doesn't apply any of these supplemental rules.
282
+ As a consequence,it complains about the found ambiguity and stops the parsing...
283
+ Although `Rley` can cope with ambiguities, this requires the use of an advanced data structure
284
+ called `Shared Packed Parse Forest (SPPF)`.
285
+ SPPF are much more complex to handle than the `common` parse trees present in most compiler or interpreter books.
286
+ Therefore, a future version of `Rley` will incorporate the capability to define disambuiguation rules.
287
+
288
+ In the meantime, the `Loxxy` will progress on other __Lox__ features like:
289
+ - Variables,
290
+ - Block structures...
291
+
292
+
293
+ #### Print Statement
294
+
295
+ The statement print + expression + ; prints the result of the expression to stdout.
296
+
297
+ ``` javascript
298
+ print "Hello, world!"; // Output: Hello, world!
204
299
 
205
- ```javascript
206
- // Print statement with nested concatenation
207
- print "Hello" + ", " + "world!";
208
300
  ```
209
301
 
210
302
  ## Installation
@@ -1,5 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'lox_print_stmt'
4
3
  require_relative 'lox_literal_expr'
5
4
  require_relative 'lox_noop_expr'
5
+ require_relative 'lox_grouping_expr'
6
+ require_relative 'lox_unary_expr'
7
+ require_relative 'lox_binary_expr'
8
+ require_relative 'lox_logical_expr'
9
+ require_relative 'lox_print_stmt'
10
+ require_relative 'lox_if_stmt'
@@ -15,7 +15,6 @@ module Loxxy
15
15
  # @return [Hash{String => String}]
16
16
  Name2special = {
17
17
  'AND' => 'and',
18
- 'BANG' => '!',
19
18
  'BANG_EQUAL' => '!=',
20
19
  'COMMA' => ',',
21
20
  'DOT' => '.',
@@ -36,6 +35,11 @@ module Loxxy
36
35
  'SLASH' => '/',
37
36
  'STAR' => '*'
38
37
  }.freeze
38
+
39
+ Name2unary = {
40
+ 'BANG' => '!',
41
+ 'MINUS' => '-@'
42
+ }.freeze
39
43
  end # defined
40
44
 
41
45
  attr_reader :strict
@@ -92,6 +96,17 @@ module Loxxy
92
96
  node
93
97
  end
94
98
 
99
+ def reduce_logical_expr(_production, _range, tokens, theChildren)
100
+ operand1 = theChildren[0]
101
+
102
+ # Second child is array with couples [operator, operand2]
103
+ theChildren[1].each do |(operator, operand2)|
104
+ operand1 = LoxLogicalExpr.new(tokens[0].position, operator, operand1, operand2)
105
+ end
106
+
107
+ operand1
108
+ end
109
+
95
110
  # rule('lhs' => 'nonterm_i nonterm_k_plus')
96
111
  def reduce_binary_operator(_production, _range, tokens, theChildren)
97
112
  operand1 = theChildren[0]
@@ -119,6 +134,11 @@ module Loxxy
119
134
  [[operator, operand2]]
120
135
  end
121
136
 
137
+ # Return the AST node corresponding to the second symbol in the rhs
138
+ def reduce_keep_symbol2(_production, _range, _tokens, theChildren)
139
+ theChildren[1]
140
+ end
141
+
122
142
  #####################################
123
143
  # SEMANTIC ACTIONS
124
144
  #####################################
@@ -138,6 +158,14 @@ module Loxxy
138
158
  return_first_child(range, tokens, theChildren) # Discard the semicolon
139
159
  end
140
160
 
161
+ # rule('ifStmt' => 'IF ifCondition statement elsePart_opt')
162
+ def reduce_if_stmt(_production, _range, tokens, theChildren)
163
+ condition = theChildren[1]
164
+ then_stmt = theChildren[2]
165
+ else_stmt = theChildren[3]
166
+ LoxIfStmt.new(tokens[0].position, condition, then_stmt, else_stmt)
167
+ end
168
+
141
169
  # rule('printStmt' => 'PRINT expression SEMICOLON')
142
170
  def reduce_print_stmt(_production, _range, tokens, theChildren)
143
171
  Ast::LoxPrintStmt.new(tokens[1].position, theChildren[1])
@@ -145,7 +173,7 @@ module Loxxy
145
173
 
146
174
  # rule('logic_or' => 'logic_and disjunct_plus')
147
175
  def reduce_logic_or_plus(production, range, tokens, theChildren)
148
- reduce_binary_operator(production, range, tokens, theChildren)
176
+ reduce_logical_expr(production, range, tokens, theChildren)
149
177
  end
150
178
 
151
179
  # rule('disjunct_plus' => 'disjunct_plus OR logic_and')
@@ -160,7 +188,7 @@ module Loxxy
160
188
 
161
189
  # rule('logic_and' => 'equality conjunct_plus')
162
190
  def reduce_logic_and_plus(production, range, tokens, theChildren)
163
- reduce_binary_operator(production, range, tokens, theChildren)
191
+ reduce_logical_expr(production, range, tokens, theChildren)
164
192
  end
165
193
 
166
194
  # rule('conjunct_plus' => 'conjunct_plus AND equality')
@@ -231,6 +259,19 @@ module Loxxy
231
259
  reduce_binary_plus_end(production, range, tokens, theChildren)
232
260
  end
233
261
 
262
+ # rule('unary' => 'unaryOp unary')
263
+ def reduce_unary_expr(_production, _range, tokens, theChildren)
264
+ operator = Name2unary[theChildren[0].symbol.name].to_sym
265
+ operand = theChildren[1]
266
+ LoxUnaryExpr.new(tokens[0].position, operator, operand)
267
+ end
268
+
269
+ # rule('primary' => 'LEFT_PAREN expression RIGHT_PAREN')
270
+ def reduce_grouping_expr(_production, _range, tokens, theChildren)
271
+ subexpr = theChildren[1]
272
+ LoxGroupingExpr.new(tokens[0].position, subexpr)
273
+ end
274
+
234
275
  # rule('primary' => 'FALSE' | TRUE').as 'literal_expr'
235
276
  def reduce_literal_expr(_production, _range, _tokens, theChildren)
236
277
  first_child = theChildren.first
@@ -51,7 +51,15 @@ module Loxxy
51
51
  broadcast(:after_ptree, aParseTree)
52
52
  end
53
53
 
54
- # Visit event. The visitor is about to visit a print statement expression.
54
+ # Visit event. The visitor is about to visit a if statement.
55
+ # @param anIfStmt [AST::LOXIfStmt] the if statement node to visit
56
+ def visit_if_stmt(anIfStmt)
57
+ broadcast(:before_if_stmt, anIfStmt)
58
+ traverse_subnodes(anIfStmt) # The condition is visited/evaluated here...
59
+ broadcast(:after_if_stmt, anIfStmt, self)
60
+ end
61
+
62
+ # Visit event. The visitor is about to visit a print statement.
55
63
  # @param aPrintStmt [AST::LOXPrintStmt] the print statement node to visit
56
64
  def visit_print_stmt(aPrintStmt)
57
65
  broadcast(:before_print_stmt, aPrintStmt)
@@ -59,7 +67,21 @@ module Loxxy
59
67
  broadcast(:after_print_stmt, aPrintStmt)
60
68
  end
61
69
 
62
- # Visit event. The visitor is about to visit a print statement expression.
70
+ # Visit event. The visitor is about to visit a logical expression.
71
+ # Since logical expressions may take shorcuts by not evaluating all their
72
+ # sub-expressiosns, they are responsible for visiting or not their children.
73
+ # @param aBinaryExpr [AST::LOXBinaryExpr] the logical expression node to visit
74
+ def visit_logical_expr(aLogicalExpr)
75
+ broadcast(:before_logical_expr, aLogicalExpr)
76
+
77
+ # As logical connectors may take a shortcut only the first argument is visited
78
+ traverse_given_subnode(aLogicalExpr, 0)
79
+
80
+ # The second child could be visited: this action is deferred in handler
81
+ broadcast(:after_logical_expr, aLogicalExpr, self)
82
+ end
83
+
84
+ # Visit event. The visitor is about to visit a binary expression.
63
85
  # @param aBinaryExpr [AST::LOXBinaryExpr] the binary expression node to visit
64
86
  def visit_binary_expr(aBinaryExpr)
65
87
  broadcast(:before_binary_expr, aBinaryExpr)
@@ -67,6 +89,22 @@ module Loxxy
67
89
  broadcast(:after_binary_expr, aBinaryExpr)
68
90
  end
69
91
 
92
+ # Visit event. The visitor is about to visit an unary expression.
93
+ # @param anUnaryExpr [AST::anUnaryExpr] unary expression node to visit
94
+ def visit_unary_expr(anUnaryExpr)
95
+ broadcast(:before_unary_expr, anUnaryExpr)
96
+ traverse_subnodes(anUnaryExpr)
97
+ broadcast(:after_unary_expr, anUnaryExpr)
98
+ end
99
+
100
+ # Visit event. The visitor is about to visit a grouping expression.
101
+ # @param aGroupingExpr [AST::LoxGroupingExpr] grouping expression to visit
102
+ def visit_grouping_expr(aGroupingExpr)
103
+ broadcast(:before_grouping_expr, aGroupingExpr)
104
+ traverse_subnodes(aGroupingExpr)
105
+ broadcast(:after_grouping_expr, aGroupingExpr)
106
+ end
107
+
70
108
  # Visit event. The visitor is visiting the
71
109
  # given terminal node containing a datatype object.
72
110
  # @param aLiteralExpr [AST::LoxLiteralExpr] the leaf node to visit.
@@ -98,6 +136,20 @@ module Loxxy
98
136
  broadcast(:after_subnodes, aParentNode, subnodes)
99
137
  end
100
138
 
139
+ # Visit event. The visitor is about to visit one given subnode of a non
140
+ # terminal node.
141
+ # @param aParentNode [Ast::LocCompoundExpr] the parent node.
142
+ # @param index [integer] index of child subnode
143
+ def traverse_given_subnode(aParentNode, index)
144
+ subnode = aParentNode.subnodes[index]
145
+ broadcast(:before_given_subnode, aParentNode, subnode)
146
+
147
+ # Now, let's proceed with the visit of that subnode
148
+ subnode.accept(self)
149
+
150
+ broadcast(:after_given_subnode, aParentNode, subnode)
151
+ end
152
+
101
153
  # Send a notification to all subscribers.
102
154
  # @param msg [Symbol] event to notify
103
155
  # @param args [Array] arguments of the notification.