jweinst1
3/12/2017 - 6:30 AM

new parser of oblivoon

new parser of oblivoon

Program
  = c:Statement* _? {return {node:"?program", args:c};}

Statement
  /*Statements are the core top rule*/
  =   _? a:Assign {return a;}
  / _? d:Def {return d;}
  / _? i:If {return i;}
  / _? c:Call {return c;}
  / _? r:Return {return r;}
  / _? d:Draw {return d;}

Call
  /*Can Parse Function Calls*/
  = node:[a-zA-Z_@$]+ "(" _ args:Operands _ ")" {
     return {node:node.join(""), args:args};
  }
  / method:Attribute "(" _ args:Operands _ ")" {
     return {node:"?method", args:[method].concat(args)};
  }

Def
  = "def" _ n:Name _ "(" _ params:Params _ ")" _ b:Body _ "_" {
     return {node:"?=", args:[n, {node:"?func", args:[params, b]}]};
  }

Return
  = "return" _ a:Argument _ {
    return {node:"?return", args:[a]};
  }
  
Draw
  = "draw" _ a:Argument _ {
    return {node:"?draw", args:[a]};
  }

If
  = "if" _ c:Argument _ b:Body _ "else"? _ d:Body? _? "_" {
    return {node:"?if", args:[c, b, d]};
  }

Assign
  =  _? v:Name _? "=" _? val:Argument {return {node:"?=", args:[v, val]};}
  / _? v:Attribute _? "=" _? val:Argument {return {node:"?=>", args:[v, val]};}
  


List
  = "[" _ args:Operands _ "]" {
    return {node:"?list", args:args};
  }
  / "[" _ args:Pair* _ "]" {
    return {node:"?map", args:args};
  }
  / "[:]" {return {node:"?map", args:[]};}

Pair
  = _ arg1:Word ":" arg2:Argument _ {
    return {node:"?pair", args:[arg1, arg2]};
  }
  
Point
  = "(" _ a:Argument _ b:Argument _ ")" {
      return {node:"?point", args:[a, b]};  
  }

Attribute
  = obj:Name "." attr:Word {return {node:"?.", args:[obj, attr]};}
  
Infix
  = a:InfixArgument _ inf:Operator _ b:Infix {return {node:inf, args:[a, b]};}
  / a:InfixArgument _ inf:Operator _ b:InfixArgument {return {node:inf, args:[a, b]};}
  
InfixArgument
  = _? c:Call {return c;}
  / _? p:Process {return p;}
  / _? l:List {return l;}
  / _? p:Point {return p;}
  / _? a:Attribute {return a;}
  / _? a:Word {return a;}

Operands
  = Argument*

Params
  = p:Name* {return {node:"?params", args:p};}

Body
  = s:Statement* {return {node:"?body", args:s};}

Process
  = "{" _ proc:Body _ "}" {return {node:"?process", args:[proc]}}

Argument
  = _? c:Call {return c;}
  / _? p:Process {return p;}
  / _? i:Infix {return i;}
  / _? l:List {return l;}
  / _? p:Point {return p;}
  / _? a:Attribute {return a;}
  / _? a:Word {return a;}

_ "whitespace"
  = [ \t\n\r,]*

Name
  = _? n:[a-zA-Z_@$]+ {return {node:"?name", args:[n.join("")]};}
  
Operator
  = op:[~&|!><=/+%*-]+ {return op.join("")}


Word
  =  w:[a-z0-9A-Z_$@]+ {
      var result = w.join("");
      var imdict = {'true':['?bool', true], 'false':['?bool', false], 'null':['?null', null]};
      if(result in imdict) {return {node:imdict[result][0], args:[imdict[result][1]]}}
      else if(isNaN(result)) {return {node:"?word", args:[result]};}
      else return {node:"?number", args:[result]};
  }