git @ Cat's Eye Technologies Tamsin / 3d3b382
Improve codegen/C backend just enough to compile Hello, world. Chris Pressey 10 years ago
4 changed file(s) with 56 addition(s) and 29 deletion(s). Raw diff Collapse all Expand all
242242 self.pattern = pattern
243243
244244 def __repr__(self):
245 return u"Send(%r, %r)" % (
246 self.rule,
247 self.pattern
248 )
249
250 def __str__(self):
251 return "send(%s, %s)" % (
252 self.rule,
253 self.pattern
254 )
245 return u"Send(%r, %r)" % (self.rule, self.pattern)
246
247 def __str__(self):
248 return "send(%s, %s)" % (self.rule, self.pattern)
255249
256250
257251 class Set(AST):
1414 GetVar, SetVar, Unifier, PatternMatch,
1515 DeclState, SaveState, RestoreState,
1616 )
17 from tamsin.ast import AtomNode # bah
1718 from tamsin.term import Atom, Constructor, Variable
1819 import tamsin.sysmod
1920
115116 self.indent_ -= 1
116117
117118 def emit(self, *args):
119 s = " " * self.indent_ + ''.join(args)
120 self.outfile.write(s)
121
122 def emitln(self, *args):
118123 s = " " * self.indent_ + ''.join(args) + "\n"
119124 self.outfile.write(s)
125
126 # kontinue the line
127 def emitk(self, *args):
128 self.outfile.write(''.join(args))
129
130 def emitkln(self, *args):
131 self.outfile.write(''.join(args) + "\n")
120132
121133 def go(self):
122134 self.outfile.write(PRELUDE)
128140 for arg in codenode.args:
129141 self.traverse(arg)
130142 elif isinstance(codenode, Prototype):
131 self.emit("void prod_%s_%s(%s);" % (
143 self.emitln("void prod_%s_%s(%s);" % (
132144 codenode['module'].name, codenode['prod'].name,
133145 ', '.join(["const struct term *"
134146 for f in codenode['formals']])
139151 fmls.append("const struct term *i%s" % i)
140152 fmls = ', '.join(fmls)
141153
142 self.emit("void prod_%s_%s(%s) {" %
154 self.emitln("void prod_%s_%s(%s) {" %
143155 (codenode['module'].name, codenode['prod'].name, fmls)
144156 )
145157 self.indent()
146158 for arg in codenode.args:
147159 self.traverse(arg)
148160 self.outdent()
149 self.emit("}")
161 self.emitln("}")
150162 elif isinstance(codenode, Unifier):
151 self.emit("/* %r */" % codenode)
163 self.emitln("/* %r */" % codenode)
152164 elif isinstance(codenode, If):
153165 self.emit("if (")
154166 self.traverse(codenode[0])
155 self.emit(") {")
167 self.emitkln(") {")
168 self.indent()
156169 self.traverse(codenode[1])
157 self.emit("} else {")
170 self.outdent()
171 self.emitln("} else {")
172 self.indent()
158173 self.traverse(codenode[2])
159 self.emit("}")
174 self.outdent()
175 self.emitln("}")
160176 elif isinstance(codenode, Not):
161 self.emit("(!(")
177 self.emitk("(!(")
162178 self.traverse(codenode[0])
163 self.emit("))")
179 self.emitk("))")
164180 elif isinstance(codenode, Truth):
165 self.emit("1")
181 self.emitk("1")
166182 elif isinstance(codenode, Block):
167183 for arg in codenode.args:
168184 self.traverse(arg)
169185 elif isinstance(codenode, Builtin):
170 self.emit("/* %r */" % codenode)
186 self.emitln("/* %r */" % codenode)
187 if codenode['name'] == 'print':
188 self.emit("result = ")
189 self.traverse(codenode[0])
190 self.emitkln(';')
191 self.emitln("term_fput(result, stdout);")
192 self.emitln(r'fwrite("\n", 1, 1, stdout);')
193 self.emitln("ok = 1;")
194 elif codenode['name'] == 'return':
195 self.emit("result = ")
196 self.traverse(codenode[0])
197 self.emitkln(';')
198 else:
199 raise NotImplementedError(repr(codenode))
200 elif isinstance(codenode, AtomNode):
201 self.emitk('term_new_atom_from_cstring("%s")' % codenode.text)
171202 elif isinstance(codenode, Return):
172 self.emit("return ")
173 self.traverse(codenode[0])
203 self.emitln("return;")
174204 elif isinstance(codenode, NoMatch):
175 self.emit("/* %r */" % codenode)
205 self.emitln('result = term_new_atom_from_cstring'
206 '("No \'%s\' production matched arguments ");' %
207 codenode['prod'].name)
208 for i in xrange(0, len(codenode['formals'])):
209 self.emitln('result = term_concat(result, term_flatten(i%d));' % i)
210 self.emitln('result = term_concat(result, term_new_atom_from_cstring(", "));')
211 self.emitln("ok = 0;")
176212 else:
177213 raise NotImplementedError(repr(codenode))
178214
156156
157157 return Unifier(prod.all_pattern_variables)
158158
159 def gen_no_match(self, module, prod, formals):
160 return NoMatch(module, prod, formals)
161
162159 def gen_branches(self, module, prod, branches):
163160 if not branches:
164 return Return(NoMatch(module, prod))
161 return NoMatch(module=module, prod=prod, formals=[])
165162 branch = branches[0]
166163 branches = branches[1:]
167164 test = Truth()
164164 self.current_branch = branch
165165 self.compile_r(branch)
166166 self.current_branch = None
167
167
168168 self.emit('result = term_new_atom_from_cstring'
169169 '("No \'%s\' production matched arguments ");' %
170170 self.current_prod.name)