1 USING: accessors arrays combinators io kernel math.parser peg prettyprint
2 sequences strings unicode peg.ebnf multiline ;
3 IN: llvm.examples.kaleidoscope
5 TUPLE: ast-binop lhs rhs operator ;
6 TUPLE: ast-name value ;
7 TUPLE: ast-number value ;
8 TUPLE: ast-def name params expr ;
10 TUPLE: ast-call name args ;
11 TUPLE: ast-if condition true false ;
13 EBNF: tokenize-kaleidoscope [=[
17 SingleLineComment = "#" (!("\n") .)* "\n" => [[ ignore ]]
18 Space = [ \t\r\n] | SingleLineComment
19 Spaces = Space* => [[ ignore ]]
21 NameRest = NameFirst | Digit
22 iName = NameFirst NameRest* => [[ first2 swap prefix >string ]]
23 Name = !(Keyword) iName => [[ ast-name boa ]]
24 Number = Digits:ws '.' Digits:fs => [[ ws "." fs 3array "" concat-as string>number ast-number boa ]]
25 | Digits => [[ >string string>number ast-number boa ]]
26 Special = "(" | ")" | "*" | "+" | "/" | "-" | "<" | ">" | ","
27 Keyword = ("def" | "extern" | "if" | "then" | "else") !(NameRest)
28 Tok = Spaces (Keyword | Name | Number | Special)
32 EBNF: parse-kaleidoscope [=[
33 tokenizer = <foreign tokenize-kaleidoscope Tok>
34 Name = . ?[ ast-name? ]? => [[ value>> ]]
35 Number = . ?[ ast-number? ]? => [[ value>> ]]
38 MulOp = "*" | "%" | "/"
39 Unary = "-" Unary:p => [[ p ast-unop boa ]]
41 MulExpr = MulExpr:x MulOp:op Unary:y => [[ x y op ast-binop boa ]]
43 AddExpr = AddExpr:x AddOp:op MulExpr:y => [[ x y op ast-binop boa ]]
45 RelExpr = RelExpr:x CondOp:op AddExpr:y => [[ x y op ast-binop boa ]]
47 CondExpr = "if" RelExpr:c "then" CondExpr:e1 "else" CondExpr:e2 => [[ c e1 e2 ast-if boa ]]
49 Args = (RelExpr ("," RelExpr => [[ second ]])* => [[ first2 swap prefix ]])?
50 PrimExpr = "(" CondExpr:e ")" => [[ e ]]
51 | Name:n "(" Args:a ")" => [[ n a ast-call boa ]]
54 SrcElem = "def" Name:n "(" Name*:fs ")" CondExpr:expr => [[ n fs expr ast-def boa ]]