"""Macro support for P65. P65 Macros are cached SequenceNodes with arguments set via .alias commands and prevented from escaping with .scope and .scend commands.""" import sys import Ophis.IR as IR import Ophis.CmdLine as Cmd import Ophis.Errors as Err macros = {} currentname = None currentbody = None def newMacro(name): "Start creating a new macro with the specified name." global currentname global currentbody global macros if currentname is not None: Err.log("Internal error! Nested macro attempt!") else: if name in macros: Err.log("Duplicate macro definition '%s'" % name) currentname = name currentbody = [] def registerNode(node): global currentbody currentbody.append(IR.Node(node.ppt, node.nodetype, *node.data)) def endMacro(): global currentname global currentbody global macros if currentname is None: Err.log("Internal error! Ended a non-existent macro!") else: macros[currentname] = currentbody currentname = None currentbody = None def expandMacro(ppt, name, arglist): global macros if name not in macros: Err.log("Undefined macro '%s'" % name) return IR.NullNode argexprs = [IR.Node(ppt, "Label", "_*%d" % i, arg) for (i, arg) in zip(xrange(1, sys.maxint), arglist)] bindexprs = [IR.Node(ppt, "Label", "_%d" % i, IR.LabelExpr("_*%d" % i)) for i in range(1, len(arglist)+1)] body = [IR.Node("%s->%s" % (ppt, node.ppt), node.nodetype, *node.data) for node in macros[name]] invocation = [IR.Node(ppt, "ScopeBegin")] + argexprs + [IR.Node(ppt, "ScopeBegin")] + bindexprs + body + [IR.Node(ppt, "ScopeEnd"), IR.Node(ppt, "ScopeEnd")] return IR.SequenceNode(ppt, invocation) def dump(): global macros for mac in macros: body = macros[mac] print "Macro: "+mac for node in body: print node print ""