Mercurial > repos > icfp2014
annotate code/gqc.tp @ 69:8a0f1447c034
Implement plain if in gqc and use it in ghost0. This provides a small improvement in code size
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 27 Jul 2014 23:19:23 -0700 |
parents | 76570158a6e9 |
children | 5f44ac1bcbd6 |
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 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
91 _nextVar <- 0 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
92 //a and b are reserved for int/return values |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
93 //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
|
94 _allTemp <- [ |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
95 reg: 2 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
96 reg: 3 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
97 reg: 4 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
98 reg: 5 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
99 reg: 6 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
100 ] |
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
|
101 _tempRegs <- _allTemp |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
102 |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
103 getTemp <- { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
104 if: (_tempRegs empty?) { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
105 //out of regs, use memory |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
106 loc <- _nextVar |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
107 _nextVar <- _nextVar + 1 |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
108 mem: loc |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
109 } else: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
110 r <- _tempRegs value |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
111 _tempRegs <- _tempRegs tail |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
112 r |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
113 } |
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 preserveTemps <- :fun { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
117 saveTempRegs <- _tempRegs |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
118 res <- fun: |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
119 _tempRegs <- saveTempRegs |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
120 res |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
121 } |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
122 |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
123 _exprHandlers <- dict hash |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
124 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
125 compileExpr:syms <- :expr :syms { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
126 _exprHandlers ifget: (expr nodeType) :handler { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
127 handler: expr syms |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
128 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
129 error: "Unhandled node type " . (expr nodeType) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
130 } |
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 _exprHandlers set: (ast intlit) :expr syms { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
134 expr val |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
135 } |
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 _opNames <- dict hash |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
138 _opNames set: "+" "ADD" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
139 _opNames set: "-" "SUB" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
140 _opNames set: "*" "MUL" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
141 _opNames set: "/" "DIV" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
142 _opNames set: "and" "AND" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
143 _opNames set: "or" "OR" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
144 _opNames set: "xor" "XOR" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
145 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
146 _exprHandlers set: (ast binary) :expr syms { |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
147 l <- 0 |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
148 r <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
149 l <- compileExpr: (expr left) syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
150 compileExpr: (expr right) syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
151 } |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
152 dest <- l |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
153 if: (reg?: l) { |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
154 //reallocate temp register used by l |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
155 //not always safe, needs work |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
156 _tempRegs <- _tempRegs filter: :r { r != l } |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
157 } else: { |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
158 dest <- getTemp: |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
159 prog add: (inst: "MOV" #[ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
160 dest |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
161 l |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
162 ]) |
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 _opNames ifget: (expr op) :i { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
165 prog add: (inst: i #[ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
166 dest |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
167 r |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
168 ]) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
169 dest |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
170 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
171 error: "operator " . (expr op) . " is not supported" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
172 } |
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 _exprHandlers set: (ast sym) :expr syms { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
176 syms ifDefined: (expr name) :info { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
177 info def |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
178 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
179 error: "symbol " . (expr name) . " is not defined" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
180 } |
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 _exprHandlers set: (ast assignment) :expr syms { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
184 sym <- expr to |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
185 syms ifDefined: (sym name) :info { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
186 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
187 syms define: (sym name) (mem: _nextVar) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
188 _nextVar <- _nextVar + 1 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
189 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
190 info <- syms find: (sym name) else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
191 error: "this should never happen!" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
192 } |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
193 v <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
194 compileExpr: (expr assign) syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
195 } |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
196 dest <- info def |
67
76570158a6e9
Small optimization, avoid redundant MOV instructions
Michael Pavone <pavone@retrodev.com>
parents:
65
diff
changeset
|
197 if: dest != v { |
76570158a6e9
Small optimization, avoid redundant MOV instructions
Michael Pavone <pavone@retrodev.com>
parents:
65
diff
changeset
|
198 prog add: (inst: "MOV" #[ |
76570158a6e9
Small optimization, avoid redundant MOV instructions
Michael Pavone <pavone@retrodev.com>
parents:
65
diff
changeset
|
199 dest |
76570158a6e9
Small optimization, avoid redundant MOV instructions
Michael Pavone <pavone@retrodev.com>
parents:
65
diff
changeset
|
200 v |
76570158a6e9
Small optimization, avoid redundant MOV instructions
Michael Pavone <pavone@retrodev.com>
parents:
65
diff
changeset
|
201 ]) |
76570158a6e9
Small optimization, avoid redundant MOV instructions
Michael Pavone <pavone@retrodev.com>
parents:
65
diff
changeset
|
202 } |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
203 dest |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
204 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
205 |
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
|
206 _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
|
207 //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
|
208 _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
|
209 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
|
210 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
|
211 } |
fde898a3cbbe
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 _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
|
213 dir <- args value |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
214 v <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
215 compileExpr: dir syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
216 } |
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
|
217 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
|
218 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
|
219 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
|
220 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
|
221 ]) |
fde898a3cbbe
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 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
|
224 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 } |
fde898a3cbbe
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 _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
|
227 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
|
228 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
|
229 } |
fde898a3cbbe
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 _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
|
231 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
|
232 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
|
233 } |
fde898a3cbbe
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 _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
|
235 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
|
236 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
|
237 } |
fde898a3cbbe
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 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
|
239 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
|
240 _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
|
241 ghostIdx <- args value |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
242 v <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
243 compileExpr: ghostIdx syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
244 } |
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
|
245 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
|
246 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
|
247 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
|
248 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
|
249 ]) |
fde898a3cbbe
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 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
|
252 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
|
253 } |
fde898a3cbbe
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 _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
|
256 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
|
257 y <- (args tail) value |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
258 preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
259 x <- compileExpr: x syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
260 y <- compileExpr: y syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
261 } |
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
|
262 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
|
263 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
|
264 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
|
265 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
|
266 ]) |
fde898a3cbbe
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 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
|
269 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
|
270 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
|
271 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
|
272 ]) |
fde898a3cbbe
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 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
|
275 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
|
276 } |
fde898a3cbbe
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 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
278 //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
|
279 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
|
280 _funHandlers set: instName :args syms { |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
281 preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
282 args <- args map: :arg { compileExpr: arg syms: syms } |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
283 } |
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
|
284 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
|
285 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
286 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
287 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
288 _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
|
289 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
|
290 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
|
291 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
292 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
|
293 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
|
294 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
|
295 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
|
296 |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
297 l <- 0 |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
298 r <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
299 l <- compileExpr: (cond left) syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
300 compileExpr: (cond right) syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
301 } |
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
|
302 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
303 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
|
304 //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
|
305 //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
|
306 //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
|
307 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
|
308 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
|
309 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
|
310 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
|
311 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
|
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 } 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
|
314 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
|
315 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
|
316 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
|
317 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
|
318 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
|
319 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
320 } 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
|
321 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
|
322 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
|
323 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
|
324 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
|
325 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
|
326 ]) |
fde898a3cbbe
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 } 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
|
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 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
|
330 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
|
331 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
|
332 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
|
333 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
|
334 ]) |
fde898a3cbbe
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 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
|
336 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
|
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 ]) |
fde898a3cbbe
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 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
|
340 } 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
|
341 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
|
342 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
|
343 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
|
344 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
|
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 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
|
349 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
|
350 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
|
351 ]) |
fde898a3cbbe
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 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
|
353 } 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
|
354 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
|
355 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
|
356 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
|
357 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
|
358 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
|
359 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
|
360 ]) |
fde898a3cbbe
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 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
|
362 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
|
363 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
|
364 ]) |
fde898a3cbbe
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 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
|
366 } 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
|
367 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
|
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 } |
fde898a3cbbe
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 } |
fde898a3cbbe
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 } |
fde898a3cbbe
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 } |
fde898a3cbbe
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 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
|
375 //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
|
376 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
|
377 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
|
378 //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
|
379 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
|
380 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
|
381 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
|
382 } else: { |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
383 v <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
384 compileExpr: expr syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
385 } |
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
|
386 } |
fde898a3cbbe
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 } |
fde898a3cbbe
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 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
|
389 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
|
390 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
|
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 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
|
393 } 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
|
394 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
|
395 } |
fde898a3cbbe
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 } 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
|
397 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
|
398 } |
fde898a3cbbe
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 } |
fde898a3cbbe
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 |
58
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
401 _funHandlers set: "if:else" :args syms { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
402 cond <- (args value) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
403 trueBody <- ((args tail) value) expressions |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
404 falseBody <- (((args tail) tail) value) expressions |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
405 |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
406 if: (cond nodeType) = (ast binary) { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
407 trueLbl <- prog makeLabel: "true" |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
408 falseLbl <- prog makeLabel: "false" |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
409 endLbl <- prog makeLabel: "end" |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
410 |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
411 l <- 0 |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
412 r <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
413 l <- compileExpr: (cond left) syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
414 compileExpr: (cond right) syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
415 } |
58
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
416 |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
417 ok <- true |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
418 |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
419 if: (cond op) = ">=" { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
420 prog add: (inst: "JLT" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
421 falseLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
422 l |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
423 r |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
424 ]) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
425 } else: { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
426 if: (cond op) = "<=" { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
427 prog add: (inst: "JGT" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
428 falseLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
429 l |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
430 r |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
431 ]) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
432 } else: { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
433 if: (cond op) = "!=" { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
434 prog add: (inst: "JEQ" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
435 falseLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
436 l |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
437 r |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
438 ]) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
439 } else: { |
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: "JGT" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
442 trueLbl |
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 prog add: (inst: "MOV" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
447 reg: 8 |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
448 falseLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
449 ]) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
450 } else: { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
451 if: (cond op) = "<" { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
452 prog add: (inst: "JLT" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
453 trueLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
454 l |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
455 r |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
456 ]) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
457 prog add: (inst: "MOV" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
458 reg: 8 |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
459 falseLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
460 ]) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
461 } else: { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
462 bodyLbl <- prog makeLabel: "loop_body" |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
463 if: (cond op) = "=" { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
464 prog add: (inst: "JEQ" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
465 trueLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
466 l |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
467 r |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
468 ]) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
469 prog add: (inst: "MOV" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
470 reg: 8 |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
471 falseLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
472 ]) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
473 } else: { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
474 ok <- false |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
475 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
476 } |
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 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
479 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
480 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
481 if: ok { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
482 prog setLabel: trueLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
483 //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
|
484 foreach: trueBody :idx expr { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
485 if: (expr nodeType) = (ast sym) { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
486 //allow using bare symbols to define labels |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
487 lbl <- prog makeLabel: (expr name) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
488 prog setLabel: lbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
489 syms define: (expr name) lbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
490 } else: { |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
491 v <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
492 compileExpr: expr syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
493 } |
58
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
494 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
495 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
496 prog add: (inst: "MOV" #[ |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
497 reg: 8 |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
498 endLbl |
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 prog setLabel: falseLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
501 //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
|
502 foreach: falseBody :idx expr { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
503 if: (expr nodeType) = (ast sym) { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
504 //allow using bare symbols to define labels |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
505 lbl <- prog makeLabel: (expr name) |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
506 prog setLabel: lbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
507 syms define: (expr name) lbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
508 } else: { |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
509 v <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
510 compileExpr: expr syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
511 } |
58
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
512 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
513 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
514 prog setLabel: endLbl |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
515 } else: { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
516 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
|
517 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
518 } else: { |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
519 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
|
520 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
521 } |
d35601d47db1
Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents:
56
diff
changeset
|
522 |
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
|
523 _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
|
524 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
|
525 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
|
526 |
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
|
527 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
|
528 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
|
529 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
|
530 |
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
|
531 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
|
532 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
|
533 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
|
534 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
|
535 } |
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
|
536 |
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
|
537 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
|
538 |
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
|
539 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
|
540 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
|
541 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
|
542 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
|
543 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
|
544 ]) |
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 } 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
|
546 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
|
547 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
|
548 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
|
549 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
|
550 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
|
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 } 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
|
553 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
|
554 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
|
555 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
|
556 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
|
557 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
|
558 ]) |
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 } 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
|
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: "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
|
562 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
|
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 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
|
567 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
|
568 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
|
569 ]) |
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 } 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
|
571 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
|
572 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
|
573 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
|
574 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
|
575 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
|
576 ]) |
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 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
|
578 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
|
579 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
|
580 ]) |
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 } 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
|
582 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
|
583 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
|
584 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
|
585 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
|
586 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
|
587 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
|
588 ]) |
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 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
|
590 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
|
591 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
|
592 ]) |
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 } 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
|
594 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
|
595 } |
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 } |
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 } |
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 } |
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 } |
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 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
|
602 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
|
603 //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
|
604 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
|
605 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
|
606 //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
|
607 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
|
608 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
|
609 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
|
610 } 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
|
611 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
|
612 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
|
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 } |
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 } |
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 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
|
617 } 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
|
618 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
|
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 } 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
|
621 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
|
622 } |
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 } |
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 |
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
|
625 _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
|
626 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
|
627 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
|
628 _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
|
629 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
|
630 } 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
|
631 syms ifDefined: (tc name) :info { |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
632 funArgs <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
633 (expr args) map: :arg { compileExpr: arg syms: syms} |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
634 } |
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
|
635 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
636 //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
|
637 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
|
638 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
|
639 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
640 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
|
641 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
|
642 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
|
643 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
|
644 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
|
645 ]) |
fde898a3cbbe
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 } |
fde898a3cbbe
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 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
|
648 //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
|
649 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
|
650 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
|
651 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
|
652 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
|
653 ]) |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
654 //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
|
655 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
|
656 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
|
657 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
|
658 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
|
659 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
|
660 //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
|
661 //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
|
662 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
|
663 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
|
664 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
|
665 ]) |
fde898a3cbbe
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 } 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
|
667 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
|
668 } |
fde898a3cbbe
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 } |
fde898a3cbbe
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 //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
|
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 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
|
673 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
|
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 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
|
676 //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
|
677 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
|
678 |
fde898a3cbbe
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 //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
|
680 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
|
681 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
|
682 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
|
683 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
|
684 ]) |
fde898a3cbbe
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 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
|
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 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
|
688 } 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
|
689 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
|
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 } |
fde898a3cbbe
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 } 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
|
693 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
|
694 } |
fde898a3cbbe
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 |
fde898a3cbbe
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 |
fde898a3cbbe
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 _compileFun <- :fName fun globsyms { |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
699 syms <- symbols tableWithParent: globsyms |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
700 |
65
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
701 preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
702 foreach: (fun args) :idx arg { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
703 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
|
704 r <- getTemp: |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
705 syms define: argname r |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
706 } |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
707 |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
708 lastexpr <- ((fun expressions) length) - 1 |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
709 |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
710 //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
|
711 foreach: (fun expressions) :idx expr { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
712 if: idx != lastexpr && (expr nodeType) = (ast sym) { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
713 //allow using bare symbols to define labels |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
714 prog setLabel: (expr name) |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
715 syms define: (expr name) (expr name) |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
716 } else: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
717 v <- preserveTemps: { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
718 compileExpr: expr syms: syms |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
719 } |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
720 if: idx = lastexpr && (fName != "main") { |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
721 //move result to a register |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
722 prog add: (inst: "MOV" #[ |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
723 reg: 0 |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
724 v |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
725 ]) |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
726 //return instruction |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
727 prog add: (inst: "MOV" #[ |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
728 reg: 8 |
2a5d7308e1df
Cleanup handling of temporaries in gqc
Michael Pavone <pavone@retrodev.com>
parents:
58
diff
changeset
|
729 mem: (reg: 7) |
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 } |
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
|
732 } |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
733 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
734 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
735 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
736 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
737 #{ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
738 compile <- :code { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
739 res <- parser top: code |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
740 if: res { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
741 outer <- res yield |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
742 functions <- dict hash |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
743 syms <- symbols table |
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
|
744 //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
|
745 //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
|
746 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
|
747 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
|
748 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
|
749 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
|
750 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
|
751 } |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
752 //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
|
753 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
|
754 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
|
755 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
|
756 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
|
757 |
fde898a3cbbe
Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents:
55
diff
changeset
|
758 //process top level assignments |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
759 foreach: (outer messages) :idx msg { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
760 if: (msg nodeType) = (ast assignment) { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
761 def <- msg assign |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
762 sym <- (msg to) name |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
763 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
764 if: (def nodeType) = (ast lambda) { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
765 functions set: sym def |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
766 syms define: sym sym |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
767 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
768 compileExpr: msg syms: syms |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
769 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
770 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
771 error: "Only assignments are allowed at the top level" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
772 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
773 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
774 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
775 functions ifget: "main" :def { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
776 prog setLabel: "main" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
777 _compileFun: "main" def syms |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
778 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
779 error: "Program must have a main function!" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
780 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
781 prog add: (inst: "HLT" #[]) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
782 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
783 foreach: functions :name def { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
784 if: name != "main" { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
785 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
|
786 _compileFun: name def syms |
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
787 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
788 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
789 print: prog |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
790 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
791 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
792 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
793 compileFile <- :filename { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
794 f <- file open: filename |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
795 compile: (f readAll) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
796 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
797 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
798 main <- :args { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
799 if: (args length) > 1 { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
800 compileFile: (args get: 1) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
801 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
802 print: "Usage lmc FILE\n" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
803 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
804 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
805 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
806 } |