59 lines
2.5 KiB
Factor
59 lines
2.5 KiB
Factor
USING: accessors arrays combinators io kernel math.parser peg prettyprint
|
|
sequences strings unicode peg.ebnf multiline ;
|
|
IN: llvm.examples.kaleidoscope
|
|
|
|
TUPLE: ast-binop lhs rhs operator ;
|
|
TUPLE: ast-name value ;
|
|
TUPLE: ast-number value ;
|
|
TUPLE: ast-def name params expr ;
|
|
TUPLE: ast-unop expr ;
|
|
TUPLE: ast-call name args ;
|
|
TUPLE: ast-if condition true false ;
|
|
|
|
EBNF: tokenize-kaleidoscope [=[
|
|
Letter = [a-zA-Z]
|
|
Digit = [0-9]
|
|
Digits = Digit+
|
|
SingleLineComment = "#" (!("\n") .)* "\n" => [[ ignore ]]
|
|
Space = [ \t\r\n] | SingleLineComment
|
|
Spaces = Space* => [[ ignore ]]
|
|
NameFirst = Letter
|
|
NameRest = NameFirst | Digit
|
|
iName = NameFirst NameRest* => [[ first2 swap prefix >string ]]
|
|
Name = !(Keyword) iName => [[ ast-name boa ]]
|
|
Number = Digits:ws '.' Digits:fs => [[ ws "." fs 3array "" concat-as string>number ast-number boa ]]
|
|
| Digits => [[ >string string>number ast-number boa ]]
|
|
Special = "(" | ")" | "*" | "+" | "/" | "-" | "<" | ">" | ","
|
|
Keyword = ("def" | "extern" | "if" | "then" | "else") !(NameRest)
|
|
Tok = Spaces (Keyword | Name | Number | Special)
|
|
Toks = Tok* Spaces
|
|
]=]
|
|
|
|
EBNF: parse-kaleidoscope [=[
|
|
tokenizer = <foreign tokenize-kaleidoscope Tok>
|
|
Name = . ?[ ast-name? ]? => [[ value>> ]]
|
|
Number = . ?[ ast-number? ]? => [[ value>> ]]
|
|
CondOp = "<" | ">"
|
|
AddOp = "+" | "-"
|
|
MulOp = "*" | "%" | "/"
|
|
Unary = "-" Unary:p => [[ p ast-unop boa ]]
|
|
| PrimExpr
|
|
MulExpr = MulExpr:x MulOp:op Unary:y => [[ x y op ast-binop boa ]]
|
|
| Unary
|
|
AddExpr = AddExpr:x AddOp:op MulExpr:y => [[ x y op ast-binop boa ]]
|
|
| MulExpr
|
|
RelExpr = RelExpr:x CondOp:op AddExpr:y => [[ x y op ast-binop boa ]]
|
|
| AddExpr
|
|
CondExpr = "if" RelExpr:c "then" CondExpr:e1 "else" CondExpr:e2 => [[ c e1 e2 ast-if boa ]]
|
|
| RelExpr
|
|
Args = (RelExpr ("," RelExpr => [[ second ]])* => [[ first2 swap prefix ]])?
|
|
PrimExpr = "(" CondExpr:e ")" => [[ e ]]
|
|
| Name:n "(" Args:a ")" => [[ n a ast-call boa ]]
|
|
| Name
|
|
| Number
|
|
SrcElem = "def" Name:n "(" Name*:fs ")" CondExpr:expr => [[ n fs expr ast-def boa ]]
|
|
| RelExpr
|
|
SrcElems = SrcElem*
|
|
TopLevel = SrcElems
|
|
]=]
|