@@ -10,11 +10,12 @@ import (
10
10
type parser struct {
11
11
tokens []scanner.Token
12
12
current int
13
+ fdepth int
13
14
err error
14
15
}
15
16
16
17
func NewParser (tokens []scanner.Token ) * parser {
17
- return & parser {tokens , 0 , nil }
18
+ return & parser {tokens , 0 , 0 , nil }
18
19
}
19
20
20
21
func (p * parser ) Parse () ([]Stmt , error ) {
@@ -34,10 +35,14 @@ func (p *parser) declaration() Stmt {
34
35
return p .varDeclaration ()
35
36
}
36
37
38
+ if p .match (scanner .FUN ) {
39
+ return p .funDeclaration ("function" )
40
+ }
41
+
37
42
return p .statement ()
38
43
}
39
44
40
- func (p * parser ) varDeclaration () Stmt {
45
+ func (p * parser ) varDeclaration () * VarStmt {
41
46
if ! p .match (scanner .IDENTIFIER ) {
42
47
panic (fault .NewFault (p .tokens [p .current ].Line , "expected variable name" ))
43
48
}
@@ -55,6 +60,51 @@ func (p *parser) varDeclaration() Stmt {
55
60
return & VarStmt {& name , initializer }
56
61
}
57
62
63
+ func (p * parser ) funDeclaration (kind string ) * FunStmt {
64
+ if ! p .match (scanner .IDENTIFIER ) {
65
+ message := fmt .Sprintf ("expected %s name" , kind )
66
+ panic (fault .NewFault (p .tokens [p .current ].Line , message ))
67
+ }
68
+ name := p .tokens [p .current - 1 ]
69
+
70
+ if ! p .match (scanner .LEFT_PAREN ) {
71
+ message := fmt .Sprintf ("expected '(' after %s name" , kind )
72
+ panic (fault .NewFault (p .tokens [p .current ].Line , message ))
73
+ }
74
+
75
+ params := []* scanner.Token {}
76
+ if p .tokens [p .current ].TokenType != scanner .RIGHT_PAREN && p .tokens [p .current ].TokenType != scanner .EOF {
77
+ if ! p .match (scanner .IDENTIFIER ) {
78
+ message := fmt .Sprintf ("expected parameter name at %s" , p .tokens [p .current ].Lexeme )
79
+ panic (fault .NewFault (p .tokens [p .current ].Line , message ))
80
+ }
81
+ params = append (params , & p .tokens [p .current - 1 ])
82
+ for p .match (scanner .COMMA ) {
83
+ if ! p .match (scanner .IDENTIFIER ) {
84
+ message := fmt .Sprintf ("expected parameter name at %s" , p .tokens [p .current ].Lexeme )
85
+ panic (fault .NewFault (p .tokens [p .current ].Line , message ))
86
+ }
87
+ params = append (params , & p .tokens [p .current - 1 ])
88
+ if len (params ) > 255 {
89
+ panic (fault .NewFault (p .tokens [p .current ].Line , "cannot have more than 255 parameters" ))
90
+ }
91
+ }
92
+ }
93
+
94
+ if ! p .match (scanner .RIGHT_PAREN ) {
95
+ panic (fault .NewFault (p .tokens [p .current ].Line , "expected ')' after parameter list" ))
96
+ }
97
+
98
+ if ! p .match (scanner .LEFT_BRACE ) {
99
+ message := fmt .Sprintf ("expected '{' before %s body" , kind )
100
+ panic (fault .NewFault (p .tokens [p .current ].Line , message ))
101
+ }
102
+
103
+ p .fdepth ++
104
+ defer func () { p .fdepth -- }()
105
+ return & FunStmt {& name , params , p .blockStatement ()}
106
+ }
107
+
58
108
func (p * parser ) statement () Stmt {
59
109
if p .match (scanner .PRINT ) {
60
110
return p .printStatement ()
@@ -73,13 +123,17 @@ func (p *parser) statement() Stmt {
73
123
}
74
124
75
125
if p .match (scanner .LEFT_BRACE ) {
76
- return & BlockStmt {p .block ()}
126
+ return p .blockStatement ()
127
+ }
128
+
129
+ if p .match (scanner .RETURN ) {
130
+ return p .returnStatement ()
77
131
}
78
132
79
133
return p .exprStatement ()
80
134
}
81
135
82
- func (p * parser ) printStatement () Stmt {
136
+ func (p * parser ) printStatement () * PrintStmt {
83
137
expr := p .expression ()
84
138
85
139
if ! p .match (scanner .SEMICOLON ) {
@@ -89,7 +143,7 @@ func (p *parser) printStatement() Stmt {
89
143
return & PrintStmt {expr }
90
144
}
91
145
92
- func (p * parser ) ifStatement () Stmt {
146
+ func (p * parser ) ifStatement () * IfStmt {
93
147
if ! p .match (scanner .LEFT_PAREN ) {
94
148
panic (fault .NewFault (p .tokens [p .current ].Line , "expected '(' after if" ))
95
149
}
@@ -123,15 +177,15 @@ func (p *parser) forStatement() Stmt {
123
177
}
124
178
125
179
var condition Expr
126
- if p .tokens [p .current ].TokenType != scanner .EOF && p .tokens [p .current ].TokenType != scanner .SEMICOLON {
180
+ if p .tokens [p .current ].TokenType != scanner .SEMICOLON && p .tokens [p .current ].TokenType != scanner .EOF {
127
181
condition = p .expression ()
128
182
}
129
183
if ! p .match (scanner .SEMICOLON ) {
130
184
panic (fault .NewFault (p .tokens [p .current ].Line , "expected ';' after conditional expression" ))
131
185
}
132
186
133
187
var increment Expr
134
- if p .tokens [p .current ].TokenType != scanner .EOF && p .tokens [p .current ].TokenType != scanner .RIGHT_PAREN {
188
+ if p .tokens [p .current ].TokenType != scanner .RIGHT_PAREN && p .tokens [p .current ].TokenType != scanner .EOF {
135
189
increment = p .expression ()
136
190
}
137
191
if ! p .match (scanner .RIGHT_PAREN ) {
@@ -156,7 +210,7 @@ func (p *parser) forStatement() Stmt {
156
210
return body
157
211
}
158
212
159
- func (p * parser ) whileStatement () Stmt {
213
+ func (p * parser ) whileStatement () * WhileStmt {
160
214
if ! p .match (scanner .LEFT_PAREN ) {
161
215
panic (fault .NewFault (p .tokens [p .current ].Line , "expected '(' after while" ))
162
216
}
@@ -169,21 +223,21 @@ func (p *parser) whileStatement() Stmt {
169
223
return & WhileStmt {condition , p .statement ()}
170
224
}
171
225
172
- func (p * parser ) block () [] Stmt {
226
+ func (p * parser ) blockStatement () * BlockStmt {
173
227
stmts := []Stmt {}
174
228
175
- for p .tokens [p .current ].TokenType != scanner .EOF && p .tokens [p .current ].TokenType != scanner .RIGHT_BRACE {
229
+ for p .tokens [p .current ].TokenType != scanner .RIGHT_BRACE && p .tokens [p .current ].TokenType != scanner .EOF {
176
230
stmts = append (stmts , p .declaration ())
177
231
}
178
232
179
233
if ! p .match (scanner .RIGHT_BRACE ) {
180
234
panic (fault .NewFault (p .tokens [p .current ].Line , "expected '}' after block" ))
181
235
}
182
236
183
- return stmts
237
+ return & BlockStmt { stmts }
184
238
}
185
239
186
- func (p * parser ) exprStatement () Stmt {
240
+ func (p * parser ) exprStatement () * ExprStmt {
187
241
expr := p .expression ()
188
242
189
243
if ! p .match (scanner .SEMICOLON ) {
@@ -193,6 +247,24 @@ func (p *parser) exprStatement() Stmt {
193
247
return & ExprStmt {expr }
194
248
}
195
249
250
+ func (p * parser ) returnStatement () * ReturnStmt {
251
+ keyword := p .tokens [p .current - 1 ]
252
+ if p .fdepth == 0 {
253
+ panic (fault .NewFault (keyword .Line , "cannot return outside of a function" ))
254
+ }
255
+
256
+ var value Expr
257
+ if p .tokens [p .current ].TokenType != scanner .SEMICOLON && p .tokens [p .current ].TokenType != scanner .EOF {
258
+ value = p .expression ()
259
+ }
260
+
261
+ if ! p .match (scanner .SEMICOLON ) {
262
+ panic (fault .NewFault (p .tokens [p .current ].Line , "expected ';' after return statement" ))
263
+ }
264
+
265
+ return & ReturnStmt {& keyword , value }
266
+ }
267
+
196
268
func (p * parser ) expression () Expr {
197
269
return p .assignment ()
198
270
}
@@ -293,7 +365,37 @@ func (p *parser) unary() Expr {
293
365
return & UnaryExpr {& operator , right }
294
366
}
295
367
296
- return p .primary ()
368
+ return p .call ()
369
+ }
370
+
371
+ func (p * parser ) call () Expr {
372
+ expr := p .primary ()
373
+
374
+ for p .match (scanner .LEFT_PAREN ) {
375
+ args , paren := p .arguments ()
376
+ expr = & CallExpr {expr , paren , args }
377
+ }
378
+
379
+ return expr
380
+ }
381
+
382
+ func (p * parser ) arguments () ([]Expr , scanner.Token ) {
383
+ args := []Expr {}
384
+ if p .tokens [p .current ].TokenType != scanner .RIGHT_PAREN && p .tokens [p .current ].TokenType != scanner .EOF {
385
+ args = append (args , p .expression ())
386
+ for p .match (scanner .COMMA ) {
387
+ args = append (args , p .expression ())
388
+ if len (args ) > 255 {
389
+ panic (fault .NewFault (p .tokens [p .current ].Line , "cannot have more than 255 arguments" ))
390
+ }
391
+ }
392
+ }
393
+
394
+ if ! p .match (scanner .RIGHT_PAREN ) {
395
+ panic (fault .NewFault (p .tokens [p .current ].Line , "expected ')' after argument list" ))
396
+ }
397
+
398
+ return args , p .tokens [p .current - 1 ]
297
399
}
298
400
299
401
func (p * parser ) primary () Expr {
@@ -321,26 +423,25 @@ func (p *parser) primary() Expr {
321
423
322
424
if p .match (scanner .LEFT_PAREN ) {
323
425
e := p .expression ()
324
- if p . tokens [ p . current ]. TokenType != scanner .RIGHT_PAREN {
325
- message := fmt .Sprintf ("expected ')' after \" %s \" " , p .tokens [p .current ].Lexeme )
426
+ if ! p . match ( scanner .RIGHT_PAREN ) {
427
+ message := fmt .Sprintf ("expected ')' after '%s'" , p .tokens [p .current - 1 ].Lexeme )
326
428
panic (fault .NewFault (p .tokens [p .current ].Line , message ))
327
429
}
328
- p .current ++
329
430
return & GroupingExpr {e }
330
431
}
331
432
332
- message := fmt .Sprintf ("expected expression at \" %s \" " , p .tokens [p .current ].Lexeme )
433
+ message := fmt .Sprintf ("expected expression at '%s' " , p .tokens [p .current ].Lexeme )
333
434
panic (fault .NewFault (p .tokens [p .current ].Line , message ))
334
435
}
335
436
336
437
func (p * parser ) match (types ... int ) bool {
337
- if p .tokens [p .current ].TokenType == scanner .EOF {
438
+ currentType := p .tokens [p .current ].TokenType
439
+ if currentType == scanner .EOF {
338
440
return false
339
441
}
340
442
341
- actualType := p .tokens [p .current ].TokenType
342
443
for _ , tokenType := range types {
343
- if actualType == tokenType {
444
+ if currentType == tokenType {
344
445
p .current ++
345
446
return true
346
447
}
@@ -386,4 +487,4 @@ func (p *parser) synchronize() {
386
487
p .current ++
387
488
}
388
489
}
389
- }
490
+ }
0 commit comments