loxxy 0.0.21 → 0.0.22

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fd4cbf32f4ee44a60c45630a76318425850dc35b4d9f6129274cefcbf4e91fcc
4
- data.tar.gz: 711e0ae07d2a0b3a080c2fe408d9adf4f7b96bb070af686d66dd3f9dbae8391d
3
+ metadata.gz: acd7b65477866aee4f022731a70f67cad63f482eae6ae5e3f5a35cd56c43f9b0
4
+ data.tar.gz: 4980c1dafbd83c1ed0a41cf5da09d0decba43e912722c5052fc3e4f63626d73a
5
5
  SHA512:
6
- metadata.gz: 131f6fe3b23dc0a84b063efe70744b02ecc9edb68742540799964311298f35494a0d48db75bb18a240ddeed039286ab08ba2ef99e2ae4857d2b4d5dc4403d5ba
7
- data.tar.gz: b46c18f54147fd01f9819e3ad06564ee78fe72de5c91d6ef8a5bef5945d9f1ad622cad848c4d521ae66f00c91b7825d01e57c831b2a097da830bec0d99f2cf06
6
+ metadata.gz: e8853388df750173e1a9e818e3aac92f33f98ff75cf5c575d0b583758c59938810a593823a73a6914a28413ba697d53147d7317b744484d43b4026c76a182bc4
7
+ data.tar.gz: 3426ce17792625f908f2a31c879b0a312cbefbe18c82848f769d78bcac550d3700349fc1408bbeddb7738b47735ed583fd89355636c8c377a7cde3baf2f5071f
@@ -1,4 +1,19 @@
1
- ## [0.0.21] - 2021-01-1x
1
+ ## [0.0.22] - 2021-01-17
2
+ - The interpreter can retrieve the value of a variable.
3
+
4
+ ## Added
5
+ - Method `Ast::ASTBuilder#declaration_plus_more` and `Ast::ASTBuilder#declaration_plus_end` to allow multiple expressions/statements
6
+ - Method `Ast::ASTBuilder#reduce_var_expression` creates an `Ast::LoxVariableExpr` node
7
+ - Method `Ast::ASTVisitor#visit_var_expr` for visiting `Ast::LoxVariableExpr` nodes
8
+ - Class `Ast::LoxSeqDecl` a node that represents a sequence of declarations/statements
9
+ - Class `Ast::LoxVarExpr` a node that represents a variable occurrence in an expression
10
+ - Method `Engine::after_variable_expr`: retrieve the value of variable with given name
11
+
12
+ ## Changed
13
+ - Method `Ast::ASTBuilder#reduce_lox_program` to support multiple statements/declarations
14
+ - File `README.md` updated.
15
+
16
+ ## [0.0.21] - 2021-01-16
2
17
  - The interpreter supports the declaration global variables.
3
18
 
4
19
  ## Added
data/README.md CHANGED
@@ -176,6 +176,7 @@ Loxxy supports the following statements:
176
176
  -[Comparison expressions](#comparison-expressions)
177
177
  -[Logical expressions](#logical-expressions)
178
178
  -[Grouping expressions](#grouping-expressions)
179
+ -[Variable expressions](#variable-expressions)
179
180
 
180
181
  -[Variable declarations](#var-statement)
181
182
  -[If Statement](#if-statement)
@@ -258,13 +259,20 @@ print 3 + 4 * 5; // => 23
258
259
  print (3 + 4) * 5; // => 35
259
260
  ```
260
261
 
262
+ #### Variable expressions
263
+ In __Lox__, a variable expression is nothing than retrieving the value of a variable.
264
+ ``` javascript
265
+ var foo = "bar;" // Variable declaration
266
+ foo; // Varible expression (= retrieving its value)
267
+ ```
268
+
261
269
  #### Variable declarations
262
270
  ``` javascript
263
271
  var iAmAVariable = "my-initial-value";
264
272
  var iAmNil; // __Lox__ initializes variables to nil by default;
265
273
  ```
266
274
 
267
- Warning: current version cannot retrieve the value of a variable.
275
+ Warning: current version cannot assign a value to an existing variable.
268
276
  Expect this capability to be implemented in the coming days.
269
277
 
270
278
 
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'lox_variable_expr'
3
4
  require_relative 'lox_literal_expr'
4
5
  require_relative 'lox_noop_expr'
5
6
  require_relative 'lox_grouping_expr'
@@ -9,3 +10,4 @@ require_relative 'lox_logical_expr'
9
10
  require_relative 'lox_print_stmt'
10
11
  require_relative 'lox_if_stmt'
11
12
  require_relative 'lox_var_stmt'
13
+ require_relative 'lox_seq_decl'
@@ -150,7 +150,17 @@ module Loxxy
150
150
 
151
151
  # rule('program' => 'declaration_plus EOF').as ''
152
152
  def reduce_lox_program(_production, range, tokens, theChildren)
153
- return_first_child(range, tokens, theChildren) # Discard the semicolon
153
+ LoxSeqDecl.new(tokens[0].position, theChildren[0])
154
+ end
155
+
156
+ # rule('declaration_plus' => 'declaration_plus declaration').as ''
157
+ def reduce_declaration_plus_more(_production, range, tokens, theChildren)
158
+ theChildren[0] << theChildren[1]
159
+ end
160
+
161
+ # rule('declaration_plus' => 'declaration')
162
+ def reduce_declaration_plus_end(_production, range, tokens, theChildren)
163
+ [ theChildren[0] ]
154
164
  end
155
165
 
156
166
  # rule('exprStmt' => 'expression SEMICOLON')
@@ -292,6 +302,13 @@ module Loxxy
292
302
  literal = first_child.token.value
293
303
  LoxLiteralExpr.new(pos, literal)
294
304
  end
305
+
306
+ # rule('primary' => 'IDENTIFIER')
307
+ def reduce_variable_expr(_production, _range, tokens, theChildren)
308
+ var_name = theChildren[0].token.lexeme
309
+ LoxVariableExpr.new(tokens[0].position, var_name)
310
+ end#
311
+
295
312
  end # class
296
313
  end # module
297
314
  end # module
@@ -51,6 +51,14 @@ module Loxxy
51
51
  broadcast(:after_ptree, aParseTree)
52
52
  end
53
53
 
54
+ # Visit event. The visitor is about to visit a variable declaration statement.
55
+ # @param aPrintStmt [AST::LOXVarStmt] the variable declaration node to visit
56
+ def visit_seq_decl(aSeqDecls)
57
+ broadcast(:before_seq_decl, aSeqDecls)
58
+ traverse_subnodes(aSeqDecls)
59
+ broadcast(:after_seq_decl, aSeqDecls)
60
+ end
61
+
54
62
  # Visit event. The visitor is about to visit a variable declaration statement.
55
63
  # @param aPrintStmt [AST::LOXVarStmt] the variable declaration node to visit
56
64
  def visit_var_stmt(aVarStmt)
@@ -121,8 +129,15 @@ module Loxxy
121
129
  broadcast(:after_literal_expr, aLiteralExpr)
122
130
  end
123
131
 
132
+ # Visit event. The visitor is visiting a variable reference node
133
+ # @param aLiteralExpr [AST::LoxVariableExpr] the variable reference node to visit.
134
+ def visit_variable_expr(aVariableExpr)
135
+ broadcast(:before_variable_expr, aVariableExpr)
136
+ broadcast(:after_variable_expr, aVariableExpr, self)
137
+ end
138
+
124
139
  # Visit event. The visitor is about to visit the given non terminal node.
125
- # @param aNonTerminalNode [Rley::PTre::NonTerminalNode] the node to visit.
140
+ # @param aNonTerminalNode [Rley::PTree::NonTerminalNode] the node to visit.
126
141
  def visit_nonterminal(_non_terminal_node)
127
142
  # Loxxy interpreter encountered a CST node (Concrete Syntax Tree)
128
143
  # that it cannot handle.
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lox_compound_expr'
4
+
5
+ module Loxxy
6
+ module Ast
7
+ class LoxSeqDecl < LoxCompoundExpr
8
+ # @param aPosition [Rley::Lexical::Position] Position of the entry in the input stream.
9
+ # @param declarations [Arrya<Loxxy::Ast::LoxNode>]
10
+ def initialize(aPosition, declarations)
11
+ super(aPosition, declarations)
12
+ end
13
+
14
+ # Part of the 'visitee' role in Visitor design pattern.
15
+ # @param visitor [Ast::ASTVisitor] the visitor
16
+ def accept(visitor)
17
+ visitor.visit_seq_decl(self)
18
+ end
19
+
20
+ alias operands subnodes
21
+ end # class
22
+ end # module
23
+ end # module
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lox_node'
4
+
5
+ module Loxxy
6
+ module Ast
7
+ # This AST node represents a mention of a variable
8
+ class LoxVariableExpr < LoxNode
9
+ # @return [String] variable name
10
+ attr_reader :name
11
+
12
+ # @param aPosition [Rley::Lexical::Position] Position of the entry in the input stream.
13
+ # @param aName [String] name of the variable
14
+ def initialize(aPosition, aName)
15
+ super(aPosition)
16
+ @name = aName
17
+ end
18
+
19
+ # Part of the 'visitee' role in Visitor design pattern.
20
+ # @param visitor [Ast::ASTVisitor] the visitor
21
+ def accept(visitor)
22
+ visitor.visit_variable_expr(self)
23
+ end
24
+ end # class
25
+ end # module
26
+ end # module
@@ -41,6 +41,11 @@ module Loxxy
41
41
  ##########################################################################
42
42
  # Visit event handling
43
43
  ##########################################################################
44
+
45
+ def after_seq_decl(aSeqDecls)
46
+ # Do nothing, subnodes were already evaluated
47
+ end
48
+
44
49
  def after_var_stmt(aVarStmt)
45
50
  new_var = Variable.new(aVarStmt.name, aVarStmt.subnodes[0])
46
51
  symbol_table.insert(new_var)
@@ -120,6 +125,13 @@ module Loxxy
120
125
  # Do nothing: work was already done by visiting /evaluating the subexpression
121
126
  end
122
127
 
128
+ def after_variable_expr(aVarExpr, aVisitor)
129
+ var_name = aVarExpr.name
130
+ var = symbol_table.lookup(var_name)
131
+ raise StandardError, "Unknown variable #{var_name}" unless var
132
+ var.value.accept(aVisitor) # Evaluate the variable value
133
+ end
134
+
123
135
  # @param literalExpr [Ast::LoxLiteralExpr]
124
136
  def before_literal_expr(literalExpr)
125
137
  stack.push(literalExpr.literal)
@@ -30,8 +30,8 @@ module Loxxy
30
30
  rule('program' => 'declaration_plus EOF').as 'lox_program'
31
31
 
32
32
  # Declarations: bind an identifier to something
33
- rule('declaration_plus' => 'declaration_plus declaration')
34
- rule('declaration_plus' => 'declaration')
33
+ rule('declaration_plus' => 'declaration_plus declaration').as 'declaration_plus_more'
34
+ rule('declaration_plus' => 'declaration').as 'declaration_plus_end'
35
35
  rule('declaration' => 'classDecl')
36
36
  rule('declaration' => 'funDecl')
37
37
  rule('declaration' => 'varDecl')
@@ -137,7 +137,7 @@ module Loxxy
137
137
  rule('primary' => 'THIS')
138
138
  rule('primary' => 'NUMBER').as 'literal_expr'
139
139
  rule('primary' => 'STRING').as 'literal_expr'
140
- rule('primary' => 'IDENTIFIER')
140
+ rule('primary' => 'IDENTIFIER').as 'variable_expr'
141
141
  rule('primary' => 'LEFT_PAREN expression RIGHT_PAREN').as 'grouping_expr'
142
142
  rule('primary' => 'SUPER DOT IDENTIFIER')
143
143
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Loxxy
4
- VERSION = '0.0.21'
4
+ VERSION = '0.0.22'
5
5
  end
@@ -34,6 +34,7 @@ module Loxxy
34
34
  let(:var_decl) { Ast::LoxVarStmt.new(sample_pos, 'greeting', greeting) }
35
35
  let(:lit_expr) { Ast::LoxLiteralExpr.new(sample_pos, greeting) }
36
36
 
37
+
37
38
  it "should react to 'after_var_stmt' event" do
38
39
  expect { subject.after_var_stmt(var_decl) }.not_to raise_error
39
40
  current_env = subject.symbol_table.current_env
@@ -64,7 +64,8 @@ module Loxxy
64
64
  it 'should parse a false literal' do
65
65
  input = 'false;'
66
66
  ptree = subject.parse(input)
67
- leaf = ptree.root
67
+ expect(ptree.root).to be_kind_of(Ast::LoxSeqDecl)
68
+ leaf = ptree.root.subnodes[0]
68
69
  expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
69
70
  expect(leaf.literal).to be_equal(Datatype::False.instance)
70
71
  end
@@ -72,7 +73,8 @@ module Loxxy
72
73
  it 'should parse a true literal' do
73
74
  input = 'true;'
74
75
  ptree = subject.parse(input)
75
- leaf = ptree.root
76
+ expect(ptree.root).to be_kind_of(Ast::LoxSeqDecl)
77
+ leaf = ptree.root.subnodes[0]
76
78
  expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
77
79
  expect(leaf.literal).to be_equal(Datatype::True.instance)
78
80
  end
@@ -81,7 +83,7 @@ module Loxxy
81
83
  inputs = %w[1234; 12.34;]
82
84
  inputs.each do |source|
83
85
  ptree = subject.parse(source)
84
- leaf = ptree.root
86
+ leaf = ptree.root.subnodes[0]
85
87
  expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
86
88
  expect(leaf.literal).to be_kind_of(Datatype::Number)
87
89
  expect(leaf.literal.value).to eq(source.to_f)
@@ -96,7 +98,7 @@ module Loxxy
96
98
  ]
97
99
  inputs.each do |source|
98
100
  ptree = subject.parse(source)
99
- leaf = ptree.root
101
+ leaf = ptree.root.subnodes[0]
100
102
  expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
101
103
  expect(leaf.literal).to be_kind_of(Datatype::LXString)
102
104
  expect(leaf.literal.value).to eq(source.gsub(/(^")|(";$)/, ''))
@@ -106,7 +108,7 @@ module Loxxy
106
108
  it 'should parse a nil literal' do
107
109
  input = 'nil;'
108
110
  ptree = subject.parse(input)
109
- leaf = ptree.root
111
+ leaf = ptree.root.subnodes[0]
110
112
  expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
111
113
  expect(leaf.literal).to be_equal(Datatype::Nil.instance)
112
114
  end
@@ -119,7 +121,7 @@ module Loxxy
119
121
  print "Hello, world!";
120
122
  LOX_END
121
123
  ptree = subject.parse(program)
122
- prnt_stmt = ptree.root
124
+ prnt_stmt = ptree.root.subnodes[0]
123
125
  expect(prnt_stmt).to be_kind_of(Ast::LoxPrintStmt)
124
126
  expect(prnt_stmt.subnodes[0]).to be_kind_of(Ast::LoxLiteralExpr)
125
127
  expect(prnt_stmt.subnodes[0].literal).to be_kind_of(Loxxy::Datatype::LXString)
@@ -131,7 +133,7 @@ LOX_END
131
133
  it 'should parse the addition of two number literals' do
132
134
  input = '123 + 456;'
133
135
  ptree = subject.parse(input)
134
- expr = ptree.root
136
+ expr = ptree.root.subnodes[0]
135
137
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
136
138
  expect(expr.operator).to eq(:+)
137
139
  expect(expr.operands[0].literal.value).to eq(123)
@@ -141,7 +143,7 @@ LOX_END
141
143
  it 'should parse the subtraction of two number literals' do
142
144
  input = '4 - 3;'
143
145
  ptree = subject.parse(input)
144
- expr = ptree.root
146
+ expr = ptree.root.subnodes[0]
145
147
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
146
148
  expect(expr.operator).to eq(:-)
147
149
  expect(expr.operands[0].literal.value).to eq(4)
@@ -151,7 +153,7 @@ LOX_END
151
153
  it 'should parse multiple additive operations' do
152
154
  input = '5 + 2 - 3;'
153
155
  ptree = subject.parse(input)
154
- expr = ptree.root
156
+ expr = ptree.root.subnodes[0]
155
157
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
156
158
  expect(expr.operator).to eq(:-)
157
159
  expect(expr.operands[0]).to be_kind_of(Ast::LoxBinaryExpr)
@@ -164,7 +166,7 @@ LOX_END
164
166
  it 'should parse the division of two number literals' do
165
167
  input = '8 / 2;'
166
168
  ptree = subject.parse(input)
167
- expr = ptree.root
169
+ expr = ptree.root.subnodes[0]
168
170
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
169
171
  expect(expr.operator).to eq(:/)
170
172
  expect(expr.operands[0].literal.value).to eq(8)
@@ -174,7 +176,7 @@ LOX_END
174
176
  it 'should parse the product of two number literals' do
175
177
  input = '12.34 * 0.3;'
176
178
  ptree = subject.parse(input)
177
- expr = ptree.root
179
+ expr = ptree.root.subnodes[0]
178
180
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
179
181
  expect(expr.operator).to eq(:*)
180
182
  expect(expr.operands[0].literal.value).to eq(12.34)
@@ -184,7 +186,7 @@ LOX_END
184
186
  it 'should parse multiple multiplicative operations' do
185
187
  input = '5 * 2 / 3;'
186
188
  ptree = subject.parse(input)
187
- expr = ptree.root
189
+ expr = ptree.root.subnodes[0]
188
190
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
189
191
  expect(expr.operator).to eq(:/)
190
192
  expect(expr.operands[0]).to be_kind_of(Ast::LoxBinaryExpr)
@@ -197,7 +199,7 @@ LOX_END
197
199
  it 'should parse combination of terms and factors' do
198
200
  input = '5 + 2 / 3;'
199
201
  ptree = subject.parse(input)
200
- expr = ptree.root
202
+ expr = ptree.root.subnodes[0]
201
203
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
202
204
  expect(expr.operator).to eq(:+)
203
205
  expect(expr.operands[0].literal.value).to eq(5)
@@ -212,7 +214,7 @@ LOX_END
212
214
  it 'should parse the concatenation of two string literals' do
213
215
  input = '"Lo" + "ve";'
214
216
  ptree = subject.parse(input)
215
- expr = ptree.root
217
+ expr = ptree.root.subnodes[0]
216
218
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
217
219
  expect(expr.operator).to eq(:+)
218
220
  expect(expr.operands[0].literal.value).to eq('Lo')
@@ -225,7 +227,7 @@ LOX_END
225
227
  %w[> >= < <=].each do |predicate|
226
228
  input = "3 #{predicate} 2;"
227
229
  ptree = subject.parse(input)
228
- expr = ptree.root
230
+ expr = ptree.root.subnodes[0]
229
231
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
230
232
  expect(expr.operator).to eq(predicate.to_sym)
231
233
  expect(expr.operands[0].literal.value).to eq(3)
@@ -239,7 +241,7 @@ LOX_END
239
241
  %w[!= ==].each do |predicate|
240
242
  input = "3 #{predicate} 2;"
241
243
  ptree = subject.parse(input)
242
- expr = ptree.root
244
+ expr = ptree.root.subnodes[0]
243
245
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
244
246
  expect(expr.operator).to eq(predicate.to_sym)
245
247
  expect(expr.operands[0].literal.value).to eq(3)
@@ -250,7 +252,7 @@ LOX_END
250
252
  it 'should parse combination of equality expressions' do
251
253
  input = '5 != 2 == false; // A bit contrived example'
252
254
  ptree = subject.parse(input)
253
- expr = ptree.root
255
+ expr = ptree.root.subnodes[0]
254
256
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
255
257
  expect(expr.operator).to eq(:==)
256
258
  expect(expr.operands[0]).to be_kind_of(Ast::LoxBinaryExpr)
@@ -266,7 +268,7 @@ LOX_END
266
268
  %w[or and].each do |connector|
267
269
  input = "5 > 2 #{connector} 3 <= 4;"
268
270
  ptree = subject.parse(input)
269
- expr = ptree.root
271
+ expr = ptree.root.subnodes[0]
270
272
  expect(expr).to be_kind_of(Ast::LoxLogicalExpr)
271
273
  expect(expr.operator).to eq(connector.to_sym)
272
274
  expect(expr.operands[0]).to be_kind_of(Ast::LoxBinaryExpr)
@@ -283,7 +285,7 @@ LOX_END
283
285
  it 'should parse a combinations of logical expressions' do
284
286
  input = '4 > 3 and 1 < 2 or 4 >= 5;'
285
287
  ptree = subject.parse(input)
286
- expr = ptree.root
288
+ expr = ptree.root.subnodes[0]
287
289
  expect(expr).to be_kind_of(Ast::LoxLogicalExpr)
288
290
  expect(expr.operator).to eq(:or) # or has lower precedence than and
289
291
  expect(expr.operands[0]).to be_kind_of(Ast::LoxLogicalExpr)
@@ -52,7 +52,12 @@ module Loxxy
52
52
  end # context
53
53
 
54
54
  context 'Evaluating Lox code:' do
55
- let(:hello_world) { 'print "Hello, world!";' }
55
+ let(:hello_world) do
56
+ lox =<<-LOX_END
57
+ var greeting = "Hello"; // Declaring a variable
58
+ print greeting + ", " + "world!"; // ... Playing with concatenation
59
+ LOX_END
60
+ end
56
61
 
57
62
  it 'should evaluate core data types' do
58
63
  result = subject.evaluate('true; // Not false')
@@ -259,6 +264,15 @@ module Loxxy
259
264
  expect { subject.evaluate('var iAmNil;') }.not_to raise_error
260
265
  end
261
266
 
267
+ it 'should accept variable mention' do
268
+ program = <<-LOX_END
269
+ var foo = "bar";
270
+ print foo;
271
+ LOX_END
272
+ expect { subject.evaluate(program) }.not_to raise_error
273
+ expect(sample_cfg[:ostream].string).to eq('bar')
274
+ end
275
+
262
276
  it 'should print the hello world message' do
263
277
  expect { subject.evaluate(hello_world) }.not_to raise_error
264
278
  expect(sample_cfg[:ostream].string).to eq('Hello, world!')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: loxxy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.21
4
+ version: 0.0.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitri Geshef
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-16 00:00:00.000000000 Z
11
+ date: 2021-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rley
@@ -96,8 +96,10 @@ files:
96
96
  - lib/loxxy/ast/lox_node.rb
97
97
  - lib/loxxy/ast/lox_noop_expr.rb
98
98
  - lib/loxxy/ast/lox_print_stmt.rb
99
+ - lib/loxxy/ast/lox_seq_decl.rb
99
100
  - lib/loxxy/ast/lox_unary_expr.rb
100
101
  - lib/loxxy/ast/lox_var_stmt.rb
102
+ - lib/loxxy/ast/lox_variable_expr.rb
101
103
  - lib/loxxy/back_end/engine.rb
102
104
  - lib/loxxy/back_end/entry.rb
103
105
  - lib/loxxy/back_end/environment.rb