Skip to content

Instantly share code, notes, and snippets.

@ligfx
Last active May 14, 2020 01:01
Show Gist options
  • Save ligfx/35fc7b8234d28097feeef3a63f516dfc to your computer and use it in GitHub Desktop.
Save ligfx/35fc7b8234d28097feeef3a63f516dfc to your computer and use it in GitHub Desktop.
**CAOS2PRAY
*# Pray-File "elevines.agents"
*# DS-Name "Elevines"
*# Depend blnk.c16
*# attach elevinehelp.catalogue elevines.c16
*# desc = "An easy-to-use custom elevator system. Read the help file included for details. Lovely sprites by Mea."
*# Agent Animation File = "elevines.c16"
*# Agent Sprite First Image = 4
*# Agent Animation Gallery = "elevines"
*# Web URL = "naturingnurturing.blogspot.com"
*# Web Label = "Naturing :: Nurturing"
*lift teleporting ball things.
new: comp 3 1 21051 "elevines" 13 4 2000
*Inject it where it belongs:
*Why are you including a C3 inject script when this isn't even C3 compatible?
*Probably because I am lazy and just want to copypaste my install script....
doif gnam eq "Docking Station"
setv $creatorx game "CreatorX"
setv $creatory game "CreatorY"
doif $creatorx eq 0 and $creatory eq 0
setv $creatorx 6110
setv $creatory 9200
endi
doif tmvt $creatorx $creatory eq 1
mvto $creatorx $creatory
else
mvsf $creatorx $creatory
endi
elif gnam eq "Creatures 3"
doif tmvt 5671 3599 eq 1
mvto 5671 3599
else
mvsf 5671 3599
endi
endi
clac 1000
bhvr 3
*activate 1 (1) activate 2 (2)
tick 30
attr 198
*mouse pickupable (2) mouseclickable (4) collisions (64) physics (128)
accg 30
elas 20
fric 100
perm 100
object_variable $unique_pose ov96
object_variable $unique_tintr ov97
object_variable $unique_tintg ov98
object_variable $unique_tintb ov99
*ov98 and 99 are going to be the random tints, ov97 is the random -pose-
setv ov96 rand 0 12
setv ov97 rand 50 200
setv ov98 rand 50 200
setv ov99 rand 50 200
pose ov96
tint ov97 ov98 ov99 128 128
*We'll base your ID number off your tints, just for fun:
sets ov00 vtos ov97
adds ov00 vtos ov98
adds ov00 vtos ov99
*parts-- 1, top button, 2, bottom
pat: dull 1 "elevines" 0 6 21 1
pat: dull 2 "elevi\nesd\d .. dd" 2 12 72 1
*Push -- Want to go up
scrp 3 1 21051 1
inst
lock
*first off, is it actually possible to go up?
*check where you are
setv ov10 posy
*set the little serchagent to null
seta $targetring null
*enum through other circles
enum 3 1 21051
*only check ones of your code
doif mv00 eq ov00
*see if it's on a higher level-- that is, the y coord is less than mv10
doif posy lt mv10
*herein lies the tricky part-- you want it to be lower than the ring
*being pushed, but higher than the rest.
*so NOW check to see if a previous agent has been found
doif $targetring = null
*if not, make it the current favorite
* so set the ring you just found into $targetring
* and the y coord into $targetposy
seta $targetring targ
setv $targetposy posy
*else, you have to check it against the current $targetposy to
*make sure it's the highest-lower y coord
else
doif posy gt $targetposy
seta $targetring targ
setv $targetposy posy
endi
endi
endi
endi
next
*So $targetring should be the ideal ring to tele to now
*assuming there is one.
*if there's NOT, stop this whole thing now!
doif $targetring eq null
*make sure there's a FROM creature
doif from ne null
*who pushed you?
doif from.fmly = 4
*put a bug in it's ear-- stop pushing this!
urge writ from 26 -2 -1 2
sndc "buzz"
*disappointment
stim writ from 0 1
stop
else
stop
endi
else
stop
endi
*else there IS a $targetring!
else
*if it's being carried (like by the hand), stop
doif $targetring.movs ne 0
stop
endi
*now, make sure there's a creature to move
doif from ne null
doif from.fmly = 4
*Lock it out from creatures for a second!
$targetring.tick tick
$targetring.attr 214
*now targ the norn
*make sure it's not being carried
doif from.movs ne 0
stop
endi
*Make sure it's a VALID place to move it!
*and move it!
doif from.tmvf $targetring.posx $targetring.posb = 1
from.mvft $targetring.posx $targetring.posb
*tell the norn it just travled
*and it needs to wait?
*tell the norn to STOP now..
*and make some dingysound
stim writ from 94 1
stim writ from 75 1
urge writ from 26 -2 -1 2
sndc "snap"
else
*if it's not a VALID PLACE make a sndc
sndc "buzz"
stop
endi
else
stop
endi
endi
endi
endm
*Pull -- Want to go down
scrp 3 1 21051 2
inst
*first off, is it actually possible to go DOWN?
*check where you are
setv ov10 posy
*set the little serchagent to null
seta $targetring null
*enum through other circles
enum 3 1 21051
*only check ones of your code
doif mv00 eq ov00
*see if it's on a higher level-- that is, the y coord is GREATER than mv10
doif posy gt mv10
*herein lies the tricky part-- you want it to be lower than the ring
*being pushed, but higher than the rest.
*so NOW check to see if a previous agent has been found
doif $targetring eq null
*if not, make it the current favorite
* so set the ring you just found into $targetring
* and the y coord into $targetposy
seta $targetring targ
setv $targetposy posy
*else, you have to check it against the current $targetposy to
*make sure it's the lowest-higher y coord
else
doif posy lt $targetposy
seta $targetring targ
setv $targetposy posy
endi
endi
endi
endi
next
*So $targetring should be the ideal ring to tele to now
*assuming there is one.
*if there's NOT, stop this whole thing now!
doif $targetring eq null
*make sure there's a FROM creature
doif from ne null
*who pushed you?
seta $fromcreature from
targ $fromcreature
doif fmly = 4
*put a bug in it's ear-- stop pulling this!
*hi
sndc "buzz"
urge writ targ 26 -2 -1 2
*disappointment
stim writ $fromcreature 0 1
stop
else
stop
endi
else
stop
endi
*else there IS a $targetring!
else
*if it's being carried (like by the hand), stop
targ $targetring
doif movs ne 0
sndc "buzz"
stop
endi
*now, make sure there's a creature to move
doif from ne null
doif from.fmly = 4
*set the coords of $targetring into $targetposx and $targetposb
*Lock it out from creatures for a second!
$targetring.tick $targetring.tick
$targetring.attr 214
*now targ the norn
*make sure it's not being carried
doif from.movs ne 0
stop
endi
*Make sure it's a VALID place to move it!
doif from.tmvf $targetring.posx $targetring.posb = 1
*and move it!
from.mvft $targetposx $targetposb
*tell the norn it just travled
stim writ from 94 1
*tell the norn to STOP now..
urge writ from 26 -2 -1 2
*wait?
stim writ from 75 1
*and make some dingysound
sndc "snap"
else
*if it's not a VALID PLACE make a sndc
sndc "buzz"
stop
endi
else
stop
endi
endi
endi
endm
*you've been CLICKED or clac'd or something
scrp 3 1 21051 1000
inst
*Here is how it works....
*shift+click creates a copy of the same OV
*ctrl+click creates a copy of a new OV
*shift+click kills it.
sndc "opn1"
*shift -- make a copy, save OV, same tint
doif keyd 16 eq 1 and keyd 17 eq 0
sndc "opn1"
new: comp 3 1 21051 "elevines" 13 4 2000
*move it to the old one, and make it hop a bit
mvsf ownr.posl ownr.post
velo 15 100
clac 1000
bhvr 3
*activate 1 (1) activate 2 (2)
tick 30
attr 198
*mouse pickupable (2) mouseclickable (4) collisions (64) physics (128)
accg 30
elas 20
fric 100
perm 100
*ov97, 96, 98 and 99 are going to be COPIED
setv ov96 mv96
setv ov97 mv97
setv ov98 mv98
setv ov99 mv99
pose ov96
tint ov97 ov98 ov99 128 128
*We'll base your ID number off your tints, just for fun:
sets ov00 vtos ov97
adds ov00 vtos ov98
adds ov00 vtos ov99
*parts-- 1, top button, 2, bottom
pat: dull 1 "elevines" 0 6 21 1
pat: dull 2 "elevines" 2 12 72 1
*ctrl
elif keyd 16 eq 0 and keyd 17 eq 1
sndc "unlk"
*lift teleporting ball things.
new: comp 3 1 21051 "elevines" 13 4 2000
*move it to the old one, and make it hop a bit
mvsf ownr.posl ownr.post
velo 15 100
clac 1000
bhvr 3
*activate 1 (1) activate 2 (2)
tick 30
attr 198
*mouse pickupable (2) mouseclickable (4) collisions (64) physics (128)
accg 30
elas 20
fric 100
perm 100
*ov98 and 99 are going to be the random tints, ov96 is the random -pose-
setv ov96 rand 0 12
setv ov97 rand 50 200
setv ov98 rand 50 200
setv ov99 rand 50 200
pose ov96
tint ov97 ov98 ov99 128 128
*We'll base your ID number off your tints, just for fun:
sets ov00 vtos ov97
adds ov00 vtos ov98
adds ov00 vtos ov99
*parts-- 1, top button, 2, bottom
pat: dull 1 "elevines" 0 6 21 1
pat: dull 2 "elevines" 2 12 72 1
*both
elif keyd 16 eq 1 and keyd 17 eq 1
kill ownr
endi
endm
*Meh. I tried to avoid using a timer for this but it's just
*SO MUCH MORE FLUID with it. ]:
scrp 3 1 21051 9
inst
*reset the attr if it's been changed
attr 198
*mouse pickupable (2) mouseclickable (4) collisions (64) physics (128)
*the indicator orbs change color. Yay.
setv $ishigher 0
setv $islower 0
*check where you are
setv ov10 posy
*enum through other circles
enum 3 1 21051
*only check ones of your code
doif mv00 eq ov00
*see if it's on a higher level-- that is, the y coord is less than mv10
doif posy lt mv10
setv $ishigher 1
*lower?
elif posy gt mv10
setv $islower 1
endi
endi
next
*pose accordingly!
part 1
pose $ishigher
part 2
pose $islower
endm
rscr
enum 3 1 21051
dbg: outv $hello
kill targ
next
* extended stuff
dbg: outv ownr.posy
from.mvsf 5 6
import collections
import json
import re
import string
import sys
with open("build/generated/commandinfo.json", "rb") as f:
COMMAND_INFO = json.loads(f.read())
COMMAND_INFO_C3 = COMMAND_INFO["variants"]["c3"]
COMMAND_NAMESPACES = { _.get("namespace") for _ in COMMAND_INFO_C3.values() if _.get("namespace") }
def peek(s, index):
if index < len(s):
return s[index]
return None
class TokenType:
__slots__ = ["name"]
def __init__(self, name):
self.name = name
def __repr__(self):
return self.name
TOK_COMMENT = TokenType("TOK_COMMENT")
TOK_DOLLARWORD = TokenType("TOK_DOLLARWORD")
TOK_INTEGER = TokenType("TOK_INTEGER")
TOK_STRING = TokenType("TOK_STRING")
TOK_WHITESPACE = TokenType("TOK_WHITESPACE")
TOK_WORD = TokenType("TOK_WORD")
TOK_DOT = TokenType("TOK_DOT")
TOK_EOI = TokenType("TOK_EOI")
def lexcaos(s):
p = 0
while True:
basep = p
if p >= len(s):
yield (TOK_EOI, "")
return
if s[p] in (" ", "\t", "\r", "\n"):
while peek(s, p) in (" ", "\t", "\r", "\n"):
p += 1
yield (TOK_WHITESPACE, s[basep:p])
elif s[p] == ".":
p += 1
yield (TOK_DOT, ".")
elif s[p] in string.ascii_letters + "_":
while peek(s, p) and peek(s, p) in string.ascii_letters + string.digits + "*:_":
p += 1
yield (TOK_WORD, s[basep:p])
elif s[p] == "$":
# nonstandard
p += 1
if peek(s, p) is None:
raise Exception("While parsing dollar var, got unexpected EOI")
if peek(s, p) not in string.ascii_letters + string.digits + "*:_":
raise Exception("Expected variable name after '$', got '%s' (%02x)" % (peek(s, p), ord(peek(s, p))))
while peek(s, p) and peek(s, p) in string.ascii_letters + string.digits + "*:_":
p += 1
yield (TOK_DOLLARWORD, s[basep:p])
elif s[p] == "-":
p += 1
if peek(s, p) is None:
raise Exception("While parsing negative number, got unexpected EOI")
if peek(s, p) not in string.digits:
raise Exception("Expected digit after '-', got '%s' (%02x)" % (peek(s, p), ord(peek(s, p))))
while peek(s, p) and peek(s, p) in string.digits:
p += 1
yield (TOK_INTEGER, int(s[basep:p]))
elif s[p] in string.digits:
while peek(s, p) and peek(s, p) in string.digits:
p += 1
yield (TOK_INTEGER, int(s[basep:p]))
# if peek(s, p) and peek(s, p) not in (" ", "\t", "\r", "\n"):
# raise Exception("Expected whitespace after integer, got '%s' (%02x)" % (s[p], ord(s[p])))
elif s[p] == "\"":
p += 1
while True:
if p >= len(s):
raise Exception("While parsing string, got unexpected EOI")
if s[p] == "\"":
p += 1
yield (TOK_STRING, s[basep:p])
break
elif s[p] == "\\":
p += 2
else:
p += 1
elif s[p] == "=":
p += 1
yield (TOK_WORD, "=")
elif s[p] == "*":
p += 1
while peek(s, p) != "\n":
p += 1
yield (TOK_COMMENT, s[basep:p])
else:
raise Exception("Unexpected character '%s' (%02x)" % (s[p], ord(s[p])))
class script:
def __init__(self, start, end, vaxx_vars, dollar_vars):
self.start = start
self.end = end
self.vaxx_vars = vaxx_vars
self.dollar_vars = dollar_vars
class ParserState:
__slots__ = ['p', 'tokens']
def __init__(self, tokens):
self.tokens = tokens
self.p = 0
def peekmatch(self, newp, toktypes):
if not isinstance(toktypes, (tuple, list, set)):
toktypes = (toktypes,)
if self.tokens[newp][0] not in toktypes:
raise Exception("Expected %r, got %s\n" % (toktypes, self.tokens[newp][0]))
def caosliteral(value, token):
return collections.OrderedDict([("type", "Literal"), ("value", value), ("token", token)])
def caosvariable(value, token):
return collections.OrderedDict([("type", "Variable"), ("value", value), ("token", token)])
def caoscondition(children, start_token):
end_token = children[-1].get("end_token") or children[-1].get("token")
return collections.OrderedDict([("type", "Condition"), ("children", children), ("start_token", start_token), ("end_token", end_token)])
def caosconditionkeyword(value):
return collections.OrderedDict([("type", "ConditionKeyword"), ("value", value)])
def maybe_eat_whitespace(state):
ate_whitespace = False
while state.tokens[state.p][0] in (TOK_COMMENT, TOK_WHITESPACE):
ate_whitespace = True
state.p += 1
return ate_whitespace
def eat_whitespace(state):
if not maybe_eat_whitespace(state):
raise Exception("Expected whitespace or comment, got %s %s" % (state.tokens[state.p][0], state.tokens[state.p][1]))
def parse_condition(state):
left = parse_value(state)
eat_whitespace(state)
if state.tokens[state.p][0] != TOK_WORD:
raise Exception("Expected comparison, got %s %s" % (state.tokens[state.p][0], state.tokens[state.p][1]))
startp = state.p
comparison = state.tokens[state.p][1]
state.p += 1
if comparison not in ('eq', 'lt', 'gt', 'ne', '='):
raise Exception("Unknown comparison operator '%s'" % comparison)
eat_whitespace(state)
right = parse_value(state)
ate_whitespace = maybe_eat_whitespace(state)
if ate_whitespace and state.tokens[state.p][0] == TOK_WORD and state.tokens[state.p][1] in ("and", "or"):
combiner = state.tokens[state.p][1]
state.p += 1
remainder = parse_condition(state)
return caoscondition([left, caosconditionkeyword(comparison), right, caosconditionkeyword(combiner)] + remainder["children"], startp)
else:
return caoscondition([left, caosconditionkeyword(comparison), right], startp)
def parse_directive(state):
startp = state.p
if state.tokens[state.p][0] != TOK_WORD:
raise Exception("Expected directive name, got %s %s" % (state.tokens[state.p][0], state.tokens[state.p][1]))
directive_name = state.tokens[state.p][1].lower()
if directive_name == "object_variable":
state.p += 1
eat_whitespace(state)
if state.tokens[state.p][0] != TOK_DOLLARWORD:
raise Exception("Expected variable name, got %s %s" % (state.tokens[state.p][0], state.tokens[state.p][1]))
args = [state.tokens[state.p][1]]
state.p += 1
eat_whitespace(state)
if state.tokens[state.p][0] != TOK_WORD:
raise Exception("Expected variable command, got %s %s" % (state.tokens[state.p][0], state.tokens[state.p][1]))
args.append(state.tokens[state.p][1])
state.p += 1
return {"type": "Directive", "name": "object_variable", "args": args, "start_token": startp, "end_token": state.p - 1}
else:
raise Exception("Expected directive name, got %s %s" % (state.tokens[state.p][0], state.tokens[state.p][1]))
def parse_command(state, is_toplevel):
startp = state.p
dotcommand = False
if state.tokens[state.p][0] == TOK_WORD:
if is_toplevel and state.tokens[state.p][1].lower() in ('object_variable',):
return parse_directive(state)
if state.tokens[state.p][1].lower() in COMMAND_NAMESPACES:
namespace = state.tokens[state.p][1].lower()
state.p += 1
eat_whitespace(state)
command = state.tokens[state.p][1].lower()
elif state.tokens[state.p + 1][0] == TOK_DOT:
dotcommand = True
namespace = ""
targ = state.tokens[state.p][1].lower()
# TODO: check it's a valid command
state.p += 2
command = state.tokens[state.p][1].lower()
else:
namespace = ""
command = state.tokens[state.p][1].lower()
elif state.tokens[state.p][0] == TOK_DOLLARWORD:
if state.tokens[state.p + 1][0] != TOK_DOT:
value = state.tokens[state.p][1]
state.p += 1
state.peekmatch(state.p, (TOK_WHITESPACE, TOK_COMMENT, TOK_EOI))
return caosvariable(value, startp)
dotcommand = True
namespace = ""
targ = state.tokens[state.p][1].lower()
state.p += 2
command = state.tokens[state.p][1].lower()
else:
raise Exception("Expected command name, got %s %s" % (state.tokens[state.p][0], state.tokens[state.p][1]))
commandnormalized = command
if re.match(r"(?i)^va\d\d$", command):
commandnormalized = "vaxx"
if re.match(r"(?i)^ov\d\d$", command):
commandnormalized = "ovxx"
if re.match(r"(?i)^mv\d\d$", command):
commandnormalized = "mvxx"
commandinfos = [
_ for _ in COMMAND_INFO_C3.values()
if
_.get("namespace", "").lower() == namespace
and _.get("match", "").lower() == commandnormalized
and ((is_toplevel and _.get("type") == "command") or (not is_toplevel and _.get("type") != "command"))
]
if not commandinfos:
raise Exception("Unknown command '%s'" % ((namespace + " " if namespace else "") + command))
assert len(commandinfos) == 1
state.p += 1
if commandinfos[0]["arguments"]:
eat_whitespace(state)
args = []
for _ in commandinfos[0]["arguments"]:
if _["type"] == "condition":
args.append(parse_condition(state))
else:
args.append(parse_value(state))
if args:
end_token = args[-1].get("end_token") or args[-1].get("token")
else:
end_token = startp
if dotcommand:
return collections.OrderedDict([
("type", "DotCommand"),
("targ", targ),
("command", command),
("commandtype", ("statement" if is_toplevel else "expression")),
("commandret", commandinfos[0]["type"]),
("args", args),
("start_token", startp),
("end_token", end_token)
])
else:
return collections.OrderedDict([
("type", "Command"),
("name", (namespace + " " if namespace else "") + command),
("commandtype", ("statement" if is_toplevel else "expression")),
("args", args),
("start_token", startp),
("end_token", end_token)
])
def parse_toplevel(state):
maybe_eat_whitespace(state)
return parse_command(state, True)
def parse_value(state):
maybe_eat_whitespace(state)
startp = state.p
if state.tokens[state.p][0] in (TOK_WORD, TOK_DOLLARWORD):
return parse_command(state, False)
elif state.tokens[state.p][0] == TOK_INTEGER:
value = state.tokens[state.p][1]
state.p += 1
state.peekmatch(state.p, (TOK_WHITESPACE, TOK_COMMENT, TOK_EOI))
return caosliteral(value, startp)
elif state.tokens[state.p][0] == TOK_STRING:
value = state.tokens[state.p][1]
state.p += 1
state.peekmatch(state.p, (TOK_WHITESPACE, TOK_COMMENT, TOK_EOI))
return caosliteral(value, startp)
else:
raise Exception("Unimplemented token type %s" % state.tokens[state.p][0])
def parse(tokens):
state = ParserState(tokens)
fst = []
while True:
maybe_eat_whitespace(state)
if state.tokens[state.p][0] == TOK_EOI:
break
fst.append(parse_toplevel(state))
return fst
def visit_worddotcommands(t):
if t["type"] in ("Command",):
prefix = []
newargs = []
for a in t["args"]:
more_prefix, arg = visit_worddotcommands(a)
prefix += more_prefix
newargs.append(arg)
t = dict(t)
t["args"] = newargs
# if prefix:
# prefix[0]["preceding_tokens"] = t.get("preceding_tokens", []) + prefix[0].get("preceding_tokens", [])
if prefix and t["commandtype"] == "statement":
ws = ""
for pt in reversed(t.get("preceding_tokens", [])):
if pt[0] == TOK_WHITESPACE:
ws = pt[1] + ws
else:
break
ws = ws.split("\n")[-1]
ws = ws.replace("\r", "")
# print("indent '%s'" % ws)
for p in prefix:
p["preceding_tokens"] = p.get("preceding_tokens", []) + [(TOK_WHITESPACE, ws)]
return (prefix, t)
elif t["type"] in ("Condition",):
prefix = []
newchildren = []
for a in t["children"]:
more_prefix, child = visit_worddotcommands(a)
prefix += more_prefix
newchildren.append(child)
t = dict(t)
t["children"] = newchildren
return (prefix, t)
elif t["type"] in ("DotCommand",):
if t["commandtype"] == "expression":
if t["targ"][0] == "$":
varname = t["targ"] + "_" + t["command"]
else:
varname = "$" + t["targ"] + "_" + t["command"]
prefix = [
{"type": "Command", "name": "seta", "args": [
{"type": "Variable", "value": "$__saved_targ"},
{"type": "Command", "name": "targ", "args": []}
], "preceding_tokens": [("TOK_WHITESPACE", "\n")]},
{"type": "Command", "name": "targ", "args": [
{"type": "Command", "name": t["targ"], "args": []}
], "preceding_tokens": [("TOK_WHITESPACE", "\n")]},
{"type": "Command", "name": "setv", "args": [
{"type": "Variable", "value": varname},
{"type": "Command", "name": t["command"], "args": t["args"]},
], "preceding_tokens": [("TOK_WHITESPACE", "\n")]},
{"type": "Command", "name": "targ", "args": [
{"type": "Variable", "value": "$__saved_targ"}
], "preceding_tokens": [("TOK_WHITESPACE", "\n")]},
]
t = {"type": "Variable", "value": varname}
elif t["commandtype"] == "statement":
prefix = [
{"type": "Command", "name": "seta", "args": [
{"type": "Variable", "value": "$__saved_targ"},
{"type": "Command", "name": "targ", "args": []}
], "preceding_tokens": t.get("preceding_tokens", [])},
{"type": "Command", "name": "targ", "args": [
{"type": "Command", "name": t["targ"], "args": []}
], "preceding_tokens": [("TOK_WHITESPACE", "\n")]},
{"type": "Command", "name": t["command"], "args": t["args"],
"preceding_tokens": [("TOK_WHITESPACE", "\n")]},
{"type": "Command", "name": "targ", "args": [
{"type": "Variable", "value": "$__saved_targ"}
], "preceding_tokens": [("TOK_WHITESPACE", "\n")]},
]
t = {}
return (prefix, t)
else:
return ([], t)
def print_node(t):
if not t:
return
if t.get("preceding_tokens"):
for pt in t["preceding_tokens"]:
sys.stdout.write(str(pt[1]))
if t["type"] == "Command":
sys.stdout.write(t["name"])
for a in t["args"]:
sys.stdout.write(" ")
print_node(a)
elif t["type"] == "Literal":
sys.stdout.write(str(t["value"]))
elif t["type"] == "ConditionKeyword":
sys.stdout.write(str(t["value"]))
elif t["type"] == "Variable":
sys.stdout.write(t["value"])
elif t["type"] == "Condition":
for a in t["children"]:
print_node(a)
sys.stdout.write(" ")
elif t["type"] == "DotCommand":
sys.stdout.write(t["targ"] + "." + t["command"])
for a in t["args"]:
sys.stdout.write(" ")
print_node(a)
elif t["type"] == "Directive":
sys.stdout.write(t["name"])
for a in t["args"]:
sys.stdout.write(" " + a)
else:
raise Exception("unhandled node type %s" % t["type"])
def main():
if len(sys.argv) == 2:
with open(sys.argv[1], 'rb') as f:
text = f.read()
elif len(sys.argv) == 1:
sys.stderr.write("Reading from stdin...")
text = sys.stdin.read()
else:
sys.stderr.write("USAGE: %s [FILE]" % sys.argv[0])
exit(1)
tokens = list(lexcaos(text))
fst = parse(tokens)
print(json.dumps(fst, indent=2))
tokenp = 0
for toplevel in fst:
toplevel["preceding_tokens"] = []
while tokenp < toplevel["start_token"]:
toplevel["preceding_tokens"].append(tokens[tokenp])
tokenp += 1
tokenp = toplevel["end_token"] + 1
object_variables = {}
i = 0
while i < len(fst):
t = fst[i]
if t["type"] == "Directive" and t["name"] == "object_variable":
object_variables[t["args"][0]] = t["args"][1]
del fst[i]
else:
i += 1
newfst = []
for toplevel in fst:
prefix, t = visit_worddotcommands(toplevel)
newfst += prefix
newfst.append(t)
# i = 0
# while i < len(newfst):
# t0 = newfst[i]
# a0 = peek(t0.get("args", []), 0)
# t1 = peek(newfst, i + 1)
# if (
# t0
# and t0["type"] == "Command"
# and t0["name"] == "targ"
# and a0["type"] == "Variable"
# and a0["value"] == "$__saved_targ"
# and t1
# and t1["type"] == "Command"
# and t1["name"] == "seta"
# and t1["args"][0]["type"] == "Variable"
# and t1["args"][0]["value"] == "$__saved_targ"
# and t1["args"][1]["type"] == "Command"
# and t1["args"][1]["name"] == "targ"
# ):
# del newfst[i]
# else:
# i += 1
for toplevel in newfst:
print_node(toplevel)
exit()
scripts = [script(0, 0, set(), set())]
for i, t in enumerate(tokens):
if t[0] == TOK_WORD and t[1].lower() in ("scrp", "rscr"):
scripts.append(script(i, i, set(), set()))
continue
if t[0] == TOK_WORD and re.match(r"(?i)^va\d\d$", t[1]):
scripts[-1].vaxx_vars.add(t[1].lower())
if t[0] == TOK_DOLLARWORD:
scripts[-1].dollar_vars.add(t[1])
scripts[-1].end = i
for s in scripts:
var_mapping = {}
for d in s.dollar_vars:
possibles = ["va{:02}".format(i) for i in range(100) if "va{:02}".format(i) not in (list(s.vaxx_vars) + var_mapping.values())]
if not possibles:
raise Exception("Couldn't allocate variable for '%s'" % d)
var_mapping[d] = possibles[0]
print_mapped_line = False
line = []
for t in tokens[s.start:s.end]:
if (t[0] == TOK_WHITESPACE and "\n" in t[1]) or (t[0] == TOK_COMMENT):
if print_mapped_line:
sys.stdout.write(" * ")
for lt in line:
sys.stdout.write(str(lt[1]))
print_mapped_line = False
line = []
else:
line.append(t)
if t[0] == TOK_DOLLARWORD:
print_mapped_line = True
sys.stdout.write(var_mapping[t[1]])
else:
sys.stdout.write(str(t[1]))
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment