<s> from numba import ir , errors <EOL> from . import register_rewrite , Rewrite <EOL> class Macro ( object ) : <EOL> '''<STR_LIT>''' <EOL> __slots__ = '<STR_LIT:name>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' <EOL> def __init__ ( self , name , func , callable = False , argnames = None ) : <EOL> self . name = name <EOL> self . func = func <EOL> self . callable = callable <EOL> self . argnames = argnames <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % ( self . name , self . func ) <EOL> @ register_rewrite ( '<STR_LIT>' ) <EOL> class ExpandMacros ( Rewrite ) : <EOL> """<STR_LIT>""" <EOL> def match ( self , interp , block , typemap , calltypes ) : <EOL> """<STR_LIT>""" <EOL> self . block = block <EOL> self . rewrites = rewrites = { } <EOL> for inst in block . body : <EOL> if isinstance ( inst , ir . Assign ) : <EOL> rhs = inst . value <EOL> if ( isinstance ( rhs , ir . Expr ) and rhs . op == '<STR_LIT>' <EOL> and isinstance ( rhs . func , ir . Var ) ) : <EOL> try : <EOL> const = interp . infer_constant ( rhs . func ) <EOL> except errors . ConstantInferenceError : <EOL> continue <EOL> if isinstance ( const , Macro ) : <EOL> assert const . callable <EOL> new_expr = self . _expand_callable_macro ( interp , rhs , <EOL> const , rhs . loc ) <EOL> rewrites [ rhs ] = new_expr <EOL> elif isinstance ( rhs , ir . Expr ) and rhs . op == '<STR_LIT>' : <EOL> try : <EOL> const = interp . infer_constant ( inst . target ) <EOL> except errors . ConstantInferenceError : <EOL> continue <EOL> if isinstance ( const , Macro ) and not const . callable : <EOL> new_expr = self . _expand_non_callable_macro ( const , rhs . loc ) <EOL> rewrites [ rhs ] = new_expr <EOL> return len ( rewrites ) > <NUM_LIT:0> <EOL> def _expand_non_callable_macro ( self , macro , loc ) : <EOL> """<STR_LIT>""" <EOL> intr = ir . Intrinsic ( macro . name , macro . func , args = ( ) ) <EOL> new_expr = ir . Expr . call ( func = intr , args = ( ) , <EOL> kws = ( ) , loc = loc ) <EOL> return new_expr <EOL> def _expand_callable_macro ( self , interp , call , macro , loc ) : <EOL> """<STR_LIT>""" <EOL> assert macro . callable <EOL> args = [ interp . infer_constant ( arg . name ) for arg in call . args ] <EOL> kws = { } <EOL> for k , v in call . kws : <EOL> try : <EOL> kws [ k ] = interp . infer_constant ( v ) <EOL> except errors . ConstantInferenceError : <EOL> msg = "<STR_LIT>" "<STR_LIT>" . format ( name = k , <EOL> loc = loc ) <EOL> raise ValueError ( msg ) <EOL> try : <EOL> result = macro . func ( * args , ** kws ) <EOL> except Exception as e : <EOL> msg = str ( e ) <EOL> headfmt = "<STR_LIT>" <EOL> head = headfmt . format ( line = loc ) <EOL> newmsg = "<STR_LIT>" . format ( head , msg ) <EOL> raise errors . MacroError ( newmsg ) <EOL> assert result is not None <EOL> result . loc = call . loc <EOL> new_expr = ir . Expr . call ( func = result , args = call . args , <EOL> kws = call . kws , loc = loc ) <EOL> return new_expr <EOL> def apply ( self ) : <EOL> """<STR_LIT>""" <EOL> block = self . block <EOL> rewrites = self . rewrites <EOL> for inst in block . body : <EOL> if isinstance ( inst , ir . Assign ) and inst . value in rewrites : <EOL> inst . value = rewrites [ inst . value ] <EOL> return block </s>
