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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }