@@ -43,6 +43,10 @@ const (
43
43
tokenRightCurly
44
44
tokenIndefinite
45
45
tokenLongForm
46
+ tokenComma
47
+ tokenLeftParen
48
+ tokenRightParen
49
+ tokenWord
46
50
tokenEOF
47
51
)
48
52
@@ -78,10 +82,11 @@ var (
78
82
type scanner struct {
79
83
text string
80
84
pos position
85
+ vars map [string ][]byte
81
86
}
82
87
83
88
func newScanner (text string ) * scanner {
84
- return & scanner {text : text , pos : position {Line : 1 }}
89
+ return & scanner {text : text , pos : position {Line : 1 }, vars : make ( map [ string ][] byte ) }
85
90
}
86
91
87
92
func (s * scanner ) parseEscapeSequence () (rune , error ) {
@@ -274,6 +279,15 @@ again:
274
279
case '}' :
275
280
s .advance ()
276
281
return token {Kind : tokenRightCurly , Pos : s .pos }, nil
282
+ case ',' :
283
+ s .advance ()
284
+ return token {Kind : tokenComma , Pos : s .pos }, nil
285
+ case '(' :
286
+ s .advance ()
287
+ return token {Kind : tokenLeftParen , Pos : s .pos }, nil
288
+ case ')' :
289
+ s .advance ()
290
+ return token {Kind : tokenRightParen , Pos : s .pos }, nil
277
291
case '"' :
278
292
return s .parseQuotedString ()
279
293
case 'u' :
@@ -366,7 +380,7 @@ again:
366
380
loop:
367
381
for ! s .isEOF () {
368
382
switch s .text [s .pos .Offset ] {
369
- case ' ' , '\t' , '\n' , '\r' , '{' , '}' , '[' , ']' , '`' , '"' , '#' :
383
+ case ' ' , '\t' , '\n' , '\r' , ',' , '(' , ')' , ' {' , '}' , '[' , ']' , '`' , '"' , '#' :
370
384
break loop
371
385
default :
372
386
s .advance ()
@@ -431,7 +445,7 @@ loop:
431
445
return token {Kind : tokenLongForm , Length : l }, nil
432
446
}
433
447
434
- return token {}, fmt . Errorf ( "unrecognized symbol %q" , symbol )
448
+ return token {Kind : tokenWord , Value : [] byte ( symbol ), Pos : s . pos }, nil
435
449
}
436
450
437
451
func (s * scanner ) isEOF () bool {
@@ -469,24 +483,32 @@ func (s *scanner) consumeUpTo(b byte) (string, bool) {
469
483
return "" , false
470
484
}
471
485
472
- func asciiToDERImpl (scanner * scanner , leftCurly * token ) ([]byte , error ) {
486
+ // asciiToDERImpl consumes tokens from |scanner| and returns the concatenation
487
+ // of their byte values, as well as every token processed.
488
+ func asciiToDERImpl (scanner * scanner , left * token ) ([]byte , []token , error ) {
473
489
var out []byte
490
+ var tokens []token
474
491
var lengthModifier * token
492
+ var word * token
475
493
for {
476
494
token , err := scanner .Next ()
477
495
if err != nil {
478
- return nil , err
496
+ return nil , nil , err
479
497
}
498
+ tokens = append (tokens , token )
480
499
if lengthModifier != nil && token .Kind != tokenLeftCurly {
481
- return nil , & parseError {lengthModifier .Pos , errors .New ("length modifier was not followed by '{'" )}
500
+ return nil , nil , & parseError {lengthModifier .Pos , errors .New ("length modifier was not followed by '{'" )}
501
+ }
502
+ if word != nil && token .Kind != tokenLeftParen {
503
+ return nil , nil , & parseError {word .Pos , fmt .Errorf ("unrecognized symbol %q" , string (token .Value ))}
482
504
}
483
505
switch token .Kind {
484
506
case tokenBytes :
485
507
out = append (out , token .Value ... )
486
508
case tokenLeftCurly :
487
- child , err := asciiToDERImpl (scanner , & token )
509
+ child , _ , err := asciiToDERImpl (scanner , & token )
488
510
if err != nil {
489
- return nil , err
511
+ return nil , nil , err
490
512
}
491
513
var lengthOverride int
492
514
if lengthModifier != nil {
@@ -504,22 +526,68 @@ func asciiToDERImpl(scanner *scanner, leftCurly *token) ([]byte, error) {
504
526
out , err = appendLength (out , len (child ), lengthOverride )
505
527
if err != nil {
506
528
// appendLength may fail if the lengthModifier was incompatible.
507
- return nil , & parseError {lengthModifier .Pos , err }
529
+ return nil , tokens , & parseError {lengthModifier .Pos , err }
508
530
}
509
531
out = append (out , child ... )
510
532
lengthModifier = nil
533
+ case tokenLeftParen :
534
+ if word == nil {
535
+ return nil , tokens , & parseError {token .Pos , errors .New ("missing function name" )}
536
+ }
537
+ var args [][]byte
538
+ argLoop:
539
+ for {
540
+ arg , prev , err := asciiToDERImpl (scanner , & token )
541
+ if err != nil {
542
+ return nil , tokens , err
543
+ }
544
+ args = append (args , arg )
545
+ lastToken := prev [len (prev )- 1 ]
546
+ switch lastToken .Kind {
547
+ case tokenComma :
548
+ if len (prev ) < 2 {
549
+ return nil , nil , & parseError {lastToken .Pos , errors .New ("function arguments cannot be empty" )}
550
+ }
551
+ case tokenRightParen :
552
+ if len (prev ) < 2 {
553
+ // Actually foo(), so the argument list is nil.
554
+ args = nil
555
+ }
556
+ break argLoop
557
+ default :
558
+ return nil , nil , & parseError {lastToken .Pos , errors .New ("expected ',' or ')'" )}
559
+ }
560
+ }
561
+ bytes , err := executeBuiltin (scanner , string (word .Value ), args )
562
+ if err != nil {
563
+ return nil , nil , err
564
+ }
565
+ word = nil
566
+ out = append (out , bytes ... )
511
567
case tokenRightCurly :
512
- if leftCurly != nil {
513
- return out , nil
568
+ if left != nil && left .Kind == tokenLeftCurly {
569
+ return out , tokens , nil
570
+ }
571
+ return nil , nil , & parseError {token .Pos , errors .New ("unmatched '}'" )}
572
+ case tokenRightParen :
573
+ if left != nil && left .Kind == tokenLeftParen {
574
+ return out , tokens , nil
514
575
}
515
- return nil , & parseError {token .Pos , errors .New ("unmatched '} '" )}
576
+ return nil , nil , & parseError {token .Pos , errors .New ("unmatched '( '" )}
516
577
case tokenLongForm , tokenIndefinite :
517
578
lengthModifier = & token
579
+ case tokenComma :
580
+ return out , tokens , nil
581
+ case tokenWord :
582
+ word = & token
518
583
case tokenEOF :
519
- if leftCurly == nil {
520
- return out , nil
584
+ if left == nil {
585
+ return out , tokens , nil
586
+ } else if left .Kind == tokenLeftCurly {
587
+ return nil , nil , & parseError {left .Pos , errors .New ("unmatched '{'" )}
588
+ } else {
589
+ return nil , nil , & parseError {left .Pos , errors .New ("unmatched '('" )}
521
590
}
522
- return nil , & parseError {leftCurly .Pos , errors .New ("unmatched '{'" )}
523
591
default :
524
592
panic (token )
525
593
}
@@ -528,5 +596,6 @@ func asciiToDERImpl(scanner *scanner, leftCurly *token) ([]byte, error) {
528
596
529
597
func asciiToDER (input string ) ([]byte , error ) {
530
598
scanner := newScanner (input )
531
- return asciiToDERImpl (scanner , nil )
599
+ bytes , _ , err := asciiToDERImpl (scanner , nil )
600
+ return bytes , err
532
601
}
0 commit comments