<s> import ast <EOL> import sys <EOL> import types <EOL> from . byteplay import ( <EOL> Code , LOAD_FAST , CALL_FUNCTION , LOAD_GLOBAL , STORE_FAST , LOAD_CONST , <EOL> RETURN_VALUE , STORE_NAME , LOAD_NAME , DELETE_NAME , DELETE_FAST , SetLineno <EOL> ) <EOL> from . code_tracing import inject_tracing , inject_inversion <EOL> COMPILER_VERSION = <NUM_LIT> <EOL> STARTUP = [ '<STR_LIT>' ] <EOL> CLEANUP = [ '<STR_LIT>' ] <EOL> def update_firstlineno ( code , firstlineno ) : <EOL> """<STR_LIT>""" <EOL> return types . CodeType ( <EOL> code . co_argcount , code . co_nlocals , code . co_stacksize , code . co_flags , <EOL> code . co_code , code . co_consts , code . co_names , code . co_varnames , <EOL> code . co_filename , code . co_name , firstlineno , code . co_lnotab , <EOL> code . co_freevars , code . co_cellvars , <EOL> ) <EOL> def replace_global_loads ( codelist , explicit = None ) : <EOL> """<STR_LIT>""" <EOL> explicit = explicit or set ( ) <EOL> for idx , ( op , op_arg ) in enumerate ( codelist ) : <EOL> if op == LOAD_GLOBAL and op_arg not in explicit : <EOL> codelist [ idx ] = ( LOAD_NAME , op_arg ) <EOL> def optimize_locals ( codelist ) : <EOL> """<STR_LIT>""" <EOL> fast_locals = set ( ) <EOL> for idx , ( op , op_arg ) in enumerate ( codelist ) : <EOL> if op == STORE_NAME : <EOL> fast_locals . add ( op_arg ) <EOL> codelist [ idx ] = ( STORE_FAST , op_arg ) <EOL> for idx , ( op , op_arg ) in enumerate ( codelist ) : <EOL> if op == LOAD_NAME and op_arg in fast_locals : <EOL> codelist [ idx ] = ( LOAD_FAST , op_arg ) <EOL> elif op == DELETE_NAME and op_arg in fast_locals : <EOL> codelist [ idx ] = ( DELETE_FAST , op_arg ) <EOL> def compile_simple ( py_ast , filename ) : <EOL> """<STR_LIT>""" <EOL> code = compile ( py_ast , filename , mode = '<STR_LIT>' ) <EOL> code = update_firstlineno ( code , py_ast . lineno ) <EOL> bp_code = Code . from_code ( code ) <EOL> replace_global_loads ( bp_code . code ) <EOL> optimize_locals ( bp_code . code ) <EOL> bp_code . newlocals = False <EOL> return bp_code . to_code ( ) <EOL> def compile_notify ( py_ast , filename ) : <EOL> """<STR_LIT>""" <EOL> explicit_globals = set ( ) <EOL> for node in ast . walk ( py_ast ) : <EOL> if isinstance ( node , ast . Global ) : <EOL> explicit_globals . update ( node . names ) <EOL> code = compile ( py_ast , filename , mode = '<STR_LIT>' ) <EOL> bp_code = Code . from_code ( code ) <EOL> replace_global_loads ( bp_code . code , explicit_globals ) <EOL> optimize_locals ( bp_code . code ) <EOL> bp_code . newlocals = False <EOL> return bp_code . to_code ( ) <EOL> def compile_subscribe ( py_ast , filename ) : <EOL> """<STR_LIT>""" <EOL> code = compile ( py_ast , filename , mode = '<STR_LIT>' ) <EOL> code = update_firstlineno ( code , py_ast . lineno ) <EOL> bp_code = Code . from_code ( code ) <EOL> replace_global_loads ( bp_code . code ) <EOL> optimize_locals ( bp_code . code ) <EOL> bp_code . code = inject_tracing ( bp_code . code ) <EOL> bp_code . newlocals = False <EOL> bp_code . args = ( '<STR_LIT>' , ) + bp_code . args <EOL> return bp_code . to_code ( ) <EOL> def compile_update ( py_ast , filename ) : <EOL> """<STR_LIT>""" <EOL> code = compile ( py_ast , filename , mode = '<STR_LIT>' ) <EOL> code = update_firstlineno ( code , py_ast . lineno ) <EOL> bp_code = Code . from_code ( code ) <EOL> replace_global_loads ( bp_code . code ) <EOL> optimize_locals ( bp_code . code ) <EOL> bp_code . code = inject_inversion ( bp_code . code ) <EOL> bp_code . newlocals = False <EOL> bp_code . args = ( '<STR_LIT>' , '<STR_LIT>' ) + bp_code . args <EOL> return bp_code . to_code ( ) <EOL> def compile_delegate ( py_ast , filename ) : <EOL> """<STR_LIT>""" <EOL> code = compile ( py_ast , filename , mode = '<STR_LIT>' ) <EOL> code = update_firstlineno ( code , py_ast . lineno ) <EOL> bp_code = Code . from_code ( code ) <EOL> bp_code . newlocals = False <EOL> codelist = bp_code . code [ : ] <EOL> bp_args = tuple ( bp_code . args ) <EOL> replace_global_loads ( codelist ) <EOL> optimize_locals ( codelist ) <EOL> sub_list = inject_tracing ( codelist ) <EOL> bp_code . code = sub_list <EOL> bp_code . args = ( '<STR_LIT>' , ) + bp_args <EOL> sub_code = bp_code . to_code ( ) <EOL> upd_list = inject_inversion ( codelist ) <EOL> bp_code . code = upd_list <EOL> bp_code . args = ( '<STR_LIT>' , '<STR_LIT>' ) + bp_args <EOL> upd_code = bp_code . to_code ( ) <EOL> return ( sub_code , upd_code ) <EOL> COMPILE_OP_MAP = { <EOL> '<STR_LIT:=>' : compile_simple , <EOL> '<STR_LIT>' : compile_notify , <EOL> '<STR_LIT>' : compile_subscribe , <EOL> '<STR_LIT>' : compile_update , <EOL> '<STR_LIT>' : compile_delegate , <EOL> } <EOL> class _NodeVisitor ( object ) : <EOL> """<STR_LIT>""" <EOL> def visit ( self , node ) : <EOL> """<STR_LIT>""" <EOL> name = '<STR_LIT>' % node . __class__ . __name__ <EOL> try : <EOL> method = getattr ( self , name ) <EOL> except AttributeError : <EOL> method = self . default_visit <EOL> method ( node ) <EOL> def visit_nonstrict ( self , node ) : <EOL> """<STR_LIT>""" <EOL> name = '<STR_LIT>' % node . __class__ . __name__ <EOL> try : <EOL> method = getattr ( self , name ) <EOL> except AttributeError : <EOL> pass <EOL> else : <EOL> method ( node ) <EOL> def default_visit ( self , node ) : <EOL> """<STR_LIT>""" <EOL> raise ValueError ( '<STR_LIT>' % node ) <EOL> class EnamlDefCompiler ( _NodeVisitor ) : <EOL> """<STR_LIT>""" <EOL> @ classmethod <EOL> def compile ( cls , node , filename ) : <EOL> """<STR_LIT>""" <EOL> compiler = cls ( filename ) <EOL> compiler . visit ( node ) <EOL> return compiler . stack . pop ( ) <EOL> def __init__ ( self , filename ) : <EOL> self . filename = filename <EOL> self . stack = [ ] <EOL> def visit_EnamlDef ( self , node ) : <EOL> obj = { <EOL> '<STR_LIT:filename>' : self . filename , <EOL> '<STR_LIT>' : node . lineno , <EOL> '<STR_LIT>' : node . typename , <EOL> '<STR_LIT>' : node . base , <EOL> '<STR_LIT>' : node . identifier , <EOL> '<STR_LIT>' : node . docstring , <EOL> '<STR_LIT>' : [ ] , <EOL> '<STR_LIT>' : [ ] , <EOL> '<STR_LIT>' : [ ] , <EOL> } <EOL> self . stack . append ( obj ) <EOL> for item in node . body : <EOL> self . visit ( item ) <EOL> def visit_StorageDef ( self , node ) : <EOL> storage_def = { <EOL> '<STR_LIT>' : node . lineno , <EOL> '<STR_LIT>' : node . kind , <EOL> '<STR_LIT:name>' : node . name , <EOL> '<STR_LIT>' : node . typename , <EOL> } <EOL> self . stack [ - <NUM_LIT:1> ] [ '<STR_LIT>' ] . append ( storage_def ) <EOL> if node . expr is not None : <EOL> self . visit_Binding ( node ) <EOL> def visit_Binding ( self , node ) : <EOL> opexpr = node . expr <EOL> pyast = opexpr . value . ast <EOL> opcompiler = COMPILE_OP_MAP [ opexpr . operator ] <EOL> code = opcompiler ( pyast , self . filename ) <EOL> binding = { <EOL> '<STR_LIT>' : node . lineno , <EOL> '<STR_LIT:name>' : node . name , <EOL> '<STR_LIT>' : opexpr . operator , <EOL> } <EOL> if isinstance ( code , tuple ) : <EOL> code , auxcode = code <EOL> binding [ '<STR_LIT:code>' ] = code <EOL> binding [ '<STR_LIT>' ] = auxcode <EOL> else : <EOL> binding [ '<STR_LIT:code>' ] = code <EOL> binding [ '<STR_LIT>' ] = None <EOL> self . stack [ - <NUM_LIT:1> ] [ '<STR_LIT>' ] . append ( binding ) <EOL> def visit_ChildDef ( self , node ) : <EOL> obj = { <EOL> '<STR_LIT>' : node . lineno , <EOL> '<STR_LIT>' : node . typename , <EOL> '<STR_LIT>' : node . identifier , <EOL> '<STR_LIT:filename>' : self . filename , <EOL> '<STR_LIT>' : [ ] , <EOL> '<STR_LIT>' : [ ] , <EOL> '<STR_LIT>' : [ ] , <EOL> } <EOL> self . stack . append ( obj ) <EOL> for item in node . body : <EOL> self . visit ( item ) <EOL> self . stack . pop ( ) <EOL> self . stack [ - <NUM_LIT:1> ] [ '<STR_LIT>' ] . append ( obj ) <EOL> class EnamlCompiler ( _NodeVisitor ) : <EOL> """<STR_LIT>""" <EOL> @ classmethod <EOL> def compile ( cls , module_ast , filename ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( filename , unicode ) : <EOL> filename = filename . encode ( sys . getfilesystemencoding ( ) ) <EOL> module_ops = [ ( SetLineno , <NUM_LIT:1> ) ] <EOL> for start in STARTUP : <EOL> start_code = compile ( start , filename , mode = '<STR_LIT>' ) <EOL> bp_code = Code . from_code ( start_code ) <EOL> module_ops . extend ( bp_code . code [ <NUM_LIT:1> : - <NUM_LIT:2> ] ) <EOL> compiler = cls ( filename ) <EOL> compiler . visit ( module_ast ) <EOL> module_ops . extend ( compiler . code_ops ) <EOL> for end in CLEANUP : <EOL> end_code = compile ( end , filename , mode = '<STR_LIT>' ) <EOL> bp_code = Code . from_code ( end_code ) <EOL> module_ops . extend ( bp_code . code [ <NUM_LIT:1> : - <NUM_LIT:2> ] ) <EOL> module_ops . extend ( [ <EOL> ( LOAD_CONST , None ) , <EOL> ( RETURN_VALUE , None ) , <EOL> ] ) <EOL> mod_code = Code ( <EOL> module_ops , [ ] , [ ] , False , False , False , '<STR_LIT>' , filename , <NUM_LIT:0> , '<STR_LIT>' , <EOL> ) <EOL> return mod_code . to_code ( ) <EOL> def __init__ ( self , filename ) : <EOL> self . filename = filename <EOL> self . code_ops = [ ] <EOL> def visit_Module ( self , node ) : <EOL> for item in node . body : <EOL> self . visit ( item ) <EOL> def visit_Python ( self , node ) : <EOL> py_code = compile ( node . ast , self . filename , mode = '<STR_LIT>' ) <EOL> bp_code = Code . from_code ( py_code ) <EOL> self . code_ops . extend ( bp_code . code [ <NUM_LIT:1> : - <NUM_LIT:2> ] ) <EOL> def visit_EnamlDef ( self , node ) : <EOL> code_ops = self . code_ops <EOL> dct = EnamlDefCompiler . compile ( node , self . filename ) <EOL> for decorator in node . decorators : <EOL> code = compile ( decorator . ast , self . filename , mode = '<STR_LIT>' ) <EOL> bpcode = Code . from_code ( code ) . code <EOL> code_ops . extend ( bpcode [ : - <NUM_LIT:1> ] ) <EOL> code_ops . extend ( [ <EOL> ( SetLineno , node . lineno ) , <EOL> ( LOAD_NAME , '<STR_LIT>' ) , <EOL> ( LOAD_CONST , dct ) , <EOL> ( LOAD_NAME , '<STR_LIT>' ) , <EOL> ( CALL_FUNCTION , <NUM_LIT> ) , <EOL> ( CALL_FUNCTION , <NUM_LIT> ) , <EOL> ] ) <EOL> for dec in node . decorators : <EOL> code_ops . append ( ( CALL_FUNCTION , <NUM_LIT> ) ) <EOL> code_ops . append ( ( STORE_NAME , node . typename ) ) </s>
