@@ -25,6 +25,10 @@ type operator struct {
2525 associativity associativity
2626}
2727
28+ type builtin struct {
29+ arity int
30+ }
31+
2832var unaryOperators = map [string ]operator {
2933 "not" : {50 , left },
3034 "!" : {50 , left },
@@ -58,14 +62,14 @@ var binaryOperators = map[string]operator{
5862 "**" : {70 , right },
5963}
6064
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 } ,
6973}
7074
7175type parser struct {
@@ -95,7 +99,7 @@ func Parse(input string) (*Tree, error) {
9599
96100 node := p .parseExpression (0 )
97101
98- if ! p .isEOF ( ) {
102+ if ! p .current . Is ( EOF ) {
99103 p .error ("unexpected token %v" , p .current )
100104 }
101105
@@ -121,7 +125,8 @@ func (p *parser) error(format string, args ...interface{}) {
121125func (p * parser ) next () {
122126 p .pos ++
123127 if p .pos >= len (p .tokens ) {
124- panic ("unexpected end of expression" )
128+ p .error ("unexpected end of expression" )
129+ return
125130 }
126131 p .current = p .tokens [p .pos ]
127132}
@@ -134,10 +139,6 @@ func (p *parser) expect(kind Kind, values ...string) {
134139 p .error ("unexpected token %v" , p .current )
135140}
136141
137- func (p * parser ) isEOF () bool {
138- return p .current .Is (EOF )
139- }
140-
141142// parse functions
142143
143144func (p * parser ) parseExpression (precedence int ) Node {
@@ -216,6 +217,17 @@ func (p *parser) parsePrimary() Node {
216217 return p .parsePostfixExpression (expr )
217218 }
218219
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+
219231 return p .parsePrimaryExpression ()
220232}
221233
@@ -305,18 +317,54 @@ func (p *parser) parsePrimaryExpression() Node {
305317func (p * parser ) parseIdentifierExpression (token Token ) Node {
306318 var node Node
307319 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+ }
311341 } 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+ }
313348 }
314349 } else {
315350 node = & IdentifierNode {Base : Loc (token .Location ), Value : token .Value }
316351 }
317352 return node
318353}
319354
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+
320368func (p * parser ) parseArrayExpression (token Token ) Node {
321369 nodes := p .parseList ("[" , "]" )
322370 return & ArrayNode {Base : Loc (token .Location ), Nodes : nodes }
@@ -403,10 +451,22 @@ func (p *parser) parsePostfixExpression(node Node) Node {
403451 } else if token .Value == "[" {
404452 p .next ()
405453 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+ }
410470 }
411471 p .expect (Bracket , "]" )
412472 } else {
0 commit comments