def make_name(arg): if not isinstance(arg, S.Tuple): return arg else: made_name = S.Name(names.next()) assembled = S.Bind(S.Tuple(*[make_name(x) for x in arg]), made_name) disassembly.insert(0, assembled) return made_name
def _Return(self, stmt): e = self.rewrite(stmt.value()) if isinstance(e, S.Name): stmt.parameters = [e] self.emit(stmt) return # If we're returning a tuple, we always copy the value into a return # variable. We may undo this later on, for entry-point procedures. ret = S.Name("result") self.emit(S.Bind(ret, e)) stmt.parameters = [ret] self.emit(stmt)
def _Bind(self, stmt): var = stmt.binder() varNames = [x.id for x in flatten(var)] operation = S.substituted_expression(stmt.value(), self.env) for name in varNames: if name not in self.exceptions: rename = '%s_%s' % (name, self.serial.next()) else: rename = name self.env[name] = S.Name(rename) result = S.Bind(S.substituted_expression(var, self.env), operation) return result
def _Expression(self, e): subexpressions = e.parameters e.parameters = [] for sub in subexpressions: sub = self.rewrite(sub) # XXX It doesn't seem right to include Closure on this list # of "atomic" values. But phase_assignment breaks if I # don't do this. if not isinstance(sub, (S.Name, S.Literal, S.Closure)): tn = S.Name(self.names.next()) self.emit(S.Bind(tn, sub)) else: tn = sub e.parameters.append(tn) return e
def _Return(self, stmt): e = self.rewrite(stmt.value()) if isinstance(e, S.Name): # If we're returning one of the procedure formals unchanged, # we need to copy its value into a return variable. # Here is where we check: if e.id not in self.formals: #No need to copy value into a return variable stmt.parameters = [e] self.emit(stmt) return # If we're returning a tuple, we always copy the value into a return # variable. We may undo this later on, for entry-point procedures. ret = S.Name("result") self.emit(S.Bind(ret, e)) stmt.parameters = [ret] self.emit(stmt)