mirror of
https://github.com/michaelcmartin/Ophis.git
synced 2024-05-29 00:41:29 +00:00
41bf01d035
Most of the work is handled by 2to3, but there's a few extra tricks needed to finish the job, mostly about picking the right bits to be Unicode and the right bits to be bytes.
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)
|