-
Notifications
You must be signed in to change notification settings - Fork 4
/
fold.myr
62 lines (60 loc) · 1.38 KB
/
fold.myr
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
use std
use "ctypes"
use "ast"
pkg qc =
const foldexpr : (e : expr# -> std.option(constval))
;;
const foldexpr = {e
match e
| &(`Eident &[.sc=`Sclassenum, .name=name, .ty=`Tyenum &(`std.Some enum)]):
-> `std.Some `Constint std.get(std.htget(enum.membs, name))
| &(`Ewchrlit c):
-> `std.Some `Constint (c : int64)
| &(`Echrlit c):
-> `std.Some `Constint (c : int64)
| &(`Ecast c):
-> foldexpr(c.expr)
| &(`Eintlit v):
-> `std.Some `Constint v
| &(`Eunop [.op=`Oaddr, .operand=&(`Eident sym)]):
match sym.sc
| `Sclassglobal:
-> `std.Some `Constptr (sym.name, 0)
| _:
-> `std.None
;;
| &(`Eunop [.op=`Oneg, .operand=expr]):
match foldexpr(expr)
| `std.Some `Constint v:
-> `std.Some `Constint -v
| _:
-> `std.None
;;
| &(`Ebinop [.op=op, .l=l, .r=r]):
match (op, foldexpr(l), foldexpr(r))
| (`Oplus, `std.Some `Constint c1, `std.Some `Constint c2):
-> `std.Some `Constint (c1 + c2)
| (`Oshl, `std.Some `Constint c1, `std.Some `Constint c2):
-> `std.Some `Constint (c1 << c2)
| (_, `std.None, _):
-> `std.None
| (_, _, `std.None):
-> `std.None
| _:
-> `std.None
;;
| &(`Einit initlist):
var vals = [][:]
for (offset, sube) : initlist.vals
match foldexpr(sube)
| `std.Some v:
std.slpush(&vals, (offset, exprtype(sube), v))
| `std.None:
-> `std.None
;;
;;
-> `std.Some `Constblob vals
| _:
-> `std.None
;;
}