-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunction.easy
123 lines (98 loc) · 3.71 KB
/
function.easy
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
"sl/algorithm" useFile
"sl/linkedList" useFile
"sl/array" useFile
Function: [
inputTypes:;
{
FUNCTION: ();
name:retType:;;
inputValues: inputTypes copy makeArray ["" Value] map ;
type: retType inputTypes FunctionType;
basicBlocks: List;
exported: FALSE;
appendArgument: ["" Value dup inputValues.pushBack] func;
appendBasicBlock: [val: BasicBlock; val basicBlocks.pushBack val] func;
tempName: 0;
genName: [] func;
genName: [name "" =] [getLastName toText !tempName] pfunc;
getName: [name] func;
getName: [name "" =] [tempName] pfunc;
getNameIR: [retType.getIR " @" getName & &] func;
getNameIR: [inputValues.last "VARARG" has] [type.getIR " @" getName & &] pfunc;
genOffset: [textMemorySize 0 cast 1 + 51 swap - result: ""; [result " " & !result] times result] func;
generateNames: [
lastFreeName: 0;
getLastName: [@lastFreeName @lastFreeName 1 + !lastFreeName] func;
basicBlocks [
block:; block.genName
block.instructions [instruction:; instruction "return" has [instruction.return.genName] when TRUE] enum
block.terminator "return" has [block.terminator.return.genName] when
TRUE
] enum
] func;
getIR: [
generateNames
"define " exported ~ ["internal " &] when retType.getIR " @" getName & & &
"(" inputValues [.getDefIR] getListIR ")" & & &
" {" &
IRCode:;
basicBlocks [
block:;
IRCode LF &
block.getDeclIR &
preds: ();
basicBlocks [label:; label block.isJumpHere [preds label , drop] when TRUE] enum
preds fieldCount 0 > [block.getDeclIR genOffset "; preds = " & preds [.getNameIR] getListIR & &] when
LF &
block.getIR &
!IRCode
TRUE
] enum
IRCode "}" LF LF & & &
] func;
getIR: [result: FALSE; [.name "" = result or !result TRUE] inputValues enum result] [AllArgumentNamesMustBeNonEmpty] pfunc;
}
] func;
BasicBlock: [
{
BASIC_BLOCK: ();
name: "";
tempName: 0;
instructions: List;
terminator: [NonTerminated] func;
genName: [] func;
genName: [name "" =] [getLastName toText !tempName] pfunc;
getName: [name] func;
getName: [name "" =] [tempName] pfunc;
getDeclIR: [name copy ":" &] func;
getDeclIR: [name "" =] ["; <label>:" tempName copy ":" & &] pfunc;
getNameIR: ["%" getName &] func;
getDefIR: ["label %" getName &] func;
getIR: [
IRCode: "";
instructions [.getIR IRCode swap & !IRCode TRUE] enum
IRCode terminator.getIR &
] func;
isJumpHere: [drop FALSE] func;
isJumpHere: [.terminator "INDIRECT_BRANCH" has] [terminator: .terminator; @self terminator.labels checkInList] pfunc;
isJumpHere: [.terminator "SWITCH" has] [terminator: .terminator; terminator.default @self is @self terminator.branches checkInList or] pfunc;
isJumpHere: [.terminator "INVOKE" has] [terminator: .terminator; terminator.normal @self is terminator.exception @self is or] pfunc;
isJumpHere: [.terminator "BRANCH_COND" has] [terminator: .terminator; terminator.iftrue @self is terminator.iffalse @self is or] pfunc;
isJumpHere: [.terminator "BRANCH_UNCOND" has] [terminator: .terminator; terminator.val @self is] pfunc;
}
] func;
FunctionDeclaration: [
{
FUNCTION_DECLARATION: ();
name:retType:inputTypes: makeArray;;;
type: retType inputTypes FunctionType;
getNameIR: [retType.getIR " @" name & &] func;
getNameIR: [VarargType.getIR inputTypes.last .getIR =] [type.getIR " @" name & &] pfunc;
getDefIR: [type PointerType .getIR] func;
getIR: [
"declare " retType.getIR " @" name & & &
"(" inputTypes [.getIR] getListIR ")" & & &
LF LF & &
] func;
}
] func;