 USING: kernel compiler.units parser words arrays strings math.parser sequences 
        quotations vectors namespaces math assocs continuations peg
        peg.parsers unicode.categories multiline combinators.lib 
-       splitting accessors effects ;
+       splitting accessors effects sequences.deep ;
 IN: peg.ebnf
 
 TUPLE: ebnf-non-terminal symbol ;


SYMBOL: parser
SYMBOL: main

: transform ( ast -- object )
  H{ } clone dup dup [ parser set swap (transform) main set ] bind ;

M: ebnf (transform) ( ast -- parser )
  rules>> [ (transform) ] map peek ;
  
M: ebnf-rule (transform) ( ast -- parser )
  dup elements>> (transform) [
    swap symbol>> set
  ] keep ;


M: ebnf-optional (transform) ( ast -- parser )
  transform-group optional ;

: build-locals ( string vars -- string )
  dup empty? [
    drop
  ] [
    [
      "[let* | " %
      [ dup % " [ \"" % % "\" get ] " % ] each
      " | " %
      %  
      " ] with-locals" %     
    ] "" make 
  ] if ;

M: ebnf-action (transform) ( ast -- parser )
  [ parser>> (transform) ] keep
  code>> vars get build-locals string-lines [ parse-lines ] with-compilation-unit action ;

M: ebnf-var (transform) ( ast -- parser )
  [ parser>> (transform) ] [ name>> ] bi 
  dup vars get push [ dupd set ] curry action ;

M: ebnf-terminal (transform) ( ast -- parser )
  symbol>> token sp ;
