-
Notifications
You must be signed in to change notification settings - Fork 0
/
sous.ohm
144 lines (131 loc) · 7.93 KB
/
sous.ohm
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
Sous {
Program = Stmt*
Stmt = VarDecl
| FunDecl
| ClassDecl
| ObjDecl
| ("++" | "--") Exp9 ";" --bump
| Exp9 "=" Exp ";" --assign
| Exp9_call ";" --call
| Exp9_methodCall ";" --methodcall
| break ";" --breakstmt
| ContinueStmt
| return Exp ";" --returnstmt
| return ";" --shortreturn
| ErrorStmt
| WhileStmt
| IfStmt
| TryStmt
| ForStmt
| PythForStmt
Type = Type "?" --optional
| "[" Type "]" --array
| "(" ListOf<Type, ","> ")" "->" Type --function
| id --id
VarDecl = ingredient nonemptyListOf<VarInit, ","> ";" --list
| ingredient id ":" Type ";" --without_init
VarInit = id ":=" Exp Modifier?
Modifier = "|" const
Field = ingredient id ":" Type ";"
FunDecl = recipe id "(" Params ")" (":" Type)? Block
Params = ListOf<Param, ",">
Param = ingredient id ":" Type
Block = "{" Stmt* "}"
ClassDecl = dish id "{" (Field)* (FunDecl)* "}"
ObjDecl = Type id ":=" new Type "(" ListOf<Exp, ","> ")" ";"
ContinueStmt = continue ";"
WhileStmt = while "(" Exp ")" Block
IfStmt = if "(" Exp ")" Block else Block --long
| if "(" Exp ")" Block else IfStmt --nested_if
| if "(" Exp ")" Block --short
TryStmt = try Block Catch* Finally?
Catch = catch "(" id id ")" Block
Finally = finally Block
ForStmt = for "(" VarDecl Exp4_compare ";" ForUpdate ")" Block --norm
| for "(" id in Exp ")" Block --collection
ForUpdate = Exp9_assign | Exp6_bump
PythForStmt = "F" single_letter_id "r" single_letter_id single_letter_id Block
ErrorStmt = eightysix "(" Exp "," id ")" ";"
Exp = Exp1 "?" Exp1 ":" Exp --conditional
| Exp1
Exp1 = Exp1 "??" Exp2 --unwrapelse
| Exp2
Exp2 = Exp3 ("||" Exp3)+ --or
| Exp3 ("&&" Exp3)+ --and
| Exp3
Exp3 = Exp4 ("|" Exp4)+ --bitor
| Exp4 ("^" Exp4)+ --bitxor
| Exp4 ("&" Exp4)+ --bitand
| Exp4
Exp4 = Exp5 ("<="|"<"|"=="|"!="|">="|">") Exp5 --compare
| Exp5
Exp5 = Exp5 ("<<" | ">>") Exp6 --shift
| Exp6
Exp6 = Exp6 ("+" | "-") Exp7 --add
| ("++" | "--") Exp9 --bump
| Exp7
Exp7 = Exp7 ("*"| "/" | "%") Exp8 --multiply
| Exp8
Exp8 = Exp9 "**" Exp8 --power
| Exp9
| ("-" | "!"| poached | random) Exp9 --unary
Exp9 = true ~mut
| false ~mut
| Exp9 ".." Exp9 ~mut --range
| floatlit ~mut
| intlit ~mut
| stringlit ~mut
| raw Type ~mut --emptyopt
| Exp9 ("(" | "?(") ListOf<Exp, ","> ")" ~mut --call
| Exp9 ("[" | "?[") Exp "]" --subscript
| Exp9_id ("." | "?.") Exp9_id "(" ListOf<Exp, ","> ")" --methodCall
| Exp9 ("." | "?.") id --member
| id --id
| Type_array "(" ")" ~mut --emptyarray
| "[" NonemptyListOf<Exp, ","> "]" ~mut --arrayexp
| "(" Exp ")" ~mut --parens
| Exp9 "=" Exp ~mut --assign
mut = ~"==" "=" | "++" | "--"
relop = "<=" | "<" | ">=" | ">" | "==" | "!="
string = "\"" char* "\""
poached = "poached" ~alnum
raw = "raw" ~alnum
dish = "Dish" ~alnum
ingredient = "ingredient" ~alnum
recipe = "recipe" ~alnum
if = "if" ~alnum
else = "else" ~alnum
for = "for" ~alnum
while = "while" ~alnum
return = "return" ~alnum
break = "break" ~alnum
continue = "continue" ~alnum
try = "prep" ~alnum
catch = "rescue" ~alnum
finally = "cleanup" ~alnum
random = "random" ~alnum
true = "fresh" ~alnum
false = "stale" ~alnum
in = "in" ~alnum
count = "count" ~alnum
new = "new" ~alnum
eightysix = "eightysix" ~alnum
const = "const" ~alnum
keyword = ingredient | recipe | if | else | for | while | finally | return
| break | continue | try | catch | true | false | in
| ingredient | recipe | new | eightysix | const | random | poached
| raw
single_letter_id= ~keyword letter | ~keyword "_"
id = ~keyword (letter | "_") (alnum | "_")*
intlit = digit+
floatlit = digit+ "." digit+ (("E" | "e") ("+" | "-")? digit+)?
stringlit = "\"" char* "\""
char = ~control ~"\\" ~"\"" any
| "\\" ("n" | "t" | "\"" | "\\") --escape
| "\\u{" hex hex? hex? hex? hex? hex? "}" --codepoint
control = "\x00".."\x1f" | "\x80".."\x9f"
hex = hexDigit
num = digit+ ("." digit+)? (("e" | "E") ("+" | "-")? digit+)?
space += "//" (~"\n" any)* --comment
| "'''" (~"'''" any)* "'''" --multiline
}