git @ Cat's Eye Technologies Tamsin / bea3d8b
Convert Call and Send to AST. Cat's Eye Technologies 10 years ago
5 changed file(s) with 95 addition(s) and 70 deletion(s). Raw diff Collapse all Expand all
4040 return And(self.analyze(ast.lhs), self.analyze(ast.rhs))
4141 elif isinstance(ast, Using):
4242 return Using(self.analyze(ast.lhs), ast.prodref)
43 elif ast[0] == 'CALL':
44 # ('CALL', prodref, args, ibuf)
45 prodref = ast[1]
43 elif isinstance(ast, Call):
44 prodref = ast.prodref
4645 if prodref.module == '' and prodref.name not in self.prodnames:
4746 raise ValueError("no '%s' production defined" % prodref.name)
4847 # TODO: also check builtins?
49 return ('CALL', prodref, ast[2], ast[3])
50 elif ast[0] == 'SEND':
51 return ('SEND', self.analyze(ast[1]), ast[2])
48 return ast
49 elif isinstance(ast, Send):
50 assert isinstance(ast.variable, Variable), ast
51 return Send(self.analyze(ast.rule), ast.variable)
5252 elif ast[0] == 'SET':
5353 return ast
5454 elif ast[0] == 'NOT':
6868 self.collect_locals(ast.rhs, locals_)
6969 elif isinstance(ast, Using):
7070 self.collect_locals(ast.lhs, locals_)
71 elif ast[0] == 'SEND':
72 locals_.add(ast[2].name)
71 elif isinstance(ast, Call):
72 pass
73 elif isinstance(ast, Send):
74 locals_.add(ast.variable.name)
7375 elif ast[0] == 'SET':
7476 locals_.add(ast[1].name)
7577 elif ast[0] == 'WHILE':
8383 self.rhs
8484 )
8585
86 class Call(AST):
87 def __init__(self, prodref, args, ibuf):
88 self.prodref = prodref
89 self.args = args
90 self.ibuf = ibuf
91
92 def __repr__(self):
93 return u"Call(%r, %r, %r)" % (
94 self.prodref,
95 self.args,
96 self.ibuf
97 )
98
99 class Send(AST):
100 def __init__(self, rule, variable):
101 self.rule = rule
102 self.variable = variable
103
104 def __repr__(self):
105 return u"Send(%r, %r)" % (
106 self.rule,
107 self.variable
108 )
109
86110 class Using(AST):
87111 def __init__(self, lhs, prodref):
88112 self.lhs = lhs
196196 self.emit("}")
197197 self.outdent()
198198 self.emit("}")
199 elif ast[0] == 'CALL':
200 prodref = ast[1]
199 elif isinstance(ast, Send):
200 self.compile_r(ast.rule)
201 # TODO: if ok?
202 self.emit("%s = result;" % ast.variable.name)
203 elif isinstance(ast, Call):
204 prodref = ast.prodref
201205 prodmod = prodref.module
202206 name = prodref.name
203 args = ast[2]
207 args = ast.args
204208
205209 if prodmod == '$':
206210 if name == 'expect':
239243
240244 args = ', '.join(["temp_arg%s" % p for p in xrange(0, i)])
241245 self.emit("%s_%s0(%s);" % (prodmod, name, args))
242 elif ast[0] == 'SEND':
243 self.compile_r(ast[1])
244 # TODO: if ok?
245 self.emit("%s = result;" % ast[2].name)
246246 elif ast[0] == 'SET':
247247 self.emit_term(ast[2], "temp")
248248 self.emit("result = temp;")
198198 self.context = saved_context
199199 self.scanner.install_state(saved_scanner_state)
200200 return self.interpret(ast.rhs)
201 elif isinstance(ast, Call):
202 prodref = ast.prodref
203 #prodmod = prodref[1]
204 name = prodref.name
205 args = ast.args
206 ibuf = ast.ibuf
207 prods = self.program.find_productions(prodref)
208 self.event('call_candidates', prods)
209 args = [x.expand(self.context) for x in args]
210 for prod in prods:
211 formals = prod.formals
212 self.event('call_args', formals, args)
213 if isinstance(formals, list):
214 bindings = self.match_all(formals, args)
215 self.event('call_bindings', bindings)
216 if bindings != False:
217 if ibuf is not None:
218 return self.interpret_on_buffer(
219 prod, unicode(ibuf.expand(self.context)),
220 bindings=bindings
221 )
222 else:
223 return self.interpret(prod, bindings=bindings)
224 else:
225 self.event('call_newfangled_parsing_args', prod)
226 # start a new scope. arg bindings will appear here.
227 self.context.push_scope(prod.name)
228 (success, result) = self.interpret_on_buffer(
229 formals, unicode(args[0])
230 )
231 # we do not want to start a new scope here, and we
232 # interpret the rule directly, not the prod.
233 if success:
234 self.event('begin_interpret_rule', prod.body)
235 (success, result) = self.interpret(prod.body)
236 self.event('end_interpret_rule', prod.body)
237 self.context.pop_scope(prod.name)
238 return (success, result)
239 else:
240 self.context.pop_scope(prod.name)
241 raise ValueError("No '%s' production matched arguments %r" %
242 (name, args)
243 )
244 elif isinstance(ast, Send):
245 (success, result) = self.interpret(ast.rule)
246 self.context.store(ast.variable.name, result)
247 return (success, result)
201248 elif isinstance(ast, Using):
202249 sub = ast.lhs
203250 prodref = ast.prodref
217264 self.event('leave_with', succeeded, result)
218265 self.scanner.pop_engine()
219266 return (succeeded, result)
220 elif ast[0] == 'CALL':
221 prodref = ast[1]
222 #prodmod = prodref[1]
223 name = prodref.name
224 args = ast[2]
225 ibuf = ast[3]
226 prods = self.program.find_productions(prodref)
227 self.event('call_candidates', prods)
228 args = [x.expand(self.context) for x in args]
229 for prod in prods:
230 formals = prod.formals
231 self.event('call_args', formals, args)
232 if isinstance(formals, list):
233 bindings = self.match_all(formals, args)
234 self.event('call_bindings', bindings)
235 if bindings != False:
236 if ibuf is not None:
237 return self.interpret_on_buffer(
238 prod, unicode(ibuf.expand(self.context)),
239 bindings=bindings
240 )
241 else:
242 return self.interpret(prod, bindings=bindings)
243 else:
244 self.event('call_newfangled_parsing_args', prod)
245 # start a new scope. arg bindings will appear here.
246 self.context.push_scope(prod.name)
247 (success, result) = self.interpret_on_buffer(
248 formals, unicode(args[0])
249 )
250 # we do not want to start a new scope here, and we
251 # interpret the rule directly, not the prod.
252 if success:
253 self.event('begin_interpret_rule', prod.body)
254 (success, result) = self.interpret(prod.body)
255 self.event('end_interpret_rule', prod.body)
256 self.context.pop_scope(prod.name)
257 return (success, result)
258 else:
259 self.context.pop_scope(prod.name)
260 raise ValueError("No '%s' production matched arguments %r" %
261 (name, args)
262 )
263 elif ast[0] == 'SEND':
264 (success, result) = self.interpret(ast[1])
265 assert isinstance(ast[2], Variable), ast
266 self.context.store(ast[2].name, result)
267 return (success, result)
268267 elif ast[0] == 'SET':
269268 assert isinstance(ast[1], Variable), ast
270269 assert isinstance(ast[2], Term), ast
107107 lhs = self.expr4()
108108 if self.consume(u'→') or self.consume('->'):
109109 v = self.variable()
110 lhs = ('SEND', lhs, v)
110 lhs = Send(lhs, v)
111111 return lhs
112112
113113 def expr4(self):
119119 e = self.expr0()
120120 self.expect(']')
121121 return Or(e,
122 ('CALL', Prodref('$', 'return'), [Term(u'nil')], None)
122 Call(Prodref('$', 'return'), [Term(u'nil')], None)
123123 )
124124 elif self.consume('{'):
125125 e = self.expr0()
128128 elif self.peek()[0] == '"':
129129 s = unicode(self.consume_any()[1:-1])
130130 literal = Term(s)
131 return ('CALL', Prodref('$', 'expect'), [literal], None)
131 return Call(Prodref('$', 'expect'), [literal], None)
132132 elif self.consume(u'«') or self.consume('<<'):
133133 t = self.term()
134134 if self.consume(u'»') or self.consume('>>'):
135 return ('CALL', Prodref('$', 'expect'), [t], None)
135 return Call(Prodref('$', 'expect'), [t], None)
136136 else:
137137 self.error("'>>'")
138138 elif self.consume('!'):
149149 if self.consume(u'←') or self.consume('<-'):
150150 t = self.term()
151151 else:
152 return ('CALL', Prodref('$', 'return'), [v], None)
152 return Call(Prodref('$', 'return'), [v], None)
153153 return ('SET', v, t)
154154 else:
155155 # implied return of term
156156 if self.peek()[0].isupper() or self.peek()[0] == "'":
157157 t = self.term()
158 return ('CALL', Prodref('$', 'return'), [t], None)
158 return Call(Prodref('$', 'return'), [t], None)
159159 prodref = self.prodref()
160160 args = []
161161 name = prodref.name
177177 ibuf = None
178178 if self.consume('@'):
179179 ibuf = self.term()
180 return ('CALL', prodref, args, ibuf)
180 return Call(prodref, args, ibuf)
181181
182182 def prodref(self):
183183 if self.consume('$'):