-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathc.singeli
74 lines (64 loc) · 2.4 KB
/
c.singeli
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
local {
local def extend promote{arith} = {
def arith{a:T,b if is{'number',kind{b}} and is{'primitive',typekind{T}}} = arith{a , cast{T,b}}
def arith{a,b:T if is{'number',kind{a}} and is{'primitive',typekind{T}}} = arith{cast{T,a} , b}
}
def arith{op} = { def extend _{arith} = {
def arith{a:T,b:T if is{'primitive',typekind{T}}} = emit{T, op, a, b}
extend promote{arith}
}}
def arith1{op} = { def extend _{arith} = {
def arith{a:T if is{'primitive',typekind{T}}} = emit{T, op, a}
arith
}}
def sh{op} = { def extend _{arith} = {
def arith{a:T,b:I if isint{T} and isint{I}} = emit{T, op, a, b}
extend promote{arith}
}}
def pk{T} = {
def k=typekind{T}
is{'primitive',k} or is{'pointer',k}
}
def compare{op} = { def extend _{arith} = {
def arith{a:T,b:T if pk{T}} = emit{u1, op, a, b}
extend promote{arith}
}}
def logic = arith
def logic1 = arith1
}
extend (arith1{'-'}){__neg}
extend (arith{'op +'}){__add}
extend (arith{'op -'}){__sub}
extend (arith{'op *'}){__mul}
extend (arith{'op /'}){__div}
extend (arith{'op %'}){__mod}
local {
def isptr{T} = is{'pointer',typekind{T}}
def ptrwidth = width{__pnt{void}}
def isize = primtype{'i',ptrwidth}
def ptrdiff{a} = cast{isize, a}
def ptrdiff{a:T} = promote{ptrwidth, a}
def anynum{a} = is{'number',kind{a}}; def anynum{a:T} = is{'primitive',typekind{T}}
}
def __pnt{a:T if isptr{T}} = load{a,0}
def __add{a ,b:P if isptr{P} and anynum{a}} = emit{P, 'op +', ptrdiff{a}, b}
def __add{a:P,b if isptr{P} and anynum{b}} = emit{P, 'op +', a, ptrdiff{b}}
def __sub{a:P,b if isptr{P} and anynum{b}} = emit{P, 'op -', a, ptrdiff{b}}
def __sub{a:P,b:P if isptr{P}} = emit{isize, 'op -', a, b}
extend (compare{'op =='}){__eq}
extend (compare{'op !='}){__ne}
extend (compare{'op >' }){__gt}
extend (compare{'op >='}){__ge}
extend (compare{'op <' }){__lt}
extend (compare{'op <='}){__le}
extend (logic{'op &'}){__and}
extend (logic{'op |'}){__or }
extend (logic{'op ^'}){__xor}
extend (logic1{'~'}){__not}
def __not{a:(u1)} = emit{u1, '!', a}
extend (sh{'op <<'}){__shl}
extend (sh{'op >>'}){__shr}
def load{p:*T, i if anynum{i} and not is{T,void}} = emit{T, '^load', p, i}
def store{p:*T, i, v:T if anynum{i} and not is{T,void}} = { emit{void, '^store', p, i, v}; v }
def store{p:*T, i, v if is{'number',kind{v}} and anynum{i} and not is{T,void}} = store{p, i, cast{T, v}}
def cast_i{T, x} = emit{T, '', x}