diff options
| author | 2023-02-07 16:48:37 +0000 | |
|---|---|---|
| committer | 2023-02-07 16:48:37 +0000 | |
| commit | 5084bb7771344f8dda2d43788d0fed6e36f54948 (patch) | |
| tree | 86429dba0a40b22c4785b25ab5c9de875d1cd477 /asm.py | |
| parent | asm.py: write (diff) | |
asm.py: rename
Diffstat (limited to 'asm.py')
| -rw-r--r-- | asm.py | 124 |
1 files changed, 0 insertions, 124 deletions
@@ -1,124 +0,0 @@ -#!/usr/bin/python3 - -from enum import Enum - -class ArgType(Enum): - TYPE_IMM = 1 - TYPE_REG = 2 - TYPE_VAL = 3 - TYPE_LAB = 4 - - def gettype(s): - if s.isnumeric(): - return (TYPE_IMM, int(s)) - elif s[0] == 'r' and s[1:].isnumeric(): - return (TYPE_REG, int(s[1:])) - elif s[0] == 'l' and s[1:].isnumeric(): - return (TYPE_LAB, int(s[1:])) - else: - return None - - def typecheck(self, s): - t = ArgType.gettype(s) - if t is None: - return None - if self == TYPE_VAL: - return t[0] == TYPE_REG or t[0] == TYPE_IMM - else: - return t[0] == self - -class Instruction: - def __init__(self, opcode, argtypes): - self.opcode = opcode - assert self.opcode < 0x80 and self.opcode >= 0 - self.argtypes = argtypes - def typecheck(self, sargs): - rargs = [] - if len(sargs) != len(self.argtypes): - return None - for i in range(0, len(sargs)): - if not self.argtypes[i].typecheck(sargs[i]): - return None - rargs.append(ArgType.gettype(sargs[i])) - return rargs - -instructions = { -"NOP" : Instruction(0, []), -"PUSH" : Instruction(1, [ArgType.TYPE_REG]), -"POP" : Instruction(2, [ArgType.TYPE_REG]), -"ADD" : Instruction(3, [ArgType.TYPE_VAL, ArgType.TYPE_VAL, ArgType.TYPE_VAL]), -"MUL" : Instruction(4, [ArgType.TYPE_VAL, ArgType.TYPE_VAL, ArgType.TYPE_VAL]), -"DIV" : Instruction(5, [ArgType.TYPE_VAL, ArgType.TYPE_VAL, ArgType.TYPE_VAL]), -"JL" : Instruction(6, [ArgType.TYPE_LAB, ArgType.TYPE_VAL, ArgType.TYPE_VAL]), -"CLB" : Instruction(7, [ArgType.TYPE_LAB]), -"SYS" : Instruction(8, [ArgType.TYPE_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 -} - -def encode_pseudo_utf8(n, high_bits, to): - if to > 8 or to < 0: - return None - elif to == 1: - if n < 0x80: - return bytes([n]) - else: - return None - - (maxval, start_byte, n_tot) = encoding_types[to] - if n > maxval or high_bits > 15: - return None - 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 Line: - def __init__(self, opcode, args): - self.opcode = opcode - self.args = args - def __call__(self): - b = bytes([self.opcode]) - for a in args: - if a[0] == TYPE_REG: - b = b + encode_pseudo_utf8(a[1],1,None) - else: - b = b + encode_pseudo_utf8(a[1],0,None) - return b + bytes([0]) - -class Program: - def asm_push_line(self, ins, args): - self.asm.append(Line(ins, args)) - - def parse_asm_line(self, line): - line = line.split() - if line[0] not in instructions: - raise Exception - else: - ins = instructions[line[0]] - args_w_type = ins.typecheck(line[1:]) - if r is None: - raise Exception - 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): - self.asm = [] |
