Mercurial > repos > icfp2014
annotate code/gqc.tp @ 82:ea6a0709373f
Updated README
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 28 Jul 2014 04:38:29 -0700 |
parents | a2a5d80abaa0 |
children |
rev | line source |
---|---|
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1 { |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
2 reg? <- :val { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
3 (object does: val understand?: "isReg?") && (val isReg?) |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
4 } |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
5 mem? <- :val { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
6 (object does: val understand?: "isMem?") && (val isMem?) |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
7 } |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
8 |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
9 mem <- :_addr { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
10 #{ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
11 addr <- { _addr } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
12 string <- { "[" . _addr . "]" } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
13 isReg? <- { false } |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
14 != <- :other { (not: (mem?: other)) || _addr != (other addr) } |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
15 = <- :other { (mem?: other) && _addr = (other addr) } |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
16 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
17 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
18 reg <- :_num { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
19 #{ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
20 num <- { _num } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
21 string <- { (#["a" "b" "c" "d" "e" "f" "g" "h" "pc"]) get: _num } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
22 isReg? <- { true } |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
23 != <- :other { (not: (reg?: other)) || _num != (other num) } |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
24 = <- :other { (reg?: other) && _num = (other num) } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
25 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
26 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
27 inst <- :_name _args { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
28 #{ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
29 name <- _name |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
30 args <- _args |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
31 translateLabels <- :labelDict { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
32 missing <- #[] |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
33 args <- args map: :arg { |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
34 if: (object does: arg understand?: "isString?") && (arg isString?) { |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
35 labelDict get: arg else: { |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
36 missing append: arg |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
37 arg |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
38 } |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
39 } else: { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
40 arg |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
41 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
42 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
43 missing |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
44 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
45 label <- "" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
46 comment <- "" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
47 string <- { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
48 (if: label != "" { ";" . label . "\n " } else: { " " } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
49 ) . name . " " . (args join: ", ") . ( |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
50 if: comment = "" { "" } else: { " ;" . comment}) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
51 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
52 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
53 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
54 _nextLabel <- 0 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
55 _setLabel <- :inst { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
56 inst |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
57 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
58 prog <- #{ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
59 instructions <- #[] |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
60 add <- :inst { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
61 instructions append: (_setLabel: inst) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
62 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
63 makeLabel <- :suffix { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
64 num <- _nextLabel |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
65 _nextLabel <- _nextLabel + 1 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
66 "" . num . "_" . suffix |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
67 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
68 labels <- dict hash |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
69 setLabel <- :name { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
70 labels set: name pc |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
71 _setLabel <- :inst { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
72 _setLabel <- :i { i } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
73 inst label!: name |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
74 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
75 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
76 pc <- { instructions length } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
77 print <- { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
78 foreach: instructions :idx i { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
79 missing <- i translateLabels: labels |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
80 if: (missing length) > 0 { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
81 error: "Undefined labels " . (missing join: ", ") . " at address " . idx |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
82 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
83 print: (string: i) . "\n" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
84 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
85 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
86 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
87 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
88 error <- :msg { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
89 (file stderr) write: "Error - " . msg . "\n" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
90 } |
70
5f44ac1bcbd6
Add support for a special notFirst? variable so that globals can be initialized on startup only. This allows for state that persists between turns
Michael Pavone <pavone@retrodev.com>
parents:
69
diff
changeset
|
91 //0 is used for the special notFirst? variable |
5f44ac1bcbd6
Add support for a special notFirst? variable so that globals can be initialized on startup only. This allows for state that persists between turns
Michael Pavone <pavone@retrodev.com>
parents:
69
diff
changeset
|
92 _nextVar <- 1 |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
93 //a and b are reserved for int/return values |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
94 //h is reserved as a stack pointer |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
95 _allTemp <- [ |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
96 reg: 2 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
97 reg: 3 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
98 reg: 4 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
99 reg: 5 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
100 reg: 6 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
101 ] |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
102 _tempRegs <- _allTemp |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
103 |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
104 getTemp <- { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
105 if: (_tempRegs empty?) { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
106 //out of regs, use memory |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
107 loc <- _nextVar |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
108 _nextVar <- _nextVar + 1 |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
109 mem: loc |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
110 } else: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
111 r <- _tempRegs value |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
112 _tempRegs <- _tempRegs tail |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
113 r |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
114 } |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
115 } |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
116 |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
117 preserveTemps <- :fun { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
118 saveTempRegs <- _tempRegs |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
119 res <- fun: |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
120 _tempRegs <- saveTempRegs |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
121 res |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
122 } |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
123 |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
124 _exprHandlers <- dict hash |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
125 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
126 compileExpr:syms <- :expr :syms { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
127 _exprHandlers ifget: (expr nodeType) :handler { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
128 handler: expr syms |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
129 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
130 error: "Unhandled node type " . (expr nodeType) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
131 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
132 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
133 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
134 _exprHandlers set: (ast intlit) :expr syms { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
135 expr val |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
136 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
137 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
138 _opNames <- dict hash |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
139 _opNames set: "+" "ADD" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
140 _opNames set: "-" "SUB" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
141 _opNames set: "*" "MUL" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
142 _opNames set: "/" "DIV" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
143 _opNames set: "and" "AND" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
144 _opNames set: "or" "OR" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
145 _opNames set: "xor" "XOR" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
146 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
147 _exprHandlers set: (ast binary) :expr syms { |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
148 l <- 0 |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
149 r <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
150 l <- compileExpr: (expr left) syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
151 compileExpr: (expr right) syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
152 } |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
153 dest <- l |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
154 if: (reg?: l) { |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
155 //reallocate temp register used by l |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
156 //not always safe, needs work |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
157 _tempRegs <- _tempRegs filter: :r { r != l } |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
158 } else: { |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
159 dest <- getTemp: |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
160 prog add: (inst: "MOV" #[ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
161 dest |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
162 l |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
163 ]) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
164 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
165 _opNames ifget: (expr op) :i { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
166 prog add: (inst: i #[ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
167 dest |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
168 r |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
169 ]) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
170 dest |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
171 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
172 error: "operator " . (expr op) . " is not supported" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
173 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
174 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
175 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
176 _exprHandlers set: (ast sym) :expr syms { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
177 syms ifDefined: (expr name) :info { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
178 info def |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
179 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
180 error: "symbol " . (expr name) . " is not defined" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
181 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
182 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
183 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
184 _exprHandlers set: (ast assignment) :expr syms { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
185 sym <- expr to |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
186 syms ifDefined: (sym name) :info { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
187 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
188 syms define: (sym name) (mem: _nextVar) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
189 _nextVar <- _nextVar + 1 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
190 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
191 info <- syms find: (sym name) else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
192 error: "this should never happen!" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
193 } |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
194 v <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
195 compileExpr: (expr assign) syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
196 } |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
197 dest <- info def |
67
76570158a6e9
Small optimization, avoid redundant MOV instructions
Michael Pavone <pavone@retrodev.com>
parents:
65
diff
changeset
|
198 if: dest != v { |
76570158a6e9
Small optimization, avoid redundant MOV instructions
Michael Pavone <pavone@retrodev.com>
parents:
65
diff
changeset
|
199 prog add: (inst: "MOV" #[ |
76570158a6e9
Small optimization, avoid redundant MOV instructions
Michael Pavone <pavone@retrodev.com>
parents:
65
diff
changeset
|
200 dest |
76570158a6e9
Small optimization, avoid redundant MOV instructions
Michael Pavone <pavone@retrodev.com>
parents:
65
diff
changeset
|
201 v |
76570158a6e9
Small optimization, avoid redundant MOV instructions
Michael Pavone <pavone@retrodev.com>
parents:
65
diff
changeset
|
202 ]) |
76570158a6e9
Small optimization, avoid redundant MOV instructions
Michael Pavone <pavone@retrodev.com>
parents:
65
diff
changeset
|
203 } |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
204 dest |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
205 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
206 |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
207 _funHandlers <- dict hash |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
208 //provide symbolic names for all the interupt routines |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
209 _funHandlers set: "debug" :args syms { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
210 prog add: (inst: "INT" #[8]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
211 0 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
212 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
213 _funHandlers set: "direction!" :args syms { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
214 dir <- args value |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
215 v <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
216 compileExpr: dir syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
217 } |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
218 if: (reg: 0) != v { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
219 prog add: (inst: "MOV" #[ |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
220 reg: 0 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
221 v |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
222 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
223 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
224 prog add: (inst: "INT" #[0]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
225 0 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
226 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
227 _funHandlers set: "lambdamanPos" :args syms { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
228 prog add: (inst: "INT" #[1]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
229 reg: 0 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
230 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
231 _funHandlers set: "lambdaman2Pos" :args syms { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
232 prog add: (inst: "INT" #[2]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
233 reg: 0 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
234 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
235 _funHandlers set: "me" :args syms { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
236 prog add: (inst: "INT" #[3]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
237 reg: 0 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
238 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
239 foreach: #["ghostStartPos" "ghostPos" "ghostStatus"] :idx name { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
240 intNum <- idx + 4 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
241 _funHandlers set: name :args syms { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
242 ghostIdx <- args value |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
243 v <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
244 compileExpr: ghostIdx syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
245 } |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
246 if: (reg: 0) != v { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
247 prog add: (inst: "MOV" #[ |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
248 reg: 0 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
249 v |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
250 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
251 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
252 prog add: (inst: "INT" #[intNum]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
253 reg: 0 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
254 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
255 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
256 _funHandlers set: "mapContentsAt" :args syms { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
257 x <- args value |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
258 y <- (args tail) value |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
259 preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
260 x <- compileExpr: x syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
261 y <- compileExpr: y syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
262 } |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
263 if: (reg: 0) != x { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
264 prog add: (inst: "MOV" #[ |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
265 reg: 0 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
266 x |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
267 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
268 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
269 if: (reg: 1) != y { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
270 prog add: (inst: "MOV" #[ |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
271 reg: 1 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
272 y |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
273 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
274 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
275 prog add: (inst: "INT" #[7]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
276 reg: 0 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
277 } |
72
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
278 //new Quiche parser doesn't support and/or/xor operators yet :( |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
279 _funHandlers set: "and" :args syms { |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
280 l <- 0 |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
281 r <- preserveTemps: { |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
282 l <- compileExpr: (args value) syms: syms |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
283 compileExpr: ((args tail) value) syms: syms |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
284 } |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
285 dest <- getTemp: |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
286 if: dest != l { |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
287 prog add: (inst: "MOV" #[ |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
288 dest |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
289 l |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
290 ]) |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
291 } |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
292 prog add: (inst: "AND" #[ |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
293 dest |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
294 r |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
295 ]) |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
296 dest |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
297 } |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
298 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
299 //allow access to raw instructions |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
300 foreach: #["MOV" "INC" "DEC" "ADD" "SUB" "MUL" "DIV" "AND" "OR" "XOR" "JLT" "JEQ" "JGT" "HLT"] :idx instName { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
301 _funHandlers set: instName :args syms { |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
302 preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
303 args <- args map: :arg { compileExpr: arg syms: syms } |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
304 } |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
305 prog add: (inst: instName args) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
306 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
307 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
308 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
309 _funHandlers set: "while:do" :args syms { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
310 cond <- ((args value) expressions) value |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
311 body <- ((args tail) value) expressions |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
312 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
313 if: (cond nodeType) = (ast binary) { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
314 top <- prog makeLabel: "loop_top" |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
315 end <- prog makeLabel: "loop_end" |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
316 prog setLabel: top |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
317 |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
318 l <- 0 |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
319 r <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
320 l <- compileExpr: (cond left) syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
321 compileExpr: (cond right) syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
322 } |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
323 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
324 ok <- true |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
325 //we need the inverse check in the instruction since a true condition |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
326 //means continue the loop, whereas we need a jump instruction that jumps |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
327 //only when it is time to exit |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
328 if: (cond op) = ">=" { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
329 prog add: (inst: "JLT" #[ |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
330 end |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
331 l |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
332 r |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
333 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
334 } else: { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
335 if: (cond op) = "<=" { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
336 prog add: (inst: "JGT" #[ |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
337 end |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
338 l |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
339 r |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
340 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
341 } else: { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
342 if: (cond op) = "!=" { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
343 prog add: (inst: "JEQ" #[ |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
344 end |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
345 l |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
346 r |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
347 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
348 } else: { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
349 if: (cond op) = ">" { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
350 bodyLbl <- prog makeLabel: "loop_body" |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
351 prog add: (inst: "JGT" #[ |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
352 bodyLbl |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
353 l |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
354 r |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
355 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
356 prog add: (inst: "MOV" #[ |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
357 reg: 8 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
358 end |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
359 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
360 prog setLabel: bodyLbl |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
361 } else: { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
362 if: (cond op) = "<" { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
363 bodyLbl <- prog makeLabel: "loop_body" |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
364 prog add: (inst: "JLT" #[ |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
365 bodyLbl |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
366 l |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
367 r |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
368 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
369 prog add: (inst: "MOV" #[ |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
370 reg: 8 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
371 end |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
372 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
373 prog setLabel: bodyLbl |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
374 } else: { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
375 bodyLbl <- prog makeLabel: "loop_body" |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
376 if: (cond op) = "=" { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
377 prog add: (inst: "JEQ" #[ |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
378 bodyLbl |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
379 l |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
380 r |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
381 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
382 prog add: (inst: "MOV" #[ |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
383 reg: 8 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
384 end |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
385 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
386 prog setLabel: bodyLbl |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
387 } else: { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
388 ok <- false |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
389 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
390 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
391 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
392 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
393 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
394 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
395 if: ok { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
396 //TODO: do 2 passes for labels to allow forward references |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
397 foreach: body :idx expr { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
398 if: (expr nodeType) = (ast sym) { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
399 //allow using bare symbols to define labels |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
400 lbl <- prog makeLabel: (expr name) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
401 prog setLabel: lbl |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
402 syms define: (expr name) lbl |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
403 } else: { |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
404 v <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
405 compileExpr: expr syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
406 } |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
407 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
408 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
409 prog add: (inst: "MOV" #[ |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
410 reg: 8 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
411 top |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
412 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
413 prog setLabel: end |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
414 } else: { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
415 error: "Condition parameter to while:do must be a comparison operator expression" |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
416 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
417 } else: { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
418 error: "Condition parameter to while:do must be a comparison operator expression" |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
419 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
420 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
421 |
58
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
422 _funHandlers set: "if:else" :args syms { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
423 cond <- (args value) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
424 trueBody <- ((args tail) value) expressions |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
425 falseBody <- (((args tail) tail) value) expressions |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
426 |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
427 if: (cond nodeType) = (ast binary) { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
428 trueLbl <- prog makeLabel: "true" |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
429 falseLbl <- prog makeLabel: "false" |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
430 endLbl <- prog makeLabel: "end" |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
431 |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
432 l <- 0 |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
433 r <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
434 l <- compileExpr: (cond left) syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
435 compileExpr: (cond right) syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
436 } |
58
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
437 |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
438 ok <- true |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
439 |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
440 if: (cond op) = ">=" { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
441 prog add: (inst: "JLT" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
442 falseLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
443 l |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
444 r |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
445 ]) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
446 } else: { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
447 if: (cond op) = "<=" { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
448 prog add: (inst: "JGT" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
449 falseLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
450 l |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
451 r |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
452 ]) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
453 } else: { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
454 if: (cond op) = "!=" { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
455 prog add: (inst: "JEQ" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
456 falseLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
457 l |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
458 r |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
459 ]) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
460 } else: { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
461 if: (cond op) = ">" { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
462 prog add: (inst: "JGT" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
463 trueLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
464 l |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
465 r |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
466 ]) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
467 prog add: (inst: "MOV" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
468 reg: 8 |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
469 falseLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
470 ]) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
471 } else: { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
472 if: (cond op) = "<" { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
473 prog add: (inst: "JLT" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
474 trueLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
475 l |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
476 r |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
477 ]) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
478 prog add: (inst: "MOV" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
479 reg: 8 |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
480 falseLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
481 ]) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
482 } else: { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
483 bodyLbl <- prog makeLabel: "loop_body" |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
484 if: (cond op) = "=" { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
485 prog add: (inst: "JEQ" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
486 trueLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
487 l |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
488 r |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
489 ]) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
490 prog add: (inst: "MOV" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
491 reg: 8 |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
492 falseLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
493 ]) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
494 } else: { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
495 ok <- false |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
496 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
497 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
498 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
499 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
500 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
501 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
502 if: ok { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
503 prog setLabel: trueLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
504 //TODO: do 2 passes for labels to allow forward references |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
505 foreach: trueBody :idx expr { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
506 if: (expr nodeType) = (ast sym) { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
507 //allow using bare symbols to define labels |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
508 lbl <- prog makeLabel: (expr name) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
509 prog setLabel: lbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
510 syms define: (expr name) lbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
511 } else: { |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
512 v <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
513 compileExpr: expr syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
514 } |
58
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
515 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
516 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
517 prog add: (inst: "MOV" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
518 reg: 8 |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
519 endLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
520 ]) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
521 prog setLabel: falseLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
522 //TODO: do 2 passes for labels to allow forward references |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
523 foreach: falseBody :idx expr { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
524 if: (expr nodeType) = (ast sym) { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
525 //allow using bare symbols to define labels |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
526 lbl <- prog makeLabel: (expr name) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
527 prog setLabel: lbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
528 syms define: (expr name) lbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
529 } else: { |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
530 v <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
531 compileExpr: expr syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
532 } |
58
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
533 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
534 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
535 prog setLabel: endLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
536 } else: { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
537 error: "Condition parameter to if:else must be a comparison operator expression" |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
538 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
539 } else: { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
540 error: "Condition parameter to if:else must be a comparison operator expression" |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
541 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
542 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
543 |
69
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
544 _funHandlers set: "if" :args syms { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
545 cond <- (args value) |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
546 trueBody <- ((args tail) value) expressions |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
547 |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
548 if: (cond nodeType) = (ast binary) { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
549 trueLbl <- prog makeLabel: "true" |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
550 endLbl <- prog makeLabel: "end" |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
551 |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
552 l <- 0 |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
553 r <- preserveTemps: { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
554 l <- compileExpr: (cond left) syms: syms |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
555 compileExpr: (cond right) syms: syms |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
556 } |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
557 |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
558 ok <- true |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
559 |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
560 if: (cond op) = ">=" { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
561 prog add: (inst: "JLT" #[ |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
562 endLbl |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
563 l |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
564 r |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
565 ]) |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
566 } else: { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
567 if: (cond op) = "<=" { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
568 prog add: (inst: "JGT" #[ |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
569 endLbl |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
570 l |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
571 r |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
572 ]) |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
573 } else: { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
574 if: (cond op) = "!=" { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
575 prog add: (inst: "JEQ" #[ |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
576 endLbl |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
577 l |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
578 r |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
579 ]) |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
580 } else: { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
581 if: (cond op) = ">" { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
582 prog add: (inst: "JGT" #[ |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
583 trueLbl |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
584 l |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
585 r |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
586 ]) |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
587 prog add: (inst: "MOV" #[ |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
588 reg: 8 |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
589 endLbl |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
590 ]) |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
591 } else: { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
592 if: (cond op) = "<" { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
593 prog add: (inst: "JLT" #[ |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
594 trueLbl |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
595 l |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
596 r |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
597 ]) |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
598 prog add: (inst: "MOV" #[ |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
599 reg: 8 |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
600 endLbl |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
601 ]) |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
602 } else: { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
603 bodyLbl <- prog makeLabel: "loop_body" |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
604 if: (cond op) = "=" { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
605 prog add: (inst: "JEQ" #[ |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
606 trueLbl |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
607 l |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
608 r |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
609 ]) |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
610 prog add: (inst: "MOV" #[ |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
611 reg: 8 |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
612 endLbl |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
613 ]) |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
614 } else: { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
615 ok <- false |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
616 } |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
617 } |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
618 } |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
619 } |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
620 } |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
621 } |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
622 if: ok { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
623 prog setLabel: trueLbl |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
624 //TODO: do 2 passes for labels to allow forward references |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
625 foreach: trueBody :idx expr { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
626 if: (expr nodeType) = (ast sym) { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
627 //allow using bare symbols to define labels |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
628 lbl <- prog makeLabel: (expr name) |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
629 prog setLabel: lbl |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
630 syms define: (expr name) lbl |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
631 } else: { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
632 v <- preserveTemps: { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
633 compileExpr: expr syms: syms |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
634 } |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
635 } |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
636 } |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
637 prog setLabel: endLbl |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
638 } else: { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
639 error: "Condition parameter to if must be a comparison operator expression" |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
640 } |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
641 } else: { |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
642 error: "Condition parameter to if must be a comparison operator expression" |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
643 } |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
644 } |
8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
Michael Pavone <pavone@retrodev.com>
parents:
67
diff
changeset
|
645 |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
646 _exprHandlers set: (ast call) :expr syms { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
647 tc <- (expr tocall) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
648 if: (tc nodeType) = (ast sym) { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
649 _funHandlers ifget: (tc name) :handler { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
650 handler: (expr args) syms |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
651 } else: { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
652 syms ifDefined: (tc name) :info { |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
653 funArgs <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
654 (expr args) map: :arg { compileExpr: arg syms: syms} |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
655 } |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
656 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
657 //save registers that need it |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
658 needSave <- _allTemp filter: :r { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
659 not: (_tempRegs contains?: r) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
660 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
661 foreach: needSave :idx r { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
662 prog add: (inst: "DEC" #[(reg: 7)]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
663 prog add: (inst: "MOV" #[ |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
664 mem: (reg: 7) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
665 r |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
666 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
667 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
668 after <- prog makeLabel: "after_call" |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
669 //save PC value after call |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
670 prog add: (inst: "DEC" #[(reg: 7)]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
671 prog add: (inst: "MOV" #[ |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
672 mem: (reg: 7) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
673 after |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
674 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
675 //put arguments into the appropriate registers |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
676 passregs <- _allTemp |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
677 foreach: funArgs :idx arg { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
678 passreg <- passregs value |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
679 passregs <- passregs tail |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
680 if: passreg != arg { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
681 //there's a potential for clobbering argument temp regs |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
682 //but there's no time to figure out a good solution |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
683 prog add: (inst: "MOV" #[ |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
684 passreg |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
685 arg |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
686 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
687 } else: { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
688 print: "Skipping MOV for argument: " . arg . "\n" |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
689 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
690 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
691 //jump to function |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
692 prog add: (inst: "MOV" #[ |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
693 reg: 8 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
694 info def |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
695 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
696 prog setLabel: after |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
697 //adjust PC |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
698 prog add: (inst: "INC" #[(reg: 7)]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
699 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
700 //restore registers that were saved earlier |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
701 foreach: (reverse: needSave) :idx r { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
702 prog add: (inst: "MOV" #[ |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
703 r |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
704 mem: (reg: 7) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
705 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
706 prog add: (inst: "INC" #[(reg: 7)]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
707 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
708 reg: 0 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
709 } else: { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
710 error: "Function " . (tc name) . " is not defined" |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
711 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
712 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
713 } else: { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
714 error: "Calling expressions is not supported in" |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
715 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
716 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
717 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
718 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
719 _compileFun <- :fName fun globsyms { |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
720 syms <- symbols tableWithParent: globsyms |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
721 |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
722 preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
723 foreach: (fun args) :idx arg { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
724 argname <- (if: (arg startsWith?: ":") { arg from: 1 } else: { arg }) |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
725 r <- getTemp: |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
726 syms define: argname r |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
727 } |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
728 |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
729 lastexpr <- ((fun expressions) length) - 1 |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
730 |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
731 //TODO: do 2 passes for labels to allow forward references |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
732 foreach: (fun expressions) :idx expr { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
733 if: idx != lastexpr && (expr nodeType) = (ast sym) { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
734 //allow using bare symbols to define labels |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
735 prog setLabel: (expr name) |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
736 syms define: (expr name) (expr name) |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
737 } else: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
738 v <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
739 compileExpr: expr syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
740 } |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
741 if: idx = lastexpr && (fName != "main") { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
742 //move result to a register |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
743 prog add: (inst: "MOV" #[ |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
744 reg: 0 |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
745 v |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
746 ]) |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
747 //return instruction |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
748 prog add: (inst: "MOV" #[ |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
749 reg: 8 |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
750 mem: (reg: 7) |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
751 ]) |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
752 } |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
753 } |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
754 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
755 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
756 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
757 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
758 #{ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
759 compile <- :code { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
760 res <- parser top: code |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
761 if: res { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
762 outer <- res yield |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
763 functions <- dict hash |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
764 syms <- symbols table |
70
5f44ac1bcbd6
Add support for a special notFirst? variable so that globals can be initialized on startup only. This allows for state that persists between turns
Michael Pavone <pavone@retrodev.com>
parents:
69
diff
changeset
|
765 |
5f44ac1bcbd6
Add support for a special notFirst? variable so that globals can be initialized on startup only. This allows for state that persists between turns
Michael Pavone <pavone@retrodev.com>
parents:
69
diff
changeset
|
766 //define symbols for the special notFirst? variable |
5f44ac1bcbd6
Add support for a special notFirst? variable so that globals can be initialized on startup only. This allows for state that persists between turns
Michael Pavone <pavone@retrodev.com>
parents:
69
diff
changeset
|
767 syms define: "notFirst?" (mem: 0) |
5f44ac1bcbd6
Add support for a special notFirst? variable so that globals can be initialized on startup only. This allows for state that persists between turns
Michael Pavone <pavone@retrodev.com>
parents:
69
diff
changeset
|
768 //use it to skip global init on subsequent runthroughs |
5f44ac1bcbd6
Add support for a special notFirst? variable so that globals can be initialized on startup only. This allows for state that persists between turns
Michael Pavone <pavone@retrodev.com>
parents:
69
diff
changeset
|
769 prog add: (inst: "JEQ" #[ |
5f44ac1bcbd6
Add support for a special notFirst? variable so that globals can be initialized on startup only. This allows for state that persists between turns
Michael Pavone <pavone@retrodev.com>
parents:
69
diff
changeset
|
770 "main" |
5f44ac1bcbd6
Add support for a special notFirst? variable so that globals can be initialized on startup only. This allows for state that persists between turns
Michael Pavone <pavone@retrodev.com>
parents:
69
diff
changeset
|
771 (mem: 0) |
5f44ac1bcbd6
Add support for a special notFirst? variable so that globals can be initialized on startup only. This allows for state that persists between turns
Michael Pavone <pavone@retrodev.com>
parents:
69
diff
changeset
|
772 1 |
5f44ac1bcbd6
Add support for a special notFirst? variable so that globals can be initialized on startup only. This allows for state that persists between turns
Michael Pavone <pavone@retrodev.com>
parents:
69
diff
changeset
|
773 ]) |
5f44ac1bcbd6
Add support for a special notFirst? variable so that globals can be initialized on startup only. This allows for state that persists between turns
Michael Pavone <pavone@retrodev.com>
parents:
69
diff
changeset
|
774 prog add: (inst: "MOV" #[ |
5f44ac1bcbd6
Add support for a special notFirst? variable so that globals can be initialized on startup only. This allows for state that persists between turns
Michael Pavone <pavone@retrodev.com>
parents:
69
diff
changeset
|
775 (mem: 0) |
5f44ac1bcbd6
Add support for a special notFirst? variable so that globals can be initialized on startup only. This allows for state that persists between turns
Michael Pavone <pavone@retrodev.com>
parents:
69
diff
changeset
|
776 1 |
5f44ac1bcbd6
Add support for a special notFirst? variable so that globals can be initialized on startup only. This allows for state that persists between turns
Michael Pavone <pavone@retrodev.com>
parents:
69
diff
changeset
|
777 ]) |
5f44ac1bcbd6
Add support for a special notFirst? variable so that globals can be initialized on startup only. This allows for state that persists between turns
Michael Pavone <pavone@retrodev.com>
parents:
69
diff
changeset
|
778 |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
779 //define symbols for all registers |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
780 //for low level shenanigans |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
781 i <- 0 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
782 while: { i < 9 } do: { |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
783 r <- reg: i |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
784 syms define: (string: r) r |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
785 i <- i + 1 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
786 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
787 //define symbols for interrupt return values |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
788 syms define: "xCoord" (reg: 0) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
789 syms define: "yCoord" (reg: 1) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
790 syms define: "vitality" (reg: 0) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
791 syms define: "direction" (reg: 1) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
792 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
793 //process top level assignments |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
794 foreach: (outer messages) :idx msg { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
795 if: (msg nodeType) = (ast assignment) { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
796 def <- msg assign |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
797 sym <- (msg to) name |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
798 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
799 if: (def nodeType) = (ast lambda) { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
800 functions set: sym def |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
801 syms define: sym sym |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
802 } else: { |
72
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
803 if: (def nodeType) != (ast intlit) || (def val) != 0{ |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
804 preserveTemps: { |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
805 compileExpr: msg syms: syms |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
806 } |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
807 } else: { |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
808 syms define: sym (mem: _nextVar) |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
809 _nextVar <- _nextVar + 1 |
a2a5d80abaa0
Add and as a function to gqc to work around parser limitations
Michael Pavone <pavone@retrodev.com>
parents:
70
diff
changeset
|
810 } |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
811 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
812 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
813 error: "Only assignments are allowed at the top level" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
814 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
815 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
816 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
817 functions ifget: "main" :def { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
818 prog setLabel: "main" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
819 _compileFun: "main" def syms |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
820 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
821 error: "Program must have a main function!" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
822 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
823 prog add: (inst: "HLT" #[]) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
824 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
825 foreach: functions :name def { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
826 if: name != "main" { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
827 prog setLabel: name |
56
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
828 _compileFun: name def syms |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
829 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
830 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
831 print: prog |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
832 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
833 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
834 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
835 compileFile <- :filename { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
836 f <- file open: filename |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
837 compile: (f readAll) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
838 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
839 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
840 main <- :args { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
841 if: (args length) > 1 { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
842 compileFile: (args get: 1) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
843 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
844 print: "Usage lmc FILE\n" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
845 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
846 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
847 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
848 } |