77 lines
2.2 KiB
Python
77 lines
2.2 KiB
Python
"""Macro support for Ophis.
|
|
|
|
Ophis Macros are cached SequenceNodes with arguments
|
|
set via .alias commands and prevented from escaping
|
|
with .scope and .scend commands."""
|
|
|
|
# Copyright 2002-2014 Michael C. Martin and additional contributors.
|
|
# You may use, modify, and distribute this file under the MIT
|
|
# license: See README for details.
|
|
|
|
import sys
|
|
|
|
import Ophis.IR as IR
|
|
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(range(1, sys.maxsize), 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, file=sys.stderr)
|
|
for node in body:
|
|
print(node, file=sys.stderr)
|
|
print("", file=sys.stderr)
|