-
Notifications
You must be signed in to change notification settings - Fork 65
/
Copy pathwyvernParser.wyv
82 lines (61 loc) · 5.52 KB
/
wyvernParser.wyv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
module wyvernParser
import selfhost.lexing
import metadata selfhost.parsing
import selfhost.raw
import wyvern.collections.llist
type List = llist.LinkedList
def Single(e:raw.Exp):List[raw.Exp] = llist.Singleton[raw.Exp](e)
def makeSeq(e1:raw.Exp, e2:raw.Exp):raw.Seq = match e1:
s:raw.Seq => raw.Seq(llist.Cons[raw.Exp](e2, s.exps))
default => raw.Seq(llist.Cons[raw.Exp](e2, llist.Singleton[raw.Exp](e1)))
val grammar: parsing.Grammar = ~
Stmts -> %logline Stmt : a:Dyn => a.get(1)
| Stmts %logline Stmt : a:Dyn => makeSeq(a.get(0), a.get(2))
Stmt -> Expression : a:Dyn => a.get(0)
| %val %identifier %eq Expression : a:Dyn => raw.Val(a.get(1).value, a.get(3))
| %val %identifier %colon Type %eq Expression : a:Dyn => raw.ValAnnot(a.get(1).value, a.get(3), a.get(5))
| %def %identifier %lparen Arguments %rparen %colon Type %colon %block : a:Dyn => raw.Def(a.get(1).value, a.get(3), a.get(6), a.get(8).value)
| %type %identifier %colon %identifier %colon %block : a:Dyn => raw.TypeDecl(a.get(1).value, a.get(3).value, a.get(5).value)
| %type %identifier %eq Type : a:Dyn => raw.TypeMem(a.get(1).value, raw.EQ(), a.get(3))
| %type %identifier %leq Type : a:Dyn => raw.TypeMem(a.get(1).value, raw.LEQ(), a.get(3))
| %type %identifier %geq Type : a:Dyn => raw.TypeMem(a.get(1).value, raw.GEQ(), a.get(3))
| %val %identifier %colon Type : a:Dyn => raw.ValType(a.get(1).value, a.get(3))
| %def %identifier %lparen Arguments %rparen %colon Type : a:Dyn => raw.DefDecl(a.get(1).value, a.get(3), a.get(6))
| %def %plus %lparen Arguments %rparen %colon Type : a:Dyn => raw.DefDecl("+", a.get(3), a.get(6))
| %def %minus %lparen Arguments %rparen %colon Type : a:Dyn => raw.DefDecl("-", a.get(3), a.get(6))
| %subtype Type %extends_ Type : a:Dyn => raw.SubtypeDecl(a.get(1),a.get(3))
Arguments -> Arg : a:Dyn => llist.Singleton[raw.Arg](a.get(0))
| Arg %comma Arguments : a:Dyn => llist.Cons[raw.Arg](a.get(0),a.get(2))
Arg -> %identifier %colon Type : a:Dyn => raw.Arg(a.get(0).value,a.get(2))
Refinements -> Stmt : a:Dyn => Single(a.get(0))
| Stmt %comma Refinements : a:Dyn => llist.Cons[raw.Exp](a.get(0),a.get(2))
Type -> BaseType : a:Dyn => raw.Type(a.get(0),llist.Nil[raw.Exp]())
| BaseType %lcurl Refinements %rcurl : a:Dyn => raw.Type(a.get(0),a.get(2))
BaseType -> %identifier : a:Dyn => raw.Base(a.get(0).value)
| Expression %dot %identifier : a:Dyn => raw.Path(a.get(0),a.get(2).value)
Expression -> ExprLambda : a:Dyn => a.get(0)
ExprLambda -> ExprAddSub : a:Dyn => a.get(0)
| %identifier %colon Type %darrow ExprLambda : a:Dyn => raw.Lambda(a.get(0).value, a.get(2), a.get(4))
ExprAddSub -> ExprMultDiv : a:Dyn => a.get(0)
| ExprAddSub %plus ExprMultDiv : a:Dyn => raw.Call(a.get(0),"+",Single(a.get(2)))
| ExprAddSub %minus ExprMultDiv : a:Dyn => raw.Call(a.get(0),"-",Single(a.get(2)))
ExprMultDiv -> ExprUnary : a:Dyn => a.get(0)
| ExprMultDiv %times ExprUnary : a:Dyn => raw.Call(a.get(0),"*",Single(a.get(2)))
| ExprMultDiv %divide ExprUnary : a:Dyn => raw.Call(a.get(0),"/",Single(a.get(2)))
| ExprMultDiv %mod ExprUnary : a:Dyn => raw.Call(a.get(0),"%",Single(a.get(2)))
ExprUnary -> ExprAppl : a:Dyn => a.get(0)
| %minus ExprAppl : a:Dyn => raw.Call(raw.Integer("0"),"-",Single(a.get(1)))
ExprAppl -> ExprDot : a:Dyn => a.get(0)
| ExprAppl ExprDot : a:Dyn => raw.App(a.get(0), a.get(1))
ExprDot -> Primary : a:Dyn => a.get(0)
| ExprDot %dot %identifier %lparen CallList %rparen : a:Dyn => raw.Call(a.get(0), a.get(2).value, a.get(4))
| ExprDot %dot %identifier : a:Dyn => raw.Field(a.get(0), a.get(2).value)
CallList -> Expression %comma Expression : a:Dyn => llist.Cons[raw.Exp](a.get(0),Single(a.get(2)))
| Expression %comma CallList : a:Dyn => llist.Cons[raw.Exp](a.get(0),a.get(2))
Primary -> %identifier : a:Dyn => raw.Var(a.get(0).value)
| %lparen Expression %rparen : a:Dyn => a.get(1)
| %integer : a:Dyn => raw.Integer(a.get(0).value)
| %new_ %identifier %colon Type %colon %block: a:Dyn => raw.New(a.get(1).value, a.get(3), a.get(5).value)
| %lparen %rparen : a:Dyn => raw.UnitVal()
def makeParser(lexer:lexing.Lexer):parsing.Parser
parsing.makeParser(grammar, lexer)