<s> """<STR_LIT>""" <EOL> from . am_eval import OpCode , eval_macro <EOL> import string <EOL> class Token : <EOL> ADD = "<STR_LIT:+>" <EOL> SUB = "<STR_LIT:->" <EOL> MULT = ( "<STR_LIT:x>" , "<STR_LIT:X>" ) <EOL> DIV = "<STR_LIT:/>" <EOL> OPERATORS = ( ADD , SUB , MULT [ <NUM_LIT:0> ] , MULT [ <NUM_LIT:1> ] , DIV ) <EOL> LEFT_PARENS = "<STR_LIT:(>" <EOL> RIGHT_PARENS = "<STR_LIT:)>" <EOL> EQUALS = "<STR_LIT:=>" <EOL> EOF = "<STR_LIT>" <EOL> def token_to_opcode ( token ) : <EOL> if token == Token . ADD : <EOL> return OpCode . ADD <EOL> elif token == Token . SUB : <EOL> return OpCode . SUB <EOL> elif token in Token . MULT : <EOL> return OpCode . MUL <EOL> elif token == Token . DIV : <EOL> return OpCode . DIV <EOL> else : <EOL> return None <EOL> def precedence ( token ) : <EOL> if token == Token . ADD or token == Token . SUB : <EOL> return <NUM_LIT:1> <EOL> elif token in Token . MULT or token == Token . DIV : <EOL> return <NUM_LIT:2> <EOL> else : <EOL> return <NUM_LIT:0> <EOL> def is_op ( token ) : <EOL> return token in Token . OPERATORS <EOL> class Scanner : <EOL> def __init__ ( self , s ) : <EOL> self . buff = s <EOL> self . n = <NUM_LIT:0> <EOL> def eof ( self ) : <EOL> return self . n == len ( self . buff ) <EOL> def peek ( self ) : <EOL> if not self . eof ( ) : <EOL> return self . buff [ self . n ] <EOL> return Token . EOF <EOL> def ungetc ( self ) : <EOL> if self . n > <NUM_LIT:0> : <EOL> self . n -= <NUM_LIT:1> <EOL> def getc ( self ) : <EOL> if self . eof ( ) : <EOL> return "<STR_LIT>" <EOL> c = self . buff [ self . n ] <EOL> self . n += <NUM_LIT:1> <EOL> return c <EOL> def readint ( self ) : <EOL> n = "<STR_LIT>" <EOL> while not self . eof ( ) and ( self . peek ( ) in string . digits ) : <EOL> n += self . getc ( ) <EOL> return int ( n ) <EOL> def readfloat ( self ) : <EOL> n = "<STR_LIT>" <EOL> while not self . eof ( ) and ( self . peek ( ) in string . digits or self . peek ( ) == "<STR_LIT:.>" ) : <EOL> n += self . getc ( ) <EOL> if n == "<STR_LIT:.>" : <EOL> return <NUM_LIT:0> <EOL> return float ( n ) <EOL> def readstr ( self , end = "<STR_LIT:*>" ) : <EOL> s = "<STR_LIT>" <EOL> while not self . eof ( ) and self . peek ( ) != end : <EOL> s += self . getc ( ) <EOL> return s . strip ( ) <EOL> def print_instructions ( instructions ) : <EOL> for opcode , argument in instructions : <EOL> print ( "<STR_LIT>" % ( OpCode . str ( opcode ) , <EOL> str ( argument ) if argument is not None else "<STR_LIT>" ) ) <EOL> def read_macro ( macro ) : <EOL> instructions = [ ] <EOL> for block in macro . split ( "<STR_LIT:*>" ) : <EOL> is_primitive = False <EOL> is_equation = False <EOL> found_equation_left_side = False <EOL> found_primitive_code = False <EOL> equation_left_side = <NUM_LIT:0> <EOL> primitive_code = <NUM_LIT:0> <EOL> unary_minus_allowed = False <EOL> unary_minus = False <EOL> if Token . EQUALS in block : <EOL> is_equation = True <EOL> else : <EOL> is_primitive = True <EOL> scanner = Scanner ( block ) <EOL> op_stack = [ ] <EOL> def pop ( ) : <EOL> return op_stack . pop ( ) <EOL> def push ( op ) : <EOL> op_stack . append ( op ) <EOL> def top ( ) : <EOL> return op_stack [ - <NUM_LIT:1> ] <EOL> def empty ( ) : <EOL> return len ( op_stack ) == <NUM_LIT:0> <EOL> while not scanner . eof ( ) : <EOL> c = scanner . getc ( ) <EOL> if c == "<STR_LIT:U+002C>" : <EOL> found_primitive_code = True <EOL> while not empty ( ) : <EOL> instructions . append ( ( token_to_opcode ( pop ( ) ) , None ) ) <EOL> unary_minus_allowed = True <EOL> elif c in Token . OPERATORS : <EOL> if c == Token . SUB and unary_minus_allowed : <EOL> unary_minus = True <EOL> unary_minus_allowed = False <EOL> continue <EOL> while not empty ( ) and is_op ( top ( ) ) and precedence ( top ( ) ) >= precedence ( c ) : <EOL> instructions . append ( ( token_to_opcode ( pop ( ) ) , None ) ) <EOL> push ( c ) <EOL> elif c == Token . LEFT_PARENS : <EOL> push ( c ) <EOL> elif c == Token . RIGHT_PARENS : <EOL> while not empty ( ) and top ( ) != Token . LEFT_PARENS : <EOL> instructions . append ( ( token_to_opcode ( pop ( ) ) , None ) ) <EOL> if empty ( ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> pop ( ) <EOL> elif c . startswith ( "<STR_LIT:$>" ) : <EOL> n = scanner . readint ( ) <EOL> if is_equation and not found_equation_left_side : <EOL> equation_left_side = n <EOL> else : <EOL> instructions . append ( ( OpCode . LOAD , n ) ) <EOL> elif c == Token . EQUALS : <EOL> found_equation_left_side = True <EOL> elif c == "<STR_LIT:0>" : <EOL> if is_primitive and not found_primitive_code : <EOL> instructions . append ( ( OpCode . PUSH , scanner . readstr ( "<STR_LIT:*>" ) ) ) <EOL> found_primitive_code = True <EOL> else : <EOL> if scanner . peek ( ) not in '<STR_LIT:.>' or scanner . peek ( ) == Token . EOF : <EOL> instructions . append ( ( OpCode . PUSH , <NUM_LIT:0> ) ) <EOL> elif c in "<STR_LIT>" : <EOL> scanner . ungetc ( ) <EOL> if is_primitive and not found_primitive_code : <EOL> primitive_code = scanner . readint ( ) <EOL> else : <EOL> n = scanner . readfloat ( ) <EOL> if unary_minus : <EOL> unary_minus = False <EOL> n *= - <NUM_LIT:1> <EOL> instructions . append ( ( OpCode . PUSH , n ) ) <EOL> else : <EOL> pass <EOL> while not empty ( ) : <EOL> instructions . append ( ( token_to_opcode ( pop ( ) ) , None ) ) <EOL> if is_primitive and found_primitive_code : <EOL> instructions . append ( ( OpCode . PRIM , primitive_code ) ) <EOL> if is_equation : <EOL> instructions . append ( ( OpCode . STORE , equation_left_side ) ) <EOL> return instructions <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> import sys <EOL> instructions = read_macro ( sys . argv [ <NUM_LIT:1> ] ) <EOL> print ( "<STR_LIT>" ) <EOL> print_instructions ( instructions ) <EOL> print ( "<STR_LIT>" ) <EOL> for primitive in eval_macro ( instructions ) : <EOL> print ( primitive ) </s>
