annotate code/gqc.tp @ 72:a2a5d80abaa0

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