File tree Expand file tree Collapse file tree 3 files changed +67
-2
lines changed Expand file tree Collapse file tree 3 files changed +67
-2
lines changed Original file line number Diff line number Diff line change @@ -13,6 +13,14 @@ def emit(vm_writer, symbol_table)
13
13
end
14
14
end
15
15
16
+ BinaryOperation = Struct . new ( :operation , :left_node , :right_node ) do
17
+ def emit ( vm_writer , symbol_table )
18
+ left_node . emit ( vm_writer , symbol_table )
19
+ right_node . emit ( vm_writer , symbol_table )
20
+ vm_writer . write_operation ( operation )
21
+ end
22
+ end
23
+
16
24
attr_reader :tokenizer
17
25
private :tokenizer
18
26
@@ -21,15 +29,30 @@ def initialize(tokenizer)
21
29
end
22
30
23
31
def parse
24
- case tokenizer . token_type
32
+ left_node = case tokenizer . token_type
25
33
when Tokenizer ::INT_CONST
26
34
number = tokenizer . int_val
27
35
28
36
Number . new ( number )
29
- else
37
+ when Tokenizer :: IDENTIFIER
30
38
identifier = tokenizer . identifier
31
39
32
40
Variable . new ( identifier )
33
41
end
42
+
43
+ return left_node unless tokenizer . has_more_tokens?
44
+
45
+ tokenizer . advance
46
+
47
+ if %w[ + - * / & | < > = ] . include? ( tokenizer . symbol )
48
+ operation = tokenizer . symbol
49
+ tokenizer . advance
50
+
51
+ right_node = parse
52
+
53
+ BinaryOperation . new ( operation , left_node , right_node )
54
+ else
55
+ left_node
56
+ end
34
57
end
35
58
end
Original file line number Diff line number Diff line change @@ -14,6 +14,10 @@ def write_pop(segment, index)
14
14
io . puts ( "pop #{ segment } #{ index } " )
15
15
end
16
16
17
+ def write_operation ( operation )
18
+ write_arithmetic ( { '+' => 'add' } . fetch ( operation ) )
19
+ end
20
+
17
21
def write_arithmetic ( command )
18
22
io . puts ( command )
19
23
end
Original file line number Diff line number Diff line change 41
41
42
42
expect ( output . string ) . to eq ( "push static 0\n " )
43
43
end
44
+
45
+ it 'emits VM code for binary expressions' do
46
+ tokenizer = Tokenizer . new ( '1 + 1' )
47
+ tokenizer . advance
48
+
49
+ symbol_table = SymbolTable . new
50
+
51
+ result = ExpressionParser . new ( tokenizer ) . parse
52
+ output = StringIO . new
53
+ vm_writer = VMWriter . new ( output )
54
+ result . emit ( vm_writer , symbol_table )
55
+
56
+ expect ( output . string ) . to eq ( <<-VM )
57
+ push constant 1
58
+ push constant 1
59
+ add
60
+ VM
61
+ end
62
+
63
+ it 'emits VM code for compound binary expressions' do
64
+ tokenizer = Tokenizer . new ( '1 + 2 + 3' )
65
+ tokenizer . advance
66
+
67
+ symbol_table = SymbolTable . new
68
+
69
+ result = ExpressionParser . new ( tokenizer ) . parse
70
+ output = StringIO . new
71
+ vm_writer = VMWriter . new ( output )
72
+ result . emit ( vm_writer , symbol_table )
73
+
74
+ expect ( output . string ) . to eq ( <<-VM )
75
+ push constant 1
76
+ push constant 2
77
+ push constant 3
78
+ add
79
+ add
80
+ VM
81
+ end
44
82
end
You can’t perform that action at this time.
0 commit comments