annotate code/gqc.tp @ 58:d35601d47db1

Implement if:else in gqc
author Michael Pavone <pavone@retrodev.com>
date Sun, 27 Jul 2014 20:03:34 -0700
parents fde898a3cbbe
children 2a5d7308e1df
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 {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
2 mem <- :_addr {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
3 #{
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
4 addr <- { _addr }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
5 string <- { "[" . _addr . "]" }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
6 isReg? <- { false }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
7 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
8 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
9 reg? <- :val {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
10 (object does: val understand?: "isReg?") && (val isReg?)
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
11 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
12 reg <- :_num {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
13 #{
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
14 num <- { _num }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
15 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
16 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
17 != <- :other { (not: (reg?: other)) || _num != (other num) }
55
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
18 = <- :other { (reg?: other) && _num = (other 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 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
21 inst <- :_name _args {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
22 #{
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
23 name <- _name
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
24 args <- _args
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
25 translateLabels <- :labelDict {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
26 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
27 args <- args map: :arg {
55
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
28 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
29 labelDict get: arg else: {
55
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
30 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
31 arg
55
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
32 }
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 } 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
34 arg
55
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
35 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
36 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
37 missing
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
38 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
39 label <- ""
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
40 comment <- ""
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
41 string <- {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
42 (if: label != "" { ";" . label . "\n " } else: { " " }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
43 ) . name . " " . (args join: ", ") . (
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
44 if: comment = "" { "" } else: { " ;" . comment})
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
45 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
46 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
47 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
48 _nextLabel <- 0
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
49 _setLabel <- :inst {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
50 inst
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 prog <- #{
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
53 instructions <- #[]
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
54 add <- :inst {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
55 instructions append: (_setLabel: inst)
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
56 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
57 makeLabel <- :suffix {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
58 num <- _nextLabel
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
59 _nextLabel <- _nextLabel + 1
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
60 "" . num . "_" . suffix
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
61 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
62 labels <- dict hash
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
63 setLabel <- :name {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
64 labels set: name pc
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
65 _setLabel <- :inst {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
66 _setLabel <- :i { i }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
67 inst label!: name
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
68 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
69 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
70 pc <- { instructions length }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
71 print <- {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
72 foreach: instructions :idx i {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
73 missing <- i translateLabels: labels
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
74 if: (missing length) > 0 {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
75 error: "Undefined labels " . (missing join: ", ") . " at address " . idx
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
76 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
77 print: (string: i) . "\n"
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
78 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
79
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
80 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
81 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
82 error <- :msg {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
83 (file stderr) write: "Error - " . msg . "\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 _nextVar <- 0
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
86 //a and b are reserved for int/return values
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
87 //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
88 _allTemp <- [
55
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
89 reg: 2
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
90 reg: 3
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
91 reg: 4
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
92 reg: 5
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
93 reg: 6
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
94 ]
56
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
95 _tempRegs <- _allTemp
55
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
96
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
97 _exprHandlers <- dict hash
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
98
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
99 compileExpr:syms <- :expr :syms {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
100 _exprHandlers ifget: (expr nodeType) :handler {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
101 handler: expr syms
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
102 } else: {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
103 error: "Unhandled node type " . (expr nodeType)
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
104 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
105 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
106
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
107 _exprHandlers set: (ast intlit) :expr syms {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
108 expr val
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
109 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
110
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
111 _opNames <- dict hash
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
112 _opNames set: "+" "ADD"
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
113 _opNames set: "-" "SUB"
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
114 _opNames set: "*" "MUL"
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
115 _opNames set: "/" "DIV"
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
116 _opNames set: "and" "AND"
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
117 _opNames set: "or" "OR"
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
118 _opNames set: "xor" "XOR"
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
119
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
120 _exprHandlers set: (ast binary) :expr syms {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
121 startTempRegs <- _tempRegs
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
122 l <- compileExpr: (expr left) syms: syms
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
123 r <- compileExpr: (expr right) syms: syms
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
124 dest <- l
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
125 if: (reg?: l) {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
126 _tempRegs <- startTempRegs filter: :r { r != l }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
127 } else: {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
128 dest <- startTempRegs value
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
129 prog add: (inst: "MOV" #[
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
130 dest
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
131 l
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 _tempRegs <- startTempRegs tail
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
134 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
135 _opNames ifget: (expr op) :i {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
136 prog add: (inst: i #[
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
137 dest
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
138 r
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
139 ])
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
140 dest
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
141 } else: {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
142 error: "operator " . (expr op) . " is not supported"
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
143 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
144 }
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 sym) :expr syms {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
147 syms ifDefined: (expr name) :info {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
148 info def
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
149 } else: {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
150 error: "symbol " . (expr name) . " is not defined"
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
151 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
152 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
153
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
154 _exprHandlers set: (ast assignment) :expr syms {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
155 sym <- expr to
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
156 syms ifDefined: (sym name) :info {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
157 } else: {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
158 syms define: (sym name) (mem: _nextVar)
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
159 _nextVar <- _nextVar + 1
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
160 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
161 info <- syms find: (sym name) else: {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
162 error: "this should never happen!"
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 startTempRegs <- _tempRegs
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
165 v <- compileExpr: (expr assign) syms: syms
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
166 _tempRegs <- startTempRegs
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
167 dest <- info def
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
168 prog add: (inst: "MOV" #[
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 v
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
171 ])
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
172 dest
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
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
175 _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
176 //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
177 _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
178 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
179 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
180 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
181 _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
182 dir <- 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
183 startTempRegs <- _tempRegs
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
184 v <- compileExpr: dir syms: 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
185 _tempRegs <- startTempRegs
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
186 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
187 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
188 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
189 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
190 ])
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
191 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
192 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
193 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
194 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
195 _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
196 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
197 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
198 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
199 _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
200 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
201 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
202 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
203 _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
204 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
205 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
206 }
fde898a3cbbe 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 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
208 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
209 _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
210 ghostIdx <- 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
211 startTempRegs <- _tempRegs
fde898a3cbbe 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 v <- compileExpr: ghostIdx syms: 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 _tempRegs <- startTempRegs
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
214 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
215 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
216 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
217 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 ])
fde898a3cbbe 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 }
fde898a3cbbe 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 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
221 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
222 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
223 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
224 _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
225 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
226 y <- (args tail) 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
227 startTempRegs <- _tempRegs
fde898a3cbbe 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 x <- compileExpr: x syms: 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
229 y <- compileExpr: y syms: 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
230 _tempRegs <- startTempRegs
fde898a3cbbe 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 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
232 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
233 reg: 0
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
234 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
235 ])
fde898a3cbbe 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 }
fde898a3cbbe 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 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
238 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
239 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
240 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
241 ])
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
242 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
243 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
244 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
245 }
fde898a3cbbe 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
fde898a3cbbe 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 //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
248 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
249 _funHandlers set: instName :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
250 saveTempRegs <- _tempRegs
fde898a3cbbe 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 args <- args map: :arg { compileExpr: arg syms: 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
252 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
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
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
256 _funHandlers set: "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
257 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
258 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
259
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
260 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
261 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
262 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
263 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
264
fde898a3cbbe 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 saveTempRegs <- _tempRegs
fde898a3cbbe 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 l <- compileExpr: (cond left) syms: 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
267 r <- compileExpr: (cond right) syms: 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
268 _tempRegs <- saveTempRegs
fde898a3cbbe 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
fde898a3cbbe 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 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
271 //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
272 //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
273 //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
274 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
275 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
276 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
277 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
278 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
279 ])
fde898a3cbbe 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 } 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
281 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
282 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
283 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
284 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
285 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
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 } 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
288 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
289 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
290 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
291 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
292 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
293 ])
fde898a3cbbe 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 } 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
295 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
296 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
297 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
298 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
299 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
300 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
301 ])
fde898a3cbbe 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 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
303 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
304 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
305 ])
fde898a3cbbe 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 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
307 } 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
308 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
309 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
310 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
311 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
312 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
313 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
314 ])
fde898a3cbbe 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: "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
316 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
317 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
318 ])
fde898a3cbbe 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 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
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 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
322 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
323 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
324 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
325 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
326 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
327 ])
fde898a3cbbe 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 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
329 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
330 end
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
331 ])
fde898a3cbbe 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 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
333 } 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
334 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
335 }
fde898a3cbbe 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 }
fde898a3cbbe 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 }
fde898a3cbbe 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 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
340 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
341 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
342 //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
343 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
344 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
345 //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
346 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
347 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
348 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
349 } 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
350 saveTempRegsExpr <- _tempRegs
fde898a3cbbe 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 v <- compileExpr: expr syms: 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
352 _tempRegs <- saveTempRegsExpr
fde898a3cbbe 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 }
fde898a3cbbe 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 }
fde898a3cbbe 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 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
356 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
357 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
358 ])
fde898a3cbbe 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 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
360 } 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
361 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
362 }
fde898a3cbbe 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 } 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
364 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
365 }
fde898a3cbbe 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 }
fde898a3cbbe 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
58
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
368 _funHandlers set: "if:else" :args syms {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
369 cond <- (args value)
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
370 trueBody <- ((args tail) value) expressions
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
371 falseBody <- (((args tail) tail) value) expressions
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
372
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
373 if: (cond nodeType) = (ast binary) {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
374 trueLbl <- prog makeLabel: "true"
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
375 falseLbl <- prog makeLabel: "false"
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
376 endLbl <- prog makeLabel: "end"
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
377
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
378 saveTempRegs <- _tempRegs
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
379 l <- compileExpr: (cond left) syms: syms
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
380 r <- compileExpr: (cond right) syms: syms
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
381 _tempRegs <- saveTempRegs
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
382
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
383 ok <- true
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
384
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
385 if: (cond op) = ">=" {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
386 prog add: (inst: "JLT" #[
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
387 falseLbl
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
388 l
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
389 r
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
390 ])
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
391 } else: {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
392 if: (cond op) = "<=" {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
393 prog add: (inst: "JGT" #[
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
394 falseLbl
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
395 l
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
396 r
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
397 ])
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
398 } else: {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
399 if: (cond op) = "!=" {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
400 prog add: (inst: "JEQ" #[
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
401 falseLbl
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
402 l
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
403 r
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
404 ])
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
405 } else: {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
406 if: (cond op) = ">" {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
407 prog add: (inst: "JGT" #[
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
408 trueLbl
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
409 l
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
410 r
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
411 ])
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
412 prog add: (inst: "MOV" #[
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
413 reg: 8
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
414 falseLbl
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
415 ])
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
416 } else: {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
417 if: (cond op) = "<" {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
418 prog add: (inst: "JLT" #[
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
419 trueLbl
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
420 l
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
421 r
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
422 ])
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
423 prog add: (inst: "MOV" #[
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
424 reg: 8
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
425 falseLbl
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
426 ])
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
427 } else: {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
428 bodyLbl <- prog makeLabel: "loop_body"
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
429 if: (cond op) = "=" {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
430 prog add: (inst: "JEQ" #[
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
431 trueLbl
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
432 l
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
433 r
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
434 ])
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
435 prog add: (inst: "MOV" #[
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
436 reg: 8
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
437 falseLbl
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 ok <- false
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
441 }
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
442 }
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
443 }
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
444 }
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 }
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
447 if: ok {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
448 prog setLabel: trueLbl
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
449 //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
450 foreach: trueBody :idx expr {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
451 if: (expr nodeType) = (ast sym) {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
452 //allow using bare symbols to define labels
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
453 lbl <- prog makeLabel: (expr name)
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
454 prog setLabel: lbl
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
455 syms define: (expr name) lbl
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
456 } else: {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
457 saveTempRegsExpr <- _tempRegs
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
458 v <- compileExpr: expr syms: syms
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
459 _tempRegs <- saveTempRegsExpr
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 }
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
462 prog add: (inst: "MOV" #[
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
463 reg: 8
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
464 endLbl
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
465 ])
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
466 prog setLabel: falseLbl
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
467 //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
468 foreach: falseBody :idx expr {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
469 if: (expr nodeType) = (ast sym) {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
470 //allow using bare symbols to define labels
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
471 lbl <- prog makeLabel: (expr name)
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
472 prog setLabel: lbl
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
473 syms define: (expr name) lbl
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
474 } else: {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
475 saveTempRegsExpr <- _tempRegs
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
476 v <- compileExpr: expr syms: syms
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
477 _tempRegs <- saveTempRegsExpr
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 prog setLabel: endLbl
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
481 } else: {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
482 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
483 }
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
484 } else: {
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
485 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
486 }
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
487 }
d35601d47db1 Implement if:else in gqc
Michael Pavone <pavone@retrodev.com>
parents: 56
diff changeset
488
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
489 _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
490 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
491 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
492 _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
493 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
494 } 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
495 syms ifDefined: (tc name) :info {
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
496 saveTempRegs <- _tempRegs
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
497 funArgs <- (expr args) map: :arg { compileExpr: arg syms: 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
498 _tempRegs <- saveTempRegs
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
499
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
500 //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
501 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
502 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
503 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
504 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
505 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
506 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
507 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
508 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
509 ])
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
510 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
511 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
512 //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
513 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
514 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
515 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
516 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
517 ])
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
518 //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
519 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
520 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
521 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
522 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
523 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
524 //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
525 //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
526 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
527 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
528 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
529 ])
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
530 } 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
531 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
532 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
533 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
534 //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
535 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
536 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
537 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
538 ])
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
539 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
540 //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
541 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
542
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
543 //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
544 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
545 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
546 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
547 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
548 ])
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
549 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
550 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
551 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
552 } 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
553 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
554 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
555 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
556 } 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
557 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
558 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
559 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
560
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
561
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
562 _compileFun <- :fName fun globsyms {
55
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
563 syms <- symbols tableWithParent: globsyms
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
564
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
565 saveTempRegs <- _tempRegs
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
566 foreach: (fun args) :idx arg {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
567 argname <- (if: (arg startsWith?: ":") { arg from: 1 } else: { 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
568 r <- _tempRegs value
55
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
569 _tempRegs <- _tempRegs tail
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
570 syms define: argname r
55
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
571 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
572
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
573 lastexpr <- ((fun expressions) length) - 1
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
574
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
575 //TODO: do 2 passes for labels to allow forward references
55
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
576 foreach: (fun expressions) :idx expr {
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
577 if: idx != lastexpr && (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
578 //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
579 prog setLabel: (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
580 syms define: (expr name) (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
581 } 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
582 saveTempRegsExpr <- _tempRegs
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
583 v <- compileExpr: expr syms: 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
584 _tempRegs <- saveTempRegsExpr
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
585 if: idx = lastexpr && (fName != "main") {
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
586 //move result to a register
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
587 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
588 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
589 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
590 ])
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
591 //return instruction
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
592 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
593 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
594 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
595 ])
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
596 }
55
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
597 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
598 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
599 saveTempRegs <- _tempRegs
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
600 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
601
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
602 #{
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
603 compile <- :code {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
604 res <- parser top: code
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
605 if: res {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
606 outer <- res yield
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
607 functions <- dict hash
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
608 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
609 //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
610 //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
611 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
612 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
613 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
614 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
615 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
616 }
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
617 //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
618 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
619 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
620 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
621 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
622
fde898a3cbbe Mostly complete version of gqc. Biggest omission is if:else. Defining labels also needs work.
Michael Pavone <pavone@retrodev.com>
parents: 55
diff changeset
623 //process top level assignments
55
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
624 foreach: (outer messages) :idx msg {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
625 if: (msg nodeType) = (ast assignment) {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
626 def <- msg assign
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
627 sym <- (msg to) name
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
628
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
629 if: (def nodeType) = (ast lambda) {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
630 functions set: sym def
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
631 syms define: sym sym
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
632 } else: {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
633 compileExpr: msg syms: syms
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
634 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
635 } else: {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
636 error: "Only assignments are allowed at the top level"
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
637 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
638 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
639
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
640 functions ifget: "main" :def {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
641 prog setLabel: "main"
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
642 _compileFun: "main" def syms
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
643 } else: {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
644 error: "Program must have a main function!"
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
645 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
646 prog add: (inst: "HLT" #[])
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
647
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
648 foreach: functions :name def {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
649 if: name != "main" {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
650 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
651 _compileFun: name def syms
55
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
652 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
653 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
654 print: prog
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
655 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
656 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
657
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
658 compileFile <- :filename {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
659 f <- file open: filename
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
660 compile: (f readAll)
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
661 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
662
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
663 main <- :args {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
664 if: (args length) > 1 {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
665 compileFile: (args get: 1)
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
666 } else: {
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
667 print: "Usage lmc FILE\n"
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
668 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
669 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
670 }
194a1414e240 Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff changeset
671 }