Exemple #1
0
class MacroExec(object):
    '''A MacroExec object constructs a local symbol table (LST) every time
    the macro is called.

    When a macro is called, it builds a LST.  If a symbol is
    referenced that isn't contained in the LST then the macro looks to
    the global symbol table (GST).  The macro can reference values
    from the GST, but it can not bind new values to the GST.  Macros
    bind values only to LST, so a method is used for all binding that
    takes care to obey this invarient.

    '''
    def __init__(self, name, args, body):
        self.name = name
        self.args = args
        self.body = body
        self.lst = SymbolTable()

    def num_args(self):
        return len(self.args)

    def bind(self, exprList):
        '''bind arguments to the local symbol table'''
        assert len(exprList) == len(self.args)
        bindPairs = zip(self.args, [e.eval() for e in exprList])

        # this mutates self.lst making for sad things to happen next
        # time this macro is invoked. or maybe not, maybe it simply
        # clobbers the old bindings?
        self.lst = SymbolTable()
        self.lst.bind(bindPairs)

    def generate(self, symtab):
        ''' generate a sequence of bytes '''
        # copy the macro body so the Ident nodes are preserved for the
        # next invocation of this macro.
        # import copy
        # ast = copy.deepcopy(self.body)
        ast = self.body

        ast.replace_idents(self.lst)
        ast.replace_idents(symtab)

        return ast.generate(symtab)