comparison code/lmc.tp @ 3:a9a2ad99adfb

Rework lmc a bit to support labels in generated code. Add support for certain special funcall expressions, namely: if:else, isInteger? value and tail which translate to SEL ATOM CAR and CDR respectively
author Michael Pavone <pavone@retrodev.com>
date Fri, 25 Jul 2014 10:52:17 -0700
parents 71e8d638da5c
children eaf0a014d18b
comparison
equal deleted inserted replaced
2:71e8d638da5c 3:a9a2ad99adfb
1 { 1 {
2 inst <- :_name _args {
3 #{
4 name <- _name
5 args <- _args
6 translateLabels <- :labelDict {
7 missing <- #[]
8 foreach: args :idx arg {
9 if: (object does: arg understand?: "isString?") && (arg isString?) {
10 labelDict ifget: arg :translated {
11 args set: idx translated
12 } else: {
13 missing append: arg
14 }
15 }
16 }
17 missing
18 }
19 label <- ""
20 string <- {
21 (if: label != "" { ";" . label . "\n " } else: { " " }
22 ) . name . " " . (args join: " ")
23 }
24 }
25 }
26 _nextLabel <- 0
27 _setLabel <- :inst {
28 inst
29 }
30 prog <- #{
31 instructions <- #[]
32 add <- :inst {
33 instructions append: (_setLabel: inst)
34 }
35 makeLabel <- :suffix {
36 num <- _nextLabel
37 _nextLabel <- _nextLabel + 1
38 "" . num . "_" . suffix
39 }
40 labels <- dict hash
41 setLabel <- :name {
42 labels set: name pc
43 _setLabel <- :inst {
44 _setLabel <- :i { i }
45 inst label!: name
46 }
47 }
48 pc <- { instructions length }
49 print <- {
50 foreach: instructions :idx i {
51 missing <- i translateLabels: labels
52 if: (missing length) > 0 {
53 error: "Undefined labels " . (missing join: ", ") . " at address " . idx
54 }
55 print: (string: i) . "\n"
56 }
57
58 }
59 }
2 error <- :msg { 60 error <- :msg {
3 (file stderr) write: "Error - " . msg . "\n" 61 (file stderr) write: "Error - " . msg . "\n"
4 } 62 }
5 63
6 _exprHandlers <- dict hash 64 _exprHandlers <- dict hash
12 error: "Unhandled node type " . (expr nodeType) 70 error: "Unhandled node type " . (expr nodeType)
13 } 71 }
14 } 72 }
15 73
16 _exprHandlers set: (ast intlit) :expr { 74 _exprHandlers set: (ast intlit) :expr {
17 print: " LDC " . (expr val) . "\n" 75 prog add: (inst: "LDC" #[(expr val)])
18 } 76 }
19 77
20 _exprHandlers set: (ast sequence) :expr { 78 _exprHandlers set: (ast sequence) :expr {
21 count <- 0 79 count <- 0
22 foreach: (expr els) :idx el { 80 foreach: (expr els) :idx el {
24 count <- count + 1 82 count <- count + 1
25 } 83 }
26 if: (expr array?) { 84 if: (expr array?) {
27 count <- count - 1 85 count <- count - 1
28 } else: { 86 } else: {
29 print: " LDC 0\n" 87 prog add: (inst: "LDC" #[0])
30 } 88 }
31 while: { count > 0} do: { 89 while: { count > 0} do: {
32 print: " CONS\n" 90 prog add: (inst: "CONS" #[])
33 count <- count - 1 91 count <- count - 1
34 } 92 }
35 } 93 }
36 94
37 _opNames <- dict hash 95 _opNames <- dict hash
50 compileExpr: (expr right) 108 compileExpr: (expr right)
51 } else: { 109 } else: {
52 compileExpr: (expr right) 110 compileExpr: (expr right)
53 compileExpr: (expr left) 111 compileExpr: (expr left)
54 } 112 }
55 _opNames ifget: (expr op) :inst { 113 _opNames ifget: (expr op) :i {
56 print: " " . inst . "\n" 114 prog add: (inst: i #[])
57 } else: { 115 } else: {
58 error: "operator " . (expr op) . " is not supported" 116 error: "operator " . (expr op) . " is not supported"
117 }
118 }
119
120 _funHandlers <- dict hash
121 _funHandlers set: "if:else" :args {
122 compileExpr: (args value)
123 args <- args tail
124 tlabel <- prog makeLabel: "true"
125 flabel <- prog makeLabel: "false"
126 prog add: (inst: "SEL" #[
127 tlabel
128 flabel
129 ])
130 prog setLabel: tlabel
131 foreach: ((args value) expressions) :idx expr {
132 compileExpr: expr
133 }
134 args <- args tail
135 prog setLabel: flabel
136 foreach: ((args value) expressions) :idx expr {
137 compileExpr: expr
138 }
139 }
140 _funHandlers set: "isInteger?" :args {
141 compileExpr: (args value)
142 prog add: (inst: "ATOM" #[])
143 }
144 _funHandlers set: "value" :args {
145 compileExpr: (args value)
146 prog add: (inst: "CAR" #[])
147 }
148 _funHandlers set: "tail" :args {
149 compileExpr: (args value)
150 prog add: (inst: "CDR" #[])
151 }
152
153 _exprHandlers set: (ast call) :expr {
154 tc <- (expr tocall)
155 if: (tc nodeType) = (ast sym) {
156 _funHandlers ifget: (tc name) :handler {
157 handler: (expr args)
158 } else: {
159 error: "function calls not implemented yet"
160 }
161 } else: {
162 error: "call expression to value not implemented yet - " . tc
59 } 163 }
60 } 164 }
61 #{ 165 #{
62 compile <- :code { 166 compile <- :code {
63 res <- parser top: code 167 res <- parser top: code
74 } 178 }
75 foreach: (main_fun expressions) :idx expr { 179 foreach: (main_fun expressions) :idx expr {
76 compileExpr: expr 180 compileExpr: expr
77 } 181 }
78 foreach: others :name fun { 182 foreach: others :name fun {
79 print: ";" . name . "\n" 183 prog setLabel: name
80 foreach: (fun expressions) :idx expr { 184 foreach: (fun expressions) :idx expr {
81 compileExpr: expr 185 compileExpr: expr
82 } 186 }
83 } 187 }
188 print: prog
84 } else: { 189 } else: {
85 error: "Parse failed!" 190 error: "Parse failed!"
86 } 191 }
87 } 192 }
88 193