Mercurial > repos > icfp2014
annotate code/gqc.tp @ 55:194a1414e240
Partial implementation of Ghost-Quiche
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 27 Jul 2014 16:26:56 -0700 |
parents | |
children | fde898a3cbbe |
rev | line source |
---|---|
55
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
1 { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
2 mem <- :_addr { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
3 #{ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
4 addr <- { _addr } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
5 string <- { "[" . _addr . "]" } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
6 isReg? <- { false } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
7 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
8 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
9 reg? <- :val { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
10 (object does: val understand?: "isReg?") && (val isReg?) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
11 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
12 reg <- :_num { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
13 #{ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
14 num <- { _num } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
15 string <- { (#["a" "b" "c" "d" "e" "f" "g" "h" "pc"]) get: _num } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
16 isReg? <- { true } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
17 != <- :other { (reg?: other) && _num != (other num) } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
18 = <- :other { (reg?: other) && _num = (other num) } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
19 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
20 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
21 inst <- :_name _args { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
22 #{ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
23 name <- _name |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
24 args <- _args |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
25 translateLabels <- :labelDict { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
26 missing <- #[] |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
27 foreach: args :idx arg { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
28 if: (object does: arg understand?: "isString?") && (arg isString?) { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
29 labelDict ifget: arg :translated { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
30 args set: idx translated |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
31 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
32 missing append: arg |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
33 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
34 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
35 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
36 missing |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
37 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
38 label <- "" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
39 comment <- "" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
40 string <- { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
41 (if: label != "" { ";" . label . "\n " } else: { " " } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
42 ) . name . " " . (args join: ", ") . ( |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
43 if: comment = "" { "" } else: { " ;" . comment}) |
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 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
46 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
47 _nextLabel <- 0 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
48 _setLabel <- :inst { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
49 inst |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
50 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
51 prog <- #{ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
52 instructions <- #[] |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
53 add <- :inst { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
54 instructions append: (_setLabel: inst) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
55 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
56 makeLabel <- :suffix { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
57 num <- _nextLabel |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
58 _nextLabel <- _nextLabel + 1 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
59 "" . num . "_" . suffix |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
60 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
61 labels <- dict hash |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
62 setLabel <- :name { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
63 labels set: name pc |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
64 _setLabel <- :inst { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
65 _setLabel <- :i { i } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
66 inst label!: name |
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 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
69 pc <- { instructions length } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
70 print <- { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
71 foreach: instructions :idx i { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
72 missing <- i translateLabels: labels |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
73 if: (missing length) > 0 { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
74 error: "Undefined labels " . (missing join: ", ") . " at address " . idx |
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 print: (string: i) . "\n" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
77 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
78 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
79 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
80 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
81 error <- :msg { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
82 (file stderr) write: "Error - " . msg . "\n" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
83 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
84 _nextVar <- 0 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
85 //a and b are reserved for int/return values |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
86 //h is reserved as a stack pointer |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
87 _tempRegs <- [ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
88 reg: 2 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
89 reg: 3 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
90 reg: 4 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
91 reg: 5 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
92 reg: 6 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
93 ] |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
94 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
95 _exprHandlers <- dict hash |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
96 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
97 compileExpr:syms <- :expr :syms { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
98 _exprHandlers ifget: (expr nodeType) :handler { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
99 handler: expr syms |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
100 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
101 error: "Unhandled node type " . (expr nodeType) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
102 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
103 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
104 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
105 _exprHandlers set: (ast intlit) :expr syms { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
106 expr val |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
107 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
108 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
109 _opNames <- dict hash |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
110 _opNames set: "+" "ADD" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
111 _opNames set: "-" "SUB" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
112 _opNames set: "*" "MUL" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
113 _opNames set: "/" "DIV" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
114 _opNames set: "and" "AND" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
115 _opNames set: "or" "OR" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
116 _opNames set: "xor" "XOR" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
117 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
118 _exprHandlers set: (ast binary) :expr syms { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
119 startTempRegs <- _tempRegs |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
120 l <- compileExpr: (expr left) syms: syms |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
121 r <- compileExpr: (expr right) syms: syms |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
122 dest <- l |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
123 if: (reg?: l) { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
124 _tempRegs <- startTempRegs filter: :r { r != l } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
125 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
126 dest <- startTempRegs value |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
127 prog add: (inst: "MOV" #[ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
128 dest |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
129 l |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
130 ]) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
131 _tempRegs <- startTempRegs tail |
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 _opNames ifget: (expr op) :i { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
134 prog add: (inst: i #[ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
135 dest |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
136 r |
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 dest |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
139 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
140 error: "operator " . (expr op) . " is not supported" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
141 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
142 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
143 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
144 _exprHandlers set: (ast sym) :expr syms { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
145 syms ifDefined: (expr name) :info { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
146 info def |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
147 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
148 error: "symbol " . (expr name) . " is not defined" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
149 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
150 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
151 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
152 _exprHandlers set: (ast assignment) :expr syms { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
153 sym <- expr to |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
154 syms ifDefined: (sym name) :info { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
155 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
156 syms define: (sym name) (mem: _nextVar) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
157 _nextVar <- _nextVar + 1 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
158 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
159 info <- syms find: (sym name) else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
160 error: "this should never happen!" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
161 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
162 startTempRegs <- _tempRegs |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
163 v <- compileExpr: (expr assign) syms: syms |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
164 _tempRegs <- startTempRegs |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
165 dest <- info def |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
166 prog add: (inst: "MOV" #[ |
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 v |
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 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
172 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
173 _compileFun <- :name fun globsyms { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
174 syms <- symbols tableWithParent: globsyms |
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 saveTempRegs <- _tempRegs |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
177 foreach: (fun args) :idx arg { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
178 argname <- (if: (arg startsWith?: ":") { arg from: 1 } else: { arg }) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
179 reg <- _tempRegs value |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
180 _tempRegs <- _tempRegs tail |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
181 syms define: argname reg |
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 lastexpr <- ((fun expressions) length) - 1 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
185 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
186 foreach: (fun expressions) :idx expr { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
187 saveTempRegsExpr <- _tempRegs |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
188 v <- compileExpr: expr syms: syms |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
189 _tempRegs <- saveTempRegsExpr |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
190 if: idx = lastexpr && (name != "main") { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
191 //move result to a register |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
192 prog add: (inst: "MOV" #[ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
193 reg: 0 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
194 v |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
195 ]) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
196 //return instruction |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
197 prog add: (inst: "MOV" #[ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
198 reg: 8 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
199 mem: (reg: 7) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
200 ]) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
201 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
202 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
203 saveTempRegs <- _tempRegs |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
204 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
205 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
206 #{ |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
207 compile <- :code { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
208 res <- parser top: code |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
209 if: res { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
210 outer <- res yield |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
211 functions <- dict hash |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
212 syms <- symbols table |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
213 foreach: (outer messages) :idx msg { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
214 if: (msg nodeType) = (ast assignment) { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
215 def <- msg assign |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
216 sym <- (msg to) name |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
217 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
218 if: (def nodeType) = (ast lambda) { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
219 functions set: sym def |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
220 syms define: sym sym |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
221 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
222 compileExpr: msg syms: syms |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
223 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
224 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
225 error: "Only assignments are allowed at the top level" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
226 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
227 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
228 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
229 functions ifget: "main" :def { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
230 prog setLabel: "main" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
231 _compileFun: "main" def syms |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
232 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
233 error: "Program must have a main function!" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
234 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
235 prog add: (inst: "HLT" #[]) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
236 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
237 foreach: functions :name def { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
238 if: name != "main" { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
239 prog setLabel: name |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
240 _comipleFun: name def syms |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
241 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
242 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
243 print: prog |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
244 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
245 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
246 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
247 compileFile <- :filename { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
248 f <- file open: filename |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
249 compile: (f readAll) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
250 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
251 |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
252 main <- :args { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
253 if: (args length) > 1 { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
254 compileFile: (args get: 1) |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
255 } else: { |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
256 print: "Usage lmc FILE\n" |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
257 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
258 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
259 } |
194a1414e240
Partial implementation of Ghost-Quiche
Michael Pavone <pavone@retrodev.com>
parents:
diff
changeset
|
260 } |