<s> from dsltools import NestedBlocks <EOL> from . . import syntax , names <EOL> from . . ndtypes import ( make_tuple_type , <EOL> Int32 , Int64 , SliceT , TupleT , ScalarT , StructT , NoneT , <EOL> ArrayT , FnT , ClosureT , NoneType ) <EOL> from . . syntax import ( Assign , Return , If , <EOL> ArrayView , Attribute , Cast , Const , Closure , Comment , Expr , <EOL> Index , PrimCall , Struct , Slice , Tuple , TupleProj , TypedFn , Var , <EOL> AllocArray , ArrayExpr , Adverb , Select ) <EOL> from . . syntax . helpers import ( const_bool , const_int , get_types , <EOL> one_i64 , zero , none ) <EOL> class CoreBuilder ( object ) : <EOL> none = syntax . none <EOL> null_slice = syntax . slice_none <EOL> def __init__ ( self , type_env = None , blocks = None ) : <EOL> if type_env is None : <EOL> type_env = { } <EOL> self . type_env = type_env <EOL> if blocks is None : <EOL> blocks = NestedBlocks ( ) <EOL> self . blocks = blocks <EOL> self . tuple_elt_cache = { } <EOL> def insert_stmt ( self , stmt ) : <EOL> self . blocks . append_to_current ( stmt ) <EOL> def append ( self , stmt ) : <EOL> self . blocks . append_to_current ( stmt ) <EOL> def comment ( self , text ) : <EOL> self . blocks . append ( Comment ( text ) ) <EOL> def assign ( self , lhs , rhs ) : <EOL> self . insert_stmt ( Assign ( lhs , rhs ) ) <EOL> def return_ ( self , value ) : <EOL> self . blocks += [ Return ( value ) ] <EOL> def return_none ( self ) : <EOL> self . return_ ( none ) <EOL> def return_tuple ( self , values ) : <EOL> self . return_ ( self . tuple ( values , name = None ) ) <EOL> def fresh_var ( self , t , prefix = "<STR_LIT>" ) : <EOL> assert prefix is not None <EOL> assert t is not None , "<STR_LIT>" % prefix <EOL> prefix = names . original ( prefix ) <EOL> ssa_id = names . fresh ( prefix ) <EOL> self . type_env [ ssa_id ] = t <EOL> return Var ( ssa_id , type = t ) <EOL> def if_ ( self , cond , true_thunk , false_thunk , result_vars = ( ) ) : <EOL> """<STR_LIT>""" <EOL> merge = { } <EOL> assert all ( expr . __class__ is Var for expr in result_vars ) <EOL> left_vars = [ ] <EOL> right_vars = [ ] <EOL> for result_var in result_vars : <EOL> name = result_var . name <EOL> t = result_var . type <EOL> left_var = self . fresh_var ( t , prefix = "<STR_LIT>" + names . original ( name ) ) <EOL> left_vars . append ( left_var ) <EOL> right_var = self . fresh_var ( t , prefix = "<STR_LIT>" + names . original ( name ) ) <EOL> right_vars . append ( right_var ) <EOL> merge [ result_var . name ] = ( left_var , right_var ) <EOL> self . blocks . push ( ) <EOL> true_thunk ( * left_vars ) <EOL> true_block = self . blocks . pop ( ) <EOL> self . blocks . push ( ) <EOL> false_thunk ( * right_vars ) <EOL> false_block = self . blocks . pop ( ) <EOL> stmt = If ( cond , true_block , false_block , merge = merge ) <EOL> self . insert_stmt ( stmt ) <EOL> return stmt <EOL> def fresh_i32 ( self , prefix = "<STR_LIT>" ) : <EOL> return self . fresh_var ( Int32 , prefix ) <EOL> def fresh_i64 ( self , prefix = "<STR_LIT>" ) : <EOL> return self . fresh_var ( Int64 , prefix ) <EOL> def temp_name ( self , expr ) : <EOL> c = expr . __class__ <EOL> if c is PrimCall : <EOL> return expr . prim . name <EOL> elif c is Attribute : <EOL> if expr . value . __class__ is Var : <EOL> return names . original ( expr . value . name ) + "<STR_LIT:_>" + expr . name <EOL> else : <EOL> return expr . name <EOL> elif c is Attribute : <EOL> if expr . value . __class__ is Var : <EOL> return "<STR_LIT>" % ( expr . value . name , expr . name ) <EOL> else : <EOL> return expr . name <EOL> elif c is Index : <EOL> idx_t = expr . index . type <EOL> if isinstance ( idx_t , SliceT ) or ( isinstance ( idx_t , TupleT ) and any ( isinstance ( elt_t , SliceT ) for elt_t in idx_t . elt_types ) ) : <EOL> return "<STR_LIT>" <EOL> else : <EOL> return "<STR_LIT>" <EOL> elif c is TupleProj : <EOL> if expr . tuple . __class__ is Var : <EOL> original = names . original ( expr . tuple . name ) <EOL> return "<STR_LIT>" % ( original , names . versions [ original ] , expr . index ) <EOL> else : <EOL> return "<STR_LIT>" % expr . index <EOL> elif c is Var : <EOL> return names . refresh ( expr . name ) <EOL> else : <EOL> return "<STR_LIT>" <EOL> def is_simple ( self , expr ) : <EOL> c = expr . __class__ <EOL> return c is Var or c is Const or ( c is Tuple and len ( expr . elts ) == <NUM_LIT:0> ) or ( c is Struct and len ( expr . args ) == <NUM_LIT:0> ) or ( c is Closure and len ( expr . args ) == <NUM_LIT:0> ) <EOL> def is_pure ( self , expr ) : <EOL> c = expr . __class__ <EOL> return c is Var or c is Const or c is Tuple or c is Struct or c is Closure or c is AllocArray or c is ArrayView or c is PrimCall or isinstance ( expr , ArrayExpr ) or isinstance ( expr , Adverb ) <EOL> def assign_name ( self , expr , name = None ) : <EOL> if name is None : <EOL> name = self . temp_name ( expr ) <EOL> var = self . fresh_var ( expr . type , names . refresh ( name ) ) <EOL> self . assign ( var , expr ) <EOL> return var <EOL> def int ( self , x , name = None ) : <EOL> if name is None : <EOL> return const_int ( x ) <EOL> else : <EOL> return self . assign_name ( const_int ( x ) , name ) <EOL> def bool ( self , x , name = None ) : <EOL> if name is None : <EOL> return const_bool ( x ) <EOL> else : <EOL> return self . assign_name ( const_bool ( x ) , name ) <EOL> def zero ( self , t = Int32 , name = None ) : <EOL> if name is None : <EOL> return zero ( t ) <EOL> else : <EOL> return self . assign_name ( zero ( t ) , name ) <EOL> def zero_i32 ( self , name = None ) : <EOL> return self . zero ( t = Int32 , name = name ) <EOL> def zero_i64 ( self , name = None ) : <EOL> return self . zero ( t = Int64 , name = name ) <EOL> def cast ( self , expr , t ) : <EOL> if expr . type == t : <EOL> return expr <EOL> assert isinstance ( t , ScalarT ) , "<STR_LIT>" % ( expr , expr . type , t ) <EOL> return self . assign_name ( Cast ( expr , type = t ) , "<STR_LIT>" % t ) <EOL> def attr ( self , obj , field , name = None , temp = True ) : <EOL> if temp and name is None : <EOL> name = field <EOL> obj_t = obj . type <EOL> c = obj . __class__ <EOL> if c is Struct : <EOL> pos = obj_t . field_pos ( name ) <EOL> result = obj . args [ pos ] <EOL> elif c in ( ArrayView , Slice ) : <EOL> result = getattr ( obj , field ) <EOL> else : <EOL> assert isinstance ( obj_t , StructT ) , "<STR_LIT>" % ( field , obj_t ) <EOL> field_t = obj . type . field_type ( field ) <EOL> if field_t == NoneType : <EOL> result = none <EOL> else : <EOL> result = Attribute ( obj , field , type = field_t ) <EOL> if name and result . __class__ not in ( Var , Const ) : <EOL> return self . assign_name ( result , name ) <EOL> else : <EOL> return result <EOL> def is_none ( self , x ) : <EOL> return x is None or ( isinstance ( x , Expr ) and x . type . __class__ is NoneT ) <EOL> def tuple ( self , elts , name = None , explicit_struct = False ) : <EOL> if not isinstance ( elts , ( list , tuple ) ) : <EOL> elts = [ elts ] <EOL> tuple_t = make_tuple_type ( get_types ( elts ) ) <EOL> if explicit_struct : <EOL> tuple_expr = Struct ( elts , type = tuple_t ) <EOL> else : <EOL> tuple_expr = Tuple ( elts , type = tuple_t ) <EOL> if name : <EOL> result_var = self . assign_name ( tuple_expr , name ) <EOL> for ( i , elt ) in enumerate ( elts ) : <EOL> if self . is_simple ( elt ) : <EOL> self . tuple_elt_cache [ ( result_var . name , i ) ] = elt <EOL> return result_var <EOL> else : <EOL> return tuple_expr <EOL> def is_tuple ( self , x ) : <EOL> try : <EOL> return x . type . __class__ is TupleT <EOL> except : <EOL> return False <EOL> def is_array ( self , x ) : <EOL> return x . type . __class__ is ArrayT <EOL> def is_fn ( self , x ) : <EOL> return x . __class__ in ( TypedFn , Closure ) or isinstance ( x . type , ( FnT , ClosureT ) ) <EOL> def num_tuple_elts ( self , x ) : <EOL> assert self . is_tuple ( x ) <EOL> return len ( x . type . elt_types ) <EOL> def concat_tuples ( self , x , y , name = "<STR_LIT>" ) : <EOL> x_is_tuple = self . is_tuple ( x ) <EOL> y_is_tuple = self . is_tuple ( y ) <EOL> if x_is_tuple and y_is_tuple : <EOL> if self . num_tuple_elts ( x ) == <NUM_LIT:0> : <EOL> return y <EOL> elif self . num_tuple_elts ( y ) == <NUM_LIT:0> : <EOL> return x <EOL> if x_is_tuple : <EOL> x_elts = self . tuple_elts ( x ) <EOL> else : <EOL> x_elts = ( x , ) <EOL> if y_is_tuple : <EOL> y_elts = self . tuple_elts ( y ) <EOL> else : <EOL> y_elts = ( y , ) <EOL> elts = [ ] <EOL> elts . extend ( x_elts ) <EOL> elts . extend ( y_elts ) <EOL> return self . tuple ( elts , name = name ) <EOL> def tuple_proj ( self , tup , idx , explicit_struct = False ) : <EOL> assert isinstance ( idx , ( int , long ) ) <EOL> if isinstance ( tup , Tuple ) : <EOL> return tup . elts [ idx ] <EOL> elif isinstance ( tup , tuple ) : <EOL> return tup [ idx ] <EOL> elif tup . __class__ is Var and ( tup . name , idx ) in self . tuple_elt_cache : <EOL> return self . tuple_elt_cache [ ( tup . name , idx ) ] <EOL> elif explicit_struct : <EOL> return Attribute ( tup , "<STR_LIT>" % idx , type = tup . type . elt_types [ idx ] ) <EOL> else : <EOL> return TupleProj ( tup , idx , type = tup . type . elt_types [ idx ] ) <EOL> def tuple_elts ( self , tup , explicit_struct = False ) : <EOL> if not isinstance ( tup . type , TupleT ) : <EOL> return [ tup ] <EOL> nelts = len ( tup . type . elt_types ) <EOL> return tuple ( [ self . tuple_proj ( tup , i , explicit_struct = explicit_struct ) <EOL> for i in xrange ( nelts ) ] ) <EOL> def prod ( self , elts , name = None ) : <EOL> if self . is_tuple ( elts ) : <EOL> elts = self . tuple_elts ( elts ) <EOL> if len ( elts ) == <NUM_LIT:0> : <EOL> return one_i64 <EOL> else : <EOL> result = elts [ <NUM_LIT:0> ] <EOL> for e in elts [ <NUM_LIT:1> : ] : <EOL> result = self . mul ( result , e , name = name ) <EOL> return result <EOL> def select ( self , cond , true_value , false_value , name = None ) : <EOL> assert true_value . type == false_value . type <EOL> expr = Select ( cond , true_value , false_value , type = true_value . type ) <EOL> if name is None : <EOL> return expr <EOL> else : <EOL> return self . assign_name ( expr , name ) </s>
