63 lines
1.8 KiB
Python
63 lines
1.8 KiB
Python
"""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 ""
|