diff options
| author | 2023-02-07 17:46:44 +0000 | |
|---|---|---|
| committer | 2023-02-07 17:46:44 +0000 | |
| commit | f6e8c62f9e00210930bf222c077abef6c6d7cb34 (patch) | |
| tree | bc6b04e06d6338b3fed63ec4f1ad2d704ee6dd19 /creole_asm.py | |
| parent | add label test (diff) | |
move python
Diffstat (limited to 'creole_asm.py')
| -rw-r--r-- | creole_asm.py | 165 |
1 files changed, 0 insertions, 165 deletions
diff --git a/creole_asm.py b/creole_asm.py deleted file mode 100644 index 8e87b58..0000000 --- a/creole_asm.py +++ /dev/null @@ -1,165 +0,0 @@ -#!/usr/bin/python3 - -from enum import Enum - -class MalformedArgument(Exception): - pass - -class ArgType(Enum): - IMM = 1 - REG = 2 - VAL = 3 - LAB = 4 - - def gettype(s): - if s.isnumeric(): - return (ArgType.IMM, int(s)) - elif s[0] == 'r' and s[1:].isnumeric(): - return (ArgType.REG, int(s[1:])) - elif s[0] == 'l' and s[1:].isnumeric(): - return (ArgType.LAB, int(s[1:])) - else: - raise MalformedArgument(s) - - def typecheck(self, s): - t = ArgType.gettype(s) - if self == ArgType.VAL: - return t[0] == ArgType.REG or t[0] == ArgType.IMM - else: - return t[0] == self - -class OpcodeException(Exception): - pass -class TypecheckLenException(Exception): - pass -class TypecheckException(Exception): - pass -class Instruction: - def __init__(self, opcode, argtypes): - if opcode > 0x7F or opcode < 0: - raise OpcodeException(opcode) - - self.opcode = opcode - self.argtypes = argtypes - def typecheck(self, sargs): - rargs = [] - if len(sargs) != len(self.argtypes): - raise TypecheckLenException(sargs, self.argtypes) - for i in range(0, len(sargs)): - if not self.argtypes[i].typecheck(sargs[i]): - raise TypecheckException(self.argtypes[i], - sargs[i]) - rargs.append(ArgType.gettype(sargs[i])) - return rargs - -instructions = { -"nop" : Instruction(0, []), -"push" : Instruction(1, [ArgType.REG]), -"pop" : Instruction(2, [ArgType.REG]), -"add" : Instruction(3, [ArgType.VAL, ArgType.VAL, ArgType.VAL]), -"mul" : Instruction(4, [ArgType.VAL, ArgType.VAL, ArgType.VAL]), -"div" : Instruction(5, [ArgType.VAL, ArgType.VAL, ArgType.VAL]), -"jl" : Instruction(6, [ArgType.LAB, ArgType.VAL, ArgType.VAL]), -"clb" : Instruction(7, [ArgType.LAB]), -"sys" : Instruction(8, [ArgType.VAL]) -} - -encoding_types = { -# start mask A B - 2: (0x7F, 0xC0, 7), - 3: (0xFFF, 0xE0, 12), - 4: (0x1FFFF, 0xF0, 16), - 5: (0x3FFFFF, 0xF8, 21), - 6: (0x7FFFFFF, 0xFC, 26), - 7: (0xFFFFFFFF, 0xFE, 36), -# A : number of bits in start byte -# B : Total number of bits excluding high bits -} - -class InvalidNumberException(Exception): - pass -class InvalidLengthException(Exception): - pass -def encode_pseudo_utf8(n, high_bits, to): - if n < 0: - raise InvalidNumberException(n) - if to is None or to < 0: - for k in sorted(encoding_types): - if n <= encoding_types[k][0]: - to = k - break - if to is None: - raise InvalidNumberException(n) - if to > 8 or to < 0: - raise InvalidLengthException(to) - elif to == 1: - if n < 0x80: - return bytes([n]) - else: - raise InvalidNumberException(n,to) - - (maxval, start_byte, n_tot) = encoding_types[to] - if n > maxval or high_bits > 15: - raise InvalidNumberException(n, high_bits) - n = n | (high_bits << n_tot) - all_bytes = [] - for i in range(0, to - 1): - all_bytes.append(0x80 | (n & 0x3F)) - n >>= 6 - all_bytes.append(start_byte | n) - return bytes(reversed(all_bytes)) - -class RangeCheckException(Exception): - pass -class Line: - def __init__(self, opcode, args, labnum, regnum): - self.opcode = opcode - self.args = args - for a in args: - if a[0] == ArgType.REG: - if a[1] < 0 or a[1] >= regnum: - raise RangeCheckException(a[0], - a[1], - regnum) - elif a[0] == ArgType.LAB: - if a[1] < 0 or a[1] >= labnum: - raise RangeCheckException(a[0], - a[1], - regnum) - - def __call__(self): - b = bytes([self.opcode]) - for a in self.args: - l = 2 if a[1] < 0x80 else None - if a[0] == ArgType.REG: - b = b + encode_pseudo_utf8(a[1],1,l) - else: - b = b + encode_pseudo_utf8(a[1],0,l) - return b + bytes([0]) - -class InstructionNotFoundException(Exception): - pass -class Program: - def asm_push_line(self, ins, args): - self.asm.append(Line(ins, args, self.labnum, self.regnum)) - - def parse_asm_line(self, line): - line = line.split() - line[0] = line[0].casefold() - if line[0] not in instructions: - raise InstructionNotFoundException(line[0]) - else: - ins = instructions[line[0]] - args_w_type = ins.typecheck(line[1:]) - self.asm_push_line(ins.opcode, args_w_type) - - def __call__(self): - b = bytes() - for line in self.asm: - b = b + line() - return b - - def __init__(self, labnum=16, regnum=16): - self.asm = [] - self.labnum = labnum - self.regnum = regnum |
