Elaborate on the codegen/backend a bit.
Chris Pressey
10 years ago
9 | 9 | """ |
10 | 10 | |
11 | 11 | 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, | |
13 | 16 | ) |
14 | 17 | from tamsin.term import Atom, Constructor, Variable |
15 | 18 | import tamsin.sysmod |
141 | 144 | ) |
142 | 145 | self.indent() |
143 | 146 | for arg in codenode.args: |
144 | self.emit("/* %r */" % arg) | |
147 | self.traverse(arg) | |
145 | 148 | self.outdent() |
146 | 149 | 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) | |
147 | 176 | else: |
148 | 177 | raise NotImplementedError(repr(codenode)) |
149 | 178 |
5 | 5 | from tamsin import ast as ack |
6 | 6 | from tamsin.term import Atom, Constructor, Variable |
7 | 7 | 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. | |
8 | 12 | |
9 | 13 | |
10 | 14 | class CodeNode(object): |
44 | 48 | pass |
45 | 49 | |
46 | 50 | |
51 | class If(CodeNode): | |
52 | pass | |
53 | ||
54 | ||
55 | class And(CodeNode): | |
56 | pass | |
57 | ||
58 | ||
59 | class Not(CodeNode): | |
60 | pass | |
61 | ||
62 | ||
47 | 63 | class GetVar(CodeNode): |
48 | 64 | pass |
49 | 65 | |
50 | 66 | |
67 | class SetVar(CodeNode): | |
68 | pass | |
69 | ||
70 | ||
51 | 71 | class Unifier(CodeNode): |
52 | 72 | pass |
53 | 73 | |
54 | 74 | |
55 | class If(CodeNode): | |
56 | pass | |
57 | ||
58 | ||
59 | class And(CodeNode): | |
60 | pass | |
61 | ||
62 | ||
63 | class Not(CodeNode): | |
64 | pass | |
65 | ||
66 | ||
67 | 75 | class PatternMatch(CodeNode): |
68 | 76 | pass |
69 | 77 | |
96 | 104 | pass |
97 | 105 | |
98 | 106 | |
99 | class SetVar(CodeNode): | |
100 | pass | |
107 | class Truth(CodeNode): | |
108 | pass | |
109 | ||
110 | ||
111 | ## === ## | |
101 | 112 | |
102 | 113 | |
103 | 114 | class CodeGen(object): |
151 | 162 | def gen_branches(self, module, prod, branches): |
152 | 163 | if not branches: |
153 | 164 | 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 | # ) | |
159 | 165 | branch = branches[0] |
160 | 166 | 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) | |
161 | 177 | return If(test, |
162 | 178 | self.gen_branch(module, prod, branch), |
163 | 179 | self.gen_branches(module, prod, branches) |