def visit_If(self, node, **kwargs): print >>self.io, "%sif (%s): %s" % ( self.tab_str(**kwargs), pyc_vis.visit(self, node.test), self.lineno(node) ) self.tab_depth += 1 for n in node.body: pyc_vis.visit(self, n, **kwargs) self.tab_depth -= 1 if len(node.orelse) > 0: print >>self.io, "%selse: %s" % ( self.tab_str(**kwargs), self.lineno_str(node.orelse_lineno) ) self.tab_depth += 1 for n in node.orelse: pyc_vis.visit(self, n, **kwargs) self.tab_depth -= 1 #print >>self.io, "" return ""
def visit_If(self, node): (test_name, test_sir_list) = pyc_vis.visit(self, node.test) if_lineno = self.next_lineno() body_sir_list = [] for x in node.body: (dummy1, sl) = pyc_vis.visit(self, x) body_sir_list += sl #increment to account for the 'else:' line els_lineno = self.next_lineno() if len(node.orelse) > 0 else None els_sir_list = [] for x in node.orelse: (dummy2, sl) = pyc_vis.visit(self, x) els_sir_list += sl ifnode = ast.If( test = test_name, body = body_sir_list, orelse = els_sir_list, lineno = if_lineno ) if els_lineno: ifnode.orelse_lineno = els_lineno return ( None, test_sir_list + [ifnode] )
def visit_BlocDef(self, node): sir_body = [] bloc_lineno = self.next_lineno() sir_body.extend([ make_assign( var_set('False'), InjectFromBool(arg=ast.Num(n=0)), lineno = self.next_lineno() ), make_assign( var_set('True'), InjectFromBool(arg=ast.Num(n=1)), lineno = self.next_lineno() ) ]) for n in node.body: (name, sir_list) = pyc_vis.visit(self, n) sir_body += sir_list return ( BlocDef( name = node.name, body = sir_body, lineno = bloc_lineno, params = [pyc_vis.visit(self, n)[0] for n in node.params] ), [] )
def visit_Call(self, node, **kwargs): return "%s(%s)" % ( pyc_vis.visit(self, node.func), self.format_args( [pyc_vis.visit(self, arg) for arg in node.args] ) )
def default(self, node, *args, **kwargs): result = self.default_accumulator() if isinstance(node, ast.AST): result = self.default_accumulate(result, self.default_ast(node, *args, **kwargs)) for (fld, value) in ast.iter_fields(node): #print "%s => %s" % (fld, value.__class__.__name__) if isinstance(value, list): for i in range(0, len(value) ): if self.pass_fields: kwargs["field"] = fld + ("[%d]" % i) result = self.default_accumulate( result, pyc_vis.visit(self, value[i], *args, **kwargs) ) else: if self.pass_fields: kwargs["field"] = fld result = self.default_accumulate( result, pyc_vis.visit(self, value, *args, **kwargs) ) else: #print "non ast:" result = self.default_non_ast(node, *args, **kwargs) return result
def visit_HasAttr(self, node): return InjectFromBool( arg = HasAttr( obj = pyc_vis.visit(self, node.obj), attr = pyc_vis.visit(self, node.attr) ) )
def visit_IfExp(self, node): result_name = self.gen_name() (test_name, test_sir_list) = pyc_vis.visit(self, node.test) if_lineno = self.next_lineno() (body_name, body_sir_list) = pyc_vis.visit(self, node.body) body_sir_list += [self.make_assign( var_set(result_name), body_name )] els_lineno = self.next_lineno() #increment to account for the 'else:' line (els_name, els_sir_list) = pyc_vis.visit(self, node.orelse) els_sir_list += [self.make_assign( var_set(result_name), els_name )] return ( var_ref(result_name), test_sir_list + [ ast.If( test = test_name, body = body_sir_list, orelse = els_sir_list, lineno = if_lineno, orelse_lineno = els_lineno ) ] )
def visit_Assign(self, node, **kwargs): print >>self.io, "%s%s = %s %s" % ( self.tab_str(**kwargs), pyc_vis.visit(self, node.targets[0]), pyc_vis.visit(self, node.value), self.lineno(node) ) return ""
def visit_CreateClosure(self, node, **kwargs): return self.visit_func_like( node, [ pyc_vis.visit(self, node.name), pyc_vis.visit(self, node.free_vars) ] )
def visit_Assign(self, node): if len(node.targets) != 1: raise BadAss("expected singleton assign list") if isinstance(node.targets[0], ast.Name): return self.sattr(node.targets[0].id, pyc_vis.visit(self, node.value)) return make_assign(pyc_vis.visit(self, node.targets[0]), pyc_vis.visit(self, node.value))
def visit_Lambda(self, node): return Bloc( args = pyc_vis.visit(self, node.args), body = [ast.Return( value = pyc_vis.visit(self, node.body) )], klass = ast.Lambda )
def visit_Compare(self, node): if len(node.ops) != 1: raise BadAss("expected 1 compare op: %s" % dump(node) ) elif not isinstance(node.ops[0], ast.Eq) \ and not isinstance(node.ops[0], ast.NotEq) \ and not isinstance(node.ops[0], ast.Is): raise BadAss("unexpected compare context: %s" % dump(node) ) elif len(node.comparators) != 1: raise BadAss("expected 1 comparator: %s" % dump(node) ) class IsPolySwitch(PolySwitch): def no_match(self, name_typ_list): return ast.Num(0) def int_int(self, l, r): return simple_compare(ProjectToInt(arg=l), ProjectToInt(arg=r)) def bool_bool(self, l, r): return simple_compare(ProjectToBool(arg=l), ProjectToBool(arg=r)) def big_big(self, l, r): return simple_compare(ProjectToBig(arg=l), ProjectToBig(arg=r)) #end IsPolySwitch class CmpPolySwitch(IsPolySwitch): def int_bool(self, l, r): return simple_compare(ProjectToInt(arg=l), ProjectToBool(arg=r)) def bool_int(self, l, r): return simple_compare(ProjectToBool(arg=l), ProjectToInt(arg=r)) def big_big(self, l, r): return make_call( 'equal', [ ProjectToBig(arg=l), ProjectToBig(arg=r) ] ) l_name = self.gen_name() comp_name = self.gen_name() ps = IsPolySwitch() if isinstance(node.ops[0], ast.Is) else CmpPolySwitch() result = let_env( self.gen_name, lambda names: InjectFromBool(arg=polyswitch(ps, var_ref(names[0]), var_ref(names[1]))), pyc_vis.visit(self, node.left), pyc_vis.visit(self, node.comparators[0]) ) if isinstance(node.ops[0], ast.NotEq): return InjectFromBool(arg=ast.UnaryOp( op = ast.Not(), operand = IsTrue(arg=result) )) return result
def vis_fn(visitor, node, name, scope): locs = locals(node) fnscope = locs | scope return ast.FunctionDef( name=name, args=pyc_vis.visit(visitor, node.args, fnscope), body=[pyc_vis.visit(visitor, n, fnscope) for n in node.body], )
def visit_FunctionDef(self, node): return make_assign( var_set(node.name), Bloc( args = pyc_vis.visit(self, node.args), body = [pyc_vis.visit(self, n) for n in node.body], klass = ast.FunctionDef ) )
def visit_BinOp_Add(self, dummy, node): class AddPolySwitch(PolySwitch): def no_match(self, name_typ_list): return make_error( "cant add %s to %s" % ( name_typ_list[1][1], name_typ_list[0][1] ) ) def add_bools_or_ints(self, l, r): return ast.BinOp(left = l, op = ast.Add(), right = r) #int, bool => int, cast(bool, int) def int_int(self, l, r): return InjectFromInt( arg = self.add_bools_or_ints(ProjectToInt(arg=l), ProjectToInt(arg=r)) ) def int_bool(self, l, r): return InjectFromInt( arg = self.add_bools_or_ints(ProjectToInt(arg=l), CastBoolToInt(arg=ProjectToBool(arg=r))) ) def bool_bool(self, l, r): return InjectFromInt( arg = self.add_bools_or_ints( CastBoolToInt(arg=ProjectToBool(arg=l)), CastBoolToInt(arg=ProjectToBool(arg=r)) ) ) def bool_int(self, l, r): return InjectFromInt( arg = self.add_bools_or_ints( CastBoolToInt(arg=ProjectToBool(arg=l)), ProjectToInt(arg=r) ) ) def big_big(self, l, r): return InjectFromBig( arg = make_call( "add", [ProjectToBig(arg=l), ProjectToBig(arg=r)] ) ) #AddPolyswitch return let_env( self.gen_name, lambda names: polyswitch(AddPolySwitch(), var_ref(names[0]), var_ref(names[1])), pyc_vis.visit(self, node.left), pyc_vis.visit(self, node.right) )
def visit_If(self, node): return ast.If( test = let( name_gen = self.gen_name, rhs = pyc_vis.visit(self, node.test), body = lambda name: make_is_true(name) ), body = [pyc_vis.visit(self, x) for x in node.body], orelse = [pyc_vis.visit(self, x) for x in node.orelse] )
def visit_BlocDef(self, node, **kwargs): print >>self.io, "def %s(%s): %s" % ( node.name, self.format_args([n.id for n in node.params]), self.lineno(node) ) for n in node.body: pyc_vis.visit(self, n, **kwargs) return ""
def visit_IfExp(self, node): return ast.IfExp( test = let( name_gen = self.gen_name, rhs = pyc_vis.visit(self, node.test), body = lambda name: make_is_true(name) ), body = pyc_vis.visit(self, node.body), orelse = pyc_vis.visit(self, node.orelse) )
def visit_Let(self, node): (rhs_name, rhs_sir_list) = pyc_vis.visit(self, node.rhs) assign = self.make_assign( var_set(node.name.id), rhs_name ) (body_name, body_sir_list) = pyc_vis.visit(self, node.body) return ( body_name, rhs_sir_list + [assign] + body_sir_list )
def visit_Assign(self, node): if len(node.targets) != 1: raise InvalidP1("assign expected to have only one target: %r" % node) elif node.targets[0].__class__ not in set([ast.Name, ast.Subscript, ast.Attribute]): raise BadAss("assumed all targets were names, subs or attrs: %r" % ast.dump(node)) elif not isinstance(node.targets[0].ctx, ast.Store): raise BadAss("why isnt the target context store?: %r" % node) return ast.Assign( targets = [pyc_vis.visit(self, node.targets[0])], value = pyc_vis.visit(self, node.value) )
def visit_While(self, node): if len(node.orelse) > 0: raise InvalidP3("while orelse not supported: %s" % dump(node) ) return ast.While( test = let( name_gen = self.gen_name, rhs = pyc_vis.visit(self, node.test), body = lambda name: make_is_true(name) ), body = [pyc_vis.visit(self, x) for x in node.body] )
def visit_BoolOp_Or(self, dummy, node): if len(node.values) != 2: raise BadAss("expected 2 operands to bool op: %s" % ast.dump(node)) return let( name_gen = self.gen_name, rhs = pyc_vis.visit(self, node.values[0]), body = lambda name: ast.IfExp( test = make_is_true(name), body = var_ref(name), orelse = pyc_vis.visit(self, node.values[1]) ) )
def localize_lambda(self, node, mappy, lam_name): assert_valid(node) locs = locals(node) self.log(self.depth_fmt("locals: %r" % locs) ) lam_mappy = copy.copy(mappy) #dont need deep copy, its a shallow dict for loco in locs: self.map(lam_mappy, loco, Localizer.scope_fmt(lam_name, loco) ) body = [node.body] if isinstance(node, ast.Lambda) else node.body return ( pyc_vis.visit(self, node.args, lam_mappy, lam_name), [pyc_vis.visit(self, n, lam_mappy, lam_name) for n in body] )
def default(self, node, *args, **kwargs): result = self.default_accumulator() #print "%s" % node.__class__.__name__ new_node = node.__class__() for field, old_value in ast.iter_fields(node): #print "%s => %s" % (field, old_value.__class__.__name__) if isinstance(old_value, list): new_values = [] for value in old_value: if isinstance(value, ast.AST): value = pyc_vis.visit(self, value, *args, **kwargs) (value, result) = self.default_accumulate(result, value) if value is None: continue elif not isinstance(value, ast.AST): if value.__class__ not in set([list, tuple]): raise Exception("didnt expect returned value of (%s) %r" % (value.__class__.__name__, value) ) new_values.extend(value) continue new_values.append(value) setattr(new_node, field, new_values) elif isinstance(old_value, ast.AST): new_child = pyc_vis.visit(self, old_value, *args, **kwargs) (new_child, result) = self.default_accumulate(result, new_child) if not new_child is None: setattr(new_node, field, new_child) elif isinstance(old_value, int) \ or isinstance(old_value, str) \ or old_value is None: setattr(new_node, field, old_value) else: raise Exception( "didnt expect to copy field %r with class %r in node %s" % ( old_value, old_value.__class__, ast.dump(node) ) ) if result is None: return new_node else: return (new_node, result)
def visit_ClassDef(self, cd): if cd == self.root: return Seq(body=[pyc_vis.visit(self, n) for n in cd.body]) else: tmpname = pyc_gen_name.new(self.refname + "_classattr") return Seq(body=[vis_cd(self.parent, cd, tmpname, self.scope), self.sattr(cd.name, var_ref(tmpname))])
def visit_BinOp(self, node): (l_name, l_sir_list) = pyc_vis.visit(self, node.left) (r_name, r_sir_list) = pyc_vis.visit(self, node.right) result_name = self.gen_name() l_sir_list += r_sir_list l_sir_list.append(self.make_assign( var_set(result_name), ast.BinOp( left = l_name, op = node.op.__class__(), right = r_name ) )) return (var_ref(result_name), l_sir_list)
def visit_UnaryOp_USub(self, node): class USubPolySwitch(PolySwitch): def no_match(self, name_typ_list): return make_error( "cant negate %s " % (name_typ_list[0][1]) ) def make_usub(self, op): return ast.UnaryOp( op = ast.USub(), operand = op ) def int(self, op): return InjectFromInt( arg = self.make_usub(ProjectToInt(arg=op) ) ) def bool(self, op): return InjectFromInt( arg = self.make_usub(ProjectToBool(arg=op) ) ) #end USubPolySwitch return let( name_gen = self.gen_name, rhs = pyc_vis.visit(self, node.operand), body = lambda name: polyswitch(USubPolySwitch(), var_ref(name)) )
def visit_call_node(self, node): if not getattr(node, 'kwargs', None) is None \ or not getattr(node, 'starargs', None) is None \ or not getattr(node, 'keywords', None) is None: raise Exception("havent implemented kwargs or starargs") fn_args = [] sir_list = [] if hasattr(node, 'args'): for n in node.args: (name, arg_sir_list) = pyc_vis.visit(self, n) fn_args.append( name ) sir_list += arg_sir_list result_name = self.gen_name() sir_list.append(self.make_assign( var_set(result_name), node.__class__( func = node.func, args = fn_args ) )) return (var_ref(result_name), sir_list)
def visit_Module(self, node): return ( ast.Module( body = [pyc_vis.visit(self, n)[0] for n in node.body] ), [] )
def visit_List(self, node): if not isinstance(node.ctx, ast.Load): raise BadAss("unexpected context for list: %s" % (ast.dump(node)) ) list_name = self.gen_name() elements = [] for i in range(0, len(node.elts)): e = node.elts[i] elements.append(make_assign( ast.Subscript( value = var_ref(list_name), slice = ast.Index( InjectFromInt(arg=ast.Num(n=i)) ), ctx = ast.Store() ), pyc_vis.visit(self, e)) ) return Let( name = var_set(list_name), rhs = InjectFromBig( arg = ListRef( size = InjectFromInt(arg = ast.Num(n=len(node.elts) ) ) ) ), body = Seq(body = elements + [var_ref(list_name)]) )