diff options
| author | 2023-02-18 16:05:09 +0000 | |
|---|---|---|
| committer | 2023-02-18 16:05:09 +0000 | |
| commit | 48827c5b747eca6d56555f69cae37291feb5fcda (patch) | |
| tree | 063bc21af510fe961a7002678e0cdf9dbb8bc228 /asm/creole.py | |
| parent | add data, remove labels and make jumps absolute (diff) | |
adjust python assembler to new API
Diffstat (limited to 'asm/creole.py')
| -rw-r--r-- | asm/creole.py | 78 |
1 files changed, 57 insertions, 21 deletions
diff --git a/asm/creole.py b/asm/creole.py index 8bf609a..559d663 100644 --- a/asm/creole.py +++ b/asm/creole.py @@ -65,6 +65,24 @@ class Argument: """ Returns the high bits that the argument would have in the opcode. """ return int(self.sign) << 1 | (self.at == ArgType.REG) + def __call__(self): + l = 2 if self.val < 0x80 else None + return encode_pseudo_utf8(self.val, self.high_bits(), l) + +class StringArgument(Argument): + def __init__(self, *args, **kwargs): + super().__init__(self, *args, **kwargs) + def __bytes__(self): + b = bytes() + for v in self.val: + b = b + Argument(ArgType.IMM, v)() + return b + +class LabelArgument(Argument): + def __init__(self, *args, **kwargs): + super().__init__(self, *args, **kwargs) + def load_label(self, labels): + self.val = labels[val] class ArgType(Enum): """ Class denoting the type of an argument to an instruction. """ @@ -78,8 +96,17 @@ class ArgType(Enum): VAL = 3 """ Type that denotes either immediate values or registers. """ - LAB = 4 - """ Type of labels. """ + DAT = 4 + """ Type of data label. """ + + STR = 5 + """ Type of a string of 32 bit integers. """ + + LAB = 6 + """ Type of a label (.name). """ + + def is_number(t): + return t == ArgType.IMM or t == ArgType.REG def gettype(s): """ Parses the type of the argument represented as a string @@ -97,14 +124,18 @@ class ArgType(Enum): :return: The Argument object representing the argument. :raises MalformedArgument: """ - if s.isnumeric(): + if type(s) is list: + return StringArgument(ArgType.STR, s) + elif s.isnumeric(): return Argument(ArgType.IMM, int(s)) elif s[0] == "-" and s[1:].isnumeric(): return Argument(ArgType.IMM, word_2c(int(s[1:])), True) elif s[0] == 'r' and s[1:].isnumeric(): return Argument(ArgType.REG, int(s[1:])) - elif s[0] == 'l' and s[1:].isnumeric(): - return Argument(ArgType.LAB, int(s[1:])) + elif s[0] == 'd' and s[1:].isnumeric(): + return Argument(ArgType.DAT, int(s[1:])) + elif s[0] == '.': + return Argument(ArgType.LAB, s[1:]) else: raise MalformedArgument(s) @@ -168,14 +199,14 @@ class Instruction(Enum): DIV = 5, "_render_default", ArgType.REG, ArgType.VAL, ArgType.VAL SDIV = "DIV", "_render_change_args", ArgType.REG, ArgType.VAL, ArgType.VAL SYS = 6, "_render_default", ArgType.VAL - CLB = 7, "_render_default", ArgType.LAB - JL = 8, "_render_default", ArgType.LAB, ArgType.VAL, ArgType.VAL + JL = 7, "_render_default", ArgType.LAB, ArgType.VAL, ArgType.VAL JLS = "JL", "_render_change_args", ArgType.LAB, ArgType.VAL, ArgType.VAL - JLE = 9, "_render_default", ArgType.LAB, ArgType.VAL, ArgType.VAL + JLE = 8, "_render_default", ArgType.LAB, ArgType.VAL, ArgType.VAL JLES = "JLE", "_render_change_args", ArgType.LAB, ArgType.VAL, ArgType.VAL - JE = 10, "_render_default", ArgType.LAB, ArgType.VAL, ArgType.VAL + JE = 9, "_render_default", ArgType.LAB, ArgType.VAL, ArgType.VAL J = "JE", "_render_j", ArgType.LAB - JNE = 11, "_render_default", ArgType.LAB, ArgType.VAL, ArgType.VAL + JNE = 10, "_render_default", ArgType.LAB, ArgType.VAL, ArgType.VAL + DB = 11, "_render_default", ArgType.DAT, ArgType.STR def __int__(self): """ Returns the opcode associated with the Instruction. @@ -244,16 +275,14 @@ class Instruction(Enum): def _render_change_args(self, args): for i in range(0,len(args)): - if args[i].at != ArgType.LAB: + if ArgType.is_number(args[i].at): args[i].sign = True return Instruction[self.opcode].render(args) def _render_default(self, args): b = bytes([self.opcode]) for a in args: - l = 2 if a.val < 0x80 else None - bex = encode_pseudo_utf8(a.val, a.high_bits(), l) - b = b + bex + b = b + a() return b + bytes([0]) encoding_types = { @@ -314,12 +343,11 @@ class Line: raise RangeCheckException(a.at, a.val, reglen) - elif a.at == ArgType.LAB: - if a.val < 0 or a.val >= lablen: - raise RangeCheckException(a.at, - a.val, - reglen) + def load_label(self, labels): + for a in self.args: + if a.at == ArgType.LAB: + a.load_label(labels) def __call__(self): return self.ins.render(self.args) @@ -332,10 +360,13 @@ class Program: self.asm.append(l) def parse_asm_line(self, line): - line = line.split() + line = line.strip().split() line[0] = line[0].casefold() + if line[0][0] == '.': + self.asm.append(line[0][1:]) + return None + try: - # TODO: is there no better way to do this in Python? ins = Instruction[line[0].upper()] except Exception as e: raise InstructionNotFoundException(line[0]) @@ -349,7 +380,12 @@ class Program: def __call__(self): b = bytes() + labels = {} for line in self.asm: + if type(line) is str: + labels[line] = len(b) + continue + line.load_label(labels) b = b + line() return b |
