mirror of
https://gitlab.com/xCrystal/pokecrystal-board.git
synced 2024-11-16 11:27:33 -08:00
Merge pull request #170 from kanzure/fix-up-preprocessor
Remove some globals from preprocessor.
This commit is contained in:
commit
52c3daca54
@ -13,7 +13,6 @@ from extras.pokemontools.crystal import (
|
|||||||
PointerLabelBeforeBank,
|
PointerLabelBeforeBank,
|
||||||
PointerLabelAfterBank,
|
PointerLabelAfterBank,
|
||||||
ItemFragment,
|
ItemFragment,
|
||||||
TextEndingCommand,
|
|
||||||
text_command_classes,
|
text_command_classes,
|
||||||
movement_command_classes,
|
movement_command_classes,
|
||||||
music_classes,
|
music_classes,
|
||||||
@ -42,6 +41,9 @@ show_original_lines = False
|
|||||||
# helpful for debugging macros
|
# helpful for debugging macros
|
||||||
do_macro_sanity_check = False
|
do_macro_sanity_check = False
|
||||||
|
|
||||||
|
class SkippableMacro(object):
|
||||||
|
macro_name = "db"
|
||||||
|
|
||||||
chars = {
|
chars = {
|
||||||
"ガ": 0x05,
|
"ガ": 0x05,
|
||||||
"ギ": 0x06,
|
"ギ": 0x06,
|
||||||
@ -409,11 +411,10 @@ def quote_translator(asm):
|
|||||||
def extract_token(asm):
|
def extract_token(asm):
|
||||||
return asm.split(" ")[0].strip()
|
return asm.split(" ")[0].strip()
|
||||||
|
|
||||||
def make_macro_table():
|
def make_macro_table(macros):
|
||||||
return dict(((macro.macro_name, macro) for macro in macros))
|
return dict(((macro.macro_name, macro) for macro in macros))
|
||||||
macro_table = make_macro_table()
|
|
||||||
|
|
||||||
def macro_test(asm):
|
def macro_test(asm, macro_table):
|
||||||
"""
|
"""
|
||||||
Returns a matching macro, or None/False.
|
Returns a matching macro, or None/False.
|
||||||
"""
|
"""
|
||||||
@ -425,7 +426,19 @@ def macro_test(asm):
|
|||||||
else:
|
else:
|
||||||
return (None, None)
|
return (None, None)
|
||||||
|
|
||||||
def macro_translator(macro, token, line):
|
def is_based_on(something, base):
|
||||||
|
"""
|
||||||
|
Checks whether or not 'something' is a class that is a subclass of a class
|
||||||
|
by name. This is a terrible hack but it removes a direct dependency on
|
||||||
|
existing macros.
|
||||||
|
|
||||||
|
Used by macro_translator.
|
||||||
|
"""
|
||||||
|
options = [str(klass.__name__) for klass in something.__bases__]
|
||||||
|
options += [something.__name__]
|
||||||
|
return (base in options)
|
||||||
|
|
||||||
|
def macro_translator(macro, token, line, skippable_macros):
|
||||||
"""
|
"""
|
||||||
Converts a line with a macro into a rgbasm-compatible line.
|
Converts a line with a macro into a rgbasm-compatible line.
|
||||||
"""
|
"""
|
||||||
@ -464,10 +477,10 @@ def macro_translator(macro, token, line):
|
|||||||
if show_original_lines:
|
if show_original_lines:
|
||||||
sys.stdout.write("; original_line: " + original_line)
|
sys.stdout.write("; original_line: " + original_line)
|
||||||
|
|
||||||
# "db" is a macro because of TextEndingCommand
|
# "db" is a macro because of SkippableMacro
|
||||||
# rgbasm can handle "db" so no preprocessing is required
|
# rgbasm can handle "db" so no preprocessing is required
|
||||||
# (don't check its param count)
|
# (don't check its param count)
|
||||||
if macro.macro_name == "db" and macro in [TextEndingCommand, ItemFragment]:
|
if macro.__name__ in skippable_macros or (macro.macro_name == "db" and macro in skippable_macros):
|
||||||
sys.stdout.write(original_line)
|
sys.stdout.write(original_line)
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -524,7 +537,10 @@ def macro_translator(macro, token, line):
|
|||||||
|
|
||||||
index = 0
|
index = 0
|
||||||
while index < len(params):
|
while index < len(params):
|
||||||
|
try:
|
||||||
param_type = macro.param_types[index - correction]
|
param_type = macro.param_types[index - correction]
|
||||||
|
except KeyError as exception:
|
||||||
|
raise Exception("line is: " + str(line) + " and macro is: " + str(macro))
|
||||||
description = param_type["name"]
|
description = param_type["name"]
|
||||||
param_klass = param_type["class"]
|
param_klass = param_type["class"]
|
||||||
byte_type = param_klass.byte_type # db or dw
|
byte_type = param_klass.byte_type # db or dw
|
||||||
@ -540,14 +556,14 @@ def macro_translator(macro, token, line):
|
|||||||
|
|
||||||
output += ("; " + description + "\n")
|
output += ("; " + description + "\n")
|
||||||
|
|
||||||
if size == 3 and issubclass(param_klass, PointerLabelBeforeBank):
|
if size == 3 and is_based_on(param_klass, "PointerLabelBeforeBank"):
|
||||||
# write the bank first
|
# write the bank first
|
||||||
output += ("db " + param + "\n")
|
output += ("db " + param + "\n")
|
||||||
# write the pointer second
|
# write the pointer second
|
||||||
output += ("dw " + params[index+1].strip() + "\n")
|
output += ("dw " + params[index+1].strip() + "\n")
|
||||||
index += 2
|
index += 2
|
||||||
correction += 1
|
correction += 1
|
||||||
elif size == 3 and issubclass(param_klass, PointerLabelAfterBank):
|
elif size == 3 and is_based_on(param_klass, "PointerLabelAfterBank"):
|
||||||
# write the pointer first
|
# write the pointer first
|
||||||
output += ("dw " + param + "\n")
|
output += ("dw " + param + "\n")
|
||||||
# write the bank second
|
# write the bank second
|
||||||
@ -570,7 +586,7 @@ def macro_translator(macro, token, line):
|
|||||||
|
|
||||||
sys.stdout.write(output)
|
sys.stdout.write(output)
|
||||||
|
|
||||||
def read_line(l):
|
def read_line(l, skippable_macros, macro_table):
|
||||||
"""Preprocesses a given line of asm."""
|
"""Preprocesses a given line of asm."""
|
||||||
|
|
||||||
# strip comments from asm
|
# strip comments from asm
|
||||||
@ -596,16 +612,23 @@ def read_line(l):
|
|||||||
|
|
||||||
# check against other preprocessor features
|
# check against other preprocessor features
|
||||||
else:
|
else:
|
||||||
macro, token = macro_test(asm)
|
macro, token = macro_test(asm, macro_table)
|
||||||
if macro:
|
if macro:
|
||||||
macro_translator(macro, token, asm)
|
macro_translator(macro, token, asm, skippable_macros)
|
||||||
else:
|
else:
|
||||||
sys.stdout.write(asm)
|
sys.stdout.write(asm)
|
||||||
|
|
||||||
if comment: sys.stdout.write(comment)
|
if comment: sys.stdout.write(comment)
|
||||||
|
|
||||||
def preprocess(lines=None):
|
def preprocess(macros, skippable_macros=None, lines=None):
|
||||||
"""Main entry point for the preprocessor."""
|
"""Main entry point for the preprocessor."""
|
||||||
|
if skippable_macros == None:
|
||||||
|
skippable_macros = [SkippableMacro]
|
||||||
|
|
||||||
|
macro_table = make_macro_table(list(set(macros + skippable_macros)))
|
||||||
|
|
||||||
|
# HACK for pokecrystal. Must be after make_macro_table call.
|
||||||
|
skippable_macros += ["TextEndingCommand"]
|
||||||
|
|
||||||
if not lines:
|
if not lines:
|
||||||
# read each line from stdin
|
# read each line from stdin
|
||||||
@ -615,8 +638,8 @@ def preprocess(lines=None):
|
|||||||
lines = lines.split("\n")
|
lines = lines.split("\n")
|
||||||
|
|
||||||
for l in lines:
|
for l in lines:
|
||||||
read_line(l)
|
read_line(l, skippable_macros, macro_table)
|
||||||
|
|
||||||
# only run against stdin when not included as a module
|
# only run against stdin when not included as a module
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
preprocess()
|
preprocess(macros)
|
||||||
|
@ -13,4 +13,4 @@ if __name__ == '__main__':
|
|||||||
dest = os.path.splitext(source)[0] + '.tx'
|
dest = os.path.splitext(source)[0] + '.tx'
|
||||||
sys.stdin = open(source, 'r')
|
sys.stdin = open(source, 'r')
|
||||||
sys.stdout = open(dest, 'w')
|
sys.stdout = open(dest, 'w')
|
||||||
preprocessor.preprocess()
|
preprocessor.preprocess(preprocessor.macros)
|
||||||
|
Loading…
Reference in New Issue
Block a user