return None
+class AssemblerError(Exception):
+ pass
+
+
class Database:
def __init__(self, root):
root = _pathlib.Path(root)
return self.__names.get(key)
raise ValueError("instruction or name expected")
+
+ def assemble(self, insn, macros=None):
+ def subst(argument):
+ again = True
+ while again:
+ again = False
+ argument = _re.sub(r"\s", "", argument)
+ for (macro, value) in macros.items():
+ if argument == macro:
+ again = True
+ argument = value
+ elif argument == f"{macro}.s":
+ again = True
+ argument = f"{value}.s"
+ elif argument == f"{macro}.v":
+ again = True
+ argument = f"{value}.v"
+ elif argument == f"*{macro}":
+ again = True
+ argument = f"*{value}"
+ elif argument == f"({macro})":
+ again = True
+ argument = f"({value})"
+ return argument
+
+ if macros is None:
+ macros = {}
+
+ (opcode, *arguments) = map(str.strip, _re.split(r"\s", insn))
+ arguments = _re.split(r",", "".join(arguments))
+ arguments = tuple(filter(bool, map(subst, arguments)))
+ record = self[opcode]
+ if record is not None:
+ return WordInstruction.assemble(record=record, arguments=arguments)
+
+ if opcode.startswith("sv."):
+ (opcode, *specifiers) = map(str.strip, opcode.split("/"))
+ specifiers = tuple(filter(bool, specifiers))
+ opcode = opcode[3:]
+ record = self[opcode]
+ if record is not None:
+ return SVP64Instruction.assemble(record=record,
+ arguments=arguments, specifiers=specifiers)
+
+ raise AssemblerError(opcode)