git @ Cat's Eye Technologies Tamsin / 5b3d5b1
Elaborate on the codegen/backend a bit. Chris Pressey 10 years ago
3 changed file(s) with 68 addition(s) and 21 deletion(s). Raw diff Collapse all Expand all
99 """
1010
1111 from tamsin.codegen import (
12 CodeNode, Program, Prototype, Subroutine, Block, GetVar, Unifier, If
12 CodeNode, Program, Prototype, Subroutine,
13 Block, If, And, Not, Return, Builtin, Call, NoMatch, Truth,
14 GetVar, SetVar, Unifier, PatternMatch,
15 DeclState, SaveState, RestoreState,
1316 )
1417 from tamsin.term import Atom, Constructor, Variable
1518 import tamsin.sysmod
141144 )
142145 self.indent()
143146 for arg in codenode.args:
144 self.emit("/* %r */" % arg)
147 self.traverse(arg)
145148 self.outdent()
146149 self.emit("}")
150 elif isinstance(codenode, Unifier):
151 self.emit("/* %r */" % codenode)
152 elif isinstance(codenode, If):
153 self.emit("if (")
154 self.traverse(codenode[0])
155 self.emit(") {")
156 self.traverse(codenode[1])
157 self.emit("} else {")
158 self.traverse(codenode[2])
159 self.emit("}")
160 elif isinstance(codenode, Not):
161 self.emit("(!(")
162 self.traverse(codenode[0])
163 self.emit("))")
164 elif isinstance(codenode, Truth):
165 self.emit("1")
166 elif isinstance(codenode, Block):
167 for arg in codenode.args:
168 self.traverse(arg)
169 elif isinstance(codenode, Builtin):
170 self.emit("/* %r */" % codenode)
171 elif isinstance(codenode, Return):
172 self.emit("return ")
173 self.traverse(codenode[0])
174 elif isinstance(codenode, NoMatch):
175 self.emit("/* %r */" % codenode)
147176 else:
148177 raise NotImplementedError(repr(codenode))
149178
55 from tamsin import ast as ack
66 from tamsin.term import Atom, Constructor, Variable
77 import tamsin.sysmod
8
9
10 # TODO: is this module responsible for allocating names, or is the backend?
11 # I think it should probably be this module.
812
913
1014 class CodeNode(object):
4448 pass
4549
4650
51 class If(CodeNode):
52 pass
53
54
55 class And(CodeNode):
56 pass
57
58
59 class Not(CodeNode):
60 pass
61
62
4763 class GetVar(CodeNode):
4864 pass
4965
5066
67 class SetVar(CodeNode):
68 pass
69
70
5171 class Unifier(CodeNode):
5272 pass
5373
5474
55 class If(CodeNode):
56 pass
57
58
59 class And(CodeNode):
60 pass
61
62
63 class Not(CodeNode):
64 pass
65
66
6775 class PatternMatch(CodeNode):
6876 pass
6977
96104 pass
97105
98106
99 class SetVar(CodeNode):
100 pass
107 class Truth(CodeNode):
108 pass
109
110
111 ## === ##
101112
102113
103114 class CodeGen(object):
151162 def gen_branches(self, module, prod, branches):
152163 if not branches:
153164 return Return(NoMatch(module, prod))
154 test = Not()
155 #for fml_num in xrange(0, len(branch.formals)):
156 # self.emit(" term_match_unifier(%s, i%s, unifier) &&" %
157 # (pat_names[fml_num], fml_num)
158 # )
159165 branch = branches[0]
160166 branches = branches[1:]
167 test = Truth()
168 for fml_num in xrange(0, len(branch.formals)):
169 p = PatternMatch()
170 # self.emit(" term_match_unifier(%s, i%s, unifier) &&" %
171 # (pat_names[fml_num], fml_num)
172 # )
173 if not test:
174 test = p
175 else:
176 test = And(test, p)
161177 return If(test,
162178 self.gen_branch(module, prod, branch),
163179 self.gen_branches(module, prod, branches)
44
55 # Generates a C-language program which, when linked with -ltamsin, has
66 # the same (we hope) behaviour as interpreting the input Tamsin program.
7
8 # Will be DEPRECATED by tamsin.codegen and tamsin.backends.c soon, hopefully.
79
810 from tamsin.ast import (
911 Production, ProdBranch,