Skip to content

Commit f149a7a

Browse files
committed
Parse variables
1 parent 5cbd19b commit f149a7a

File tree

2 files changed

+39
-8
lines changed

2 files changed

+39
-8
lines changed

lib/expression_parser.rb

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
require_relative 'vm_writer'
22

33
class ExpressionParser
4+
Number = Struct.new(:value) do
5+
def emit(vm_writer, _symbol_table)
6+
vm_writer.write_push('constant', value)
7+
end
8+
end
9+
10+
Variable = Struct.new(:value) do
11+
def emit(vm_writer, symbol_table)
12+
vm_writer.write_push(symbol_table.kind_of(value), symbol_table.index_of(value))
13+
end
14+
end
15+
416
attr_reader :tokenizer
517
private :tokenizer
618

@@ -9,12 +21,15 @@ def initialize(tokenizer)
921
end
1022

1123
def parse
12-
number = tokenizer.int_val
24+
case tokenizer.token_type
25+
when Tokenizer::INT_CONST
26+
number = tokenizer.int_val
27+
28+
Number.new(number)
29+
else
30+
identifier = tokenizer.identifier
1331

14-
Struct.new(:value) {
15-
def emit(vm_writer)
16-
vm_writer.write_push('constant', value)
17-
end
18-
}.new(number)
32+
Variable.new(identifier)
33+
end
1934
end
2035
end

spec/unit/expression_parser_spec.rb

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
require 'tokenizer'
22
require 'expression_parser'
3+
require 'symbol_table'
34

45
RSpec.describe ExpressionParser do
56
it 'emits VM code for numeric constants' do
@@ -9,7 +10,7 @@
910
result = ExpressionParser.new(tokenizer).parse
1011
output = StringIO.new
1112
vm_writer = VMWriter.new(output)
12-
result.emit(vm_writer)
13+
result.emit(vm_writer, SymbolTable.new)
1314

1415
expect(output.string).to eq("push constant 1\n")
1516
end
@@ -21,8 +22,23 @@
2122
result = ExpressionParser.new(tokenizer).parse
2223
output = StringIO.new
2324
vm_writer = VMWriter.new(output)
24-
result.emit(vm_writer)
25+
result.emit(vm_writer, SymbolTable.new)
2526

2627
expect(output.string).to eq("push constant 2\n")
2728
end
29+
30+
it 'emits VM code for variables' do
31+
tokenizer = Tokenizer.new('a')
32+
tokenizer.advance
33+
34+
symbol_table = SymbolTable.new
35+
symbol_table.define('a', :int, :static)
36+
37+
result = ExpressionParser.new(tokenizer).parse
38+
output = StringIO.new
39+
vm_writer = VMWriter.new(output)
40+
result.emit(vm_writer, symbol_table)
41+
42+
expect(output.string).to eq("push static 0\n")
43+
end
2844
end

0 commit comments

Comments
 (0)