@@ -43,6 +43,10 @@ const (
4343 tokenRightCurly
4444 tokenIndefinite
4545 tokenLongForm
46+ tokenComma
47+ tokenLeftParen
48+ tokenRightParen
49+ tokenWord
4650 tokenEOF
4751)
4852
@@ -78,10 +82,11 @@ var (
7882type scanner struct {
7983 text string
8084 pos position
85+ vars map [string ][]byte
8186}
8287
8388func 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 ) }
8590}
8691
8792func (s * scanner ) parseEscapeSequence () (rune , error ) {
@@ -274,6 +279,15 @@ again:
274279 case '}' :
275280 s .advance ()
276281 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
277291 case '"' :
278292 return s .parseQuotedString ()
279293 case 'u' :
@@ -366,7 +380,7 @@ again:
366380loop:
367381 for ! s .isEOF () {
368382 switch s .text [s .pos .Offset ] {
369- case ' ' , '\t' , '\n' , '\r' , '{' , '}' , '[' , ']' , '`' , '"' , '#' :
383+ case ' ' , '\t' , '\n' , '\r' , ',' , '(' , ')' , ' {' , '}' , '[' , ']' , '`' , '"' , '#' :
370384 break loop
371385 default :
372386 s .advance ()
@@ -431,7 +445,7 @@ loop:
431445 return token {Kind : tokenLongForm , Length : l }, nil
432446 }
433447
434- return token {}, fmt . Errorf ( "unrecognized symbol %q" , symbol )
448+ return token {Kind : tokenWord , Value : [] byte ( symbol ), Pos : s . pos }, nil
435449}
436450
437451func (s * scanner ) isEOF () bool {
@@ -469,24 +483,32 @@ func (s *scanner) consumeUpTo(b byte) (string, bool) {
469483 return "" , false
470484}
471485
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 ) {
473489 var out []byte
490+ var tokens []token
474491 var lengthModifier * token
492+ var word * token
475493 for {
476494 token , err := scanner .Next ()
477495 if err != nil {
478- return nil , err
496+ return nil , nil , err
479497 }
498+ tokens = append (tokens , token )
480499 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 ))}
482504 }
483505 switch token .Kind {
484506 case tokenBytes :
485507 out = append (out , token .Value ... )
486508 case tokenLeftCurly :
487- child , err := asciiToDERImpl (scanner , & token )
509+ child , _ , err := asciiToDERImpl (scanner , & token )
488510 if err != nil {
489- return nil , err
511+ return nil , nil , err
490512 }
491513 var lengthOverride int
492514 if lengthModifier != nil {
@@ -504,22 +526,68 @@ func asciiToDERImpl(scanner *scanner, leftCurly *token) ([]byte, error) {
504526 out , err = appendLength (out , len (child ), lengthOverride )
505527 if err != nil {
506528 // appendLength may fail if the lengthModifier was incompatible.
507- return nil , & parseError {lengthModifier .Pos , err }
529+ return nil , tokens , & parseError {lengthModifier .Pos , err }
508530 }
509531 out = append (out , child ... )
510532 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 ... )
511567 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
514575 }
515- return nil , & parseError {token .Pos , errors .New ("unmatched '} '" )}
576+ return nil , nil , & parseError {token .Pos , errors .New ("unmatched '( '" )}
516577 case tokenLongForm , tokenIndefinite :
517578 lengthModifier = & token
579+ case tokenComma :
580+ return out , tokens , nil
581+ case tokenWord :
582+ word = & token
518583 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 '('" )}
521590 }
522- return nil , & parseError {leftCurly .Pos , errors .New ("unmatched '{'" )}
523591 default :
524592 panic (token )
525593 }
@@ -528,5 +596,6 @@ func asciiToDERImpl(scanner *scanner, leftCurly *token) ([]byte, error) {
528596
529597func asciiToDER (input string ) ([]byte , error ) {
530598 scanner := newScanner (input )
531- return asciiToDERImpl (scanner , nil )
599+ bytes , _ , err := asciiToDERImpl (scanner , nil )
600+ return bytes , err
532601}
0 commit comments