@@ -25,6 +25,10 @@ type operator struct {
25
25
associativity associativity
26
26
}
27
27
28
+ type builtin struct {
29
+ arity int
30
+ }
31
+
28
32
var unaryOperators = map [string ]operator {
29
33
"not" : {50 , left },
30
34
"!" : {50 , left },
@@ -58,14 +62,14 @@ var binaryOperators = map[string]operator{
58
62
"**" : {70 , right },
59
63
}
60
64
61
- var builtins = map [string ]bool {
62
- "len" : true ,
63
- "all" : true ,
64
- "none" : true ,
65
- "any" : true ,
66
- "one" : true ,
67
- "filter" : true ,
68
- "map" : true ,
65
+ var builtins = map [string ]builtin {
66
+ "len" : { 1 } ,
67
+ "all" : { 2 } ,
68
+ "none" : { 2 } ,
69
+ "any" : { 2 } ,
70
+ "one" : { 2 } ,
71
+ "filter" : { 2 } ,
72
+ "map" : { 2 } ,
69
73
}
70
74
71
75
type parser struct {
@@ -95,7 +99,7 @@ func Parse(input string) (*Tree, error) {
95
99
96
100
node := p .parseExpression (0 )
97
101
98
- if ! p .isEOF ( ) {
102
+ if ! p .current . Is ( EOF ) {
99
103
p .error ("unexpected token %v" , p .current )
100
104
}
101
105
@@ -121,7 +125,8 @@ func (p *parser) error(format string, args ...interface{}) {
121
125
func (p * parser ) next () {
122
126
p .pos ++
123
127
if p .pos >= len (p .tokens ) {
124
- panic ("unexpected end of expression" )
128
+ p .error ("unexpected end of expression" )
129
+ return
125
130
}
126
131
p .current = p .tokens [p .pos ]
127
132
}
@@ -134,10 +139,6 @@ func (p *parser) expect(kind Kind, values ...string) {
134
139
p .error ("unexpected token %v" , p .current )
135
140
}
136
141
137
- func (p * parser ) isEOF () bool {
138
- return p .current .Is (EOF )
139
- }
140
-
141
142
// parse functions
142
143
143
144
func (p * parser ) parseExpression (precedence int ) Node {
@@ -216,6 +217,17 @@ func (p *parser) parsePrimary() Node {
216
217
return p .parsePostfixExpression (expr )
217
218
}
218
219
220
+ if token .Is (Operator , "#" ) {
221
+ p .next ()
222
+ node := & PointerNode {Base : Loc (token .Location )}
223
+ return p .parsePostfixExpression (node )
224
+ }
225
+
226
+ if token .Is (Operator , "." ) {
227
+ node := & PointerNode {Base : Loc (token .Location )}
228
+ return p .parsePostfixExpression (node )
229
+ }
230
+
219
231
return p .parsePrimaryExpression ()
220
232
}
221
233
@@ -305,18 +317,54 @@ func (p *parser) parsePrimaryExpression() Node {
305
317
func (p * parser ) parseIdentifierExpression (token Token ) Node {
306
318
var node Node
307
319
if p .current .Is (Bracket , "(" ) {
308
- arguments := p .parseArguments ()
309
- if _ , ok := builtins [token .Value ]; ok {
310
- node = & BuiltinNode {Base : Loc (token .Location ), Name : token .Value , Arguments : arguments }
320
+ var arguments []Node
321
+
322
+ if b , ok := builtins [token .Value ]; ok {
323
+ p .expect (Bracket , "(" )
324
+ // TODO: Add builtins signatures.
325
+ if b .arity == 1 {
326
+ arguments = make ([]Node , 1 )
327
+ arguments [0 ] = p .parseExpression (0 )
328
+ } else if b .arity == 2 {
329
+ arguments = make ([]Node , 2 )
330
+ arguments [0 ] = p .parseExpression (0 )
331
+ p .expect (Operator , "," )
332
+ arguments [1 ] = p .parseClosure ()
333
+ }
334
+ p .expect (Bracket , ")" )
335
+
336
+ node = & BuiltinNode {
337
+ Base : Loc (token .Location ),
338
+ Name : token .Value ,
339
+ Arguments : arguments ,
340
+ }
311
341
} else {
312
- node = & FunctionNode {Base : Loc (token .Location ), Name : token .Value , Arguments : arguments }
342
+ arguments = p .parseArguments ()
343
+ node = & FunctionNode {
344
+ Base : Loc (token .Location ),
345
+ Name : token .Value ,
346
+ Arguments : arguments ,
347
+ }
313
348
}
314
349
} else {
315
350
node = & IdentifierNode {Base : Loc (token .Location ), Value : token .Value }
316
351
}
317
352
return node
318
353
}
319
354
355
+ func (p * parser ) parseClosure () Node {
356
+ token := p .current
357
+ p .expect (Bracket , "{" )
358
+
359
+ node := p .parseExpression (0 )
360
+
361
+ p .expect (Bracket , "}" )
362
+ return & ClosureNode {
363
+ Base : Loc (token .Location ),
364
+ Node : node ,
365
+ }
366
+ }
367
+
320
368
func (p * parser ) parseArrayExpression (token Token ) Node {
321
369
nodes := p .parseList ("[" , "]" )
322
370
return & ArrayNode {Base : Loc (token .Location ), Nodes : nodes }
@@ -403,10 +451,22 @@ func (p *parser) parsePostfixExpression(node Node) Node {
403
451
} else if token .Value == "[" {
404
452
p .next ()
405
453
arg := p .parseExpression (0 )
406
- node = & IndexNode {
407
- Base : Loc (token .Location ),
408
- Node : node ,
409
- Index : arg ,
454
+ if p .current .Is (Operator , ":" ) {
455
+ p .next ()
456
+ from := arg
457
+ to := p .parseExpression (0 )
458
+ node = & SliceNode {
459
+ Base : Loc (p .current .Location ),
460
+ Node : node ,
461
+ From : from ,
462
+ To : to ,
463
+ }
464
+ } else {
465
+ node = & IndexNode {
466
+ Base : Loc (token .Location ),
467
+ Node : node ,
468
+ Index : arg ,
469
+ }
410
470
}
411
471
p .expect (Bracket , "]" )
412
472
} else {
0 commit comments