diff --git a/src/api/check.py b/src/api/check.py index b2dedbdba..7d252c49a 100644 --- a/src/api/check.py +++ b/src/api/check.py @@ -406,7 +406,7 @@ def is_temporary_value(node) -> bool: return node.token not in ("STRING", "VAR") and node.t[0] not in ("_", "#") -def common_type(a, b): +def common_type(a: symbols.TYPE | Type | None, b: symbols.TYPE | Type | None) -> symbols.TYPE | Type | None: """Returns a type which is common for both a and b types. Returns None if no common types allowed. """ @@ -435,7 +435,7 @@ def common_type(a, b): assert a.is_basic assert b.is_basic - types = (a, b) + types = a, b if Type.float_ in types: return Type.float_ diff --git a/src/arch/z80/backend/common.py b/src/arch/z80/backend/common.py index d870ca89d..b04895d2d 100644 --- a/src/arch/z80/backend/common.py +++ b/src/arch/z80/backend/common.py @@ -1,8 +1,8 @@ -# vim ts=4:et:sw=4:ai - import math import re -from typing import Any, Final +from enum import StrEnum +from types import MappingProxyType +from typing import Final from src.api import global_, tmp_labels from src.api.exception import TempAlreadyFreedError @@ -22,18 +22,46 @@ "strslice.asm", } + +class DataType(StrEnum): + bool = "bool" + u8 = "u8" + u16 = "u16" + u32 = "u32" + i8 = "i8" + i16 = "i16" + i32 = "i32" + f16 = "f16" + f = "f" + + +# Handy constants, to not having to type long names :-) +BOOL_t: Final[DataType] = DataType.bool +U8_t: Final[DataType] = DataType.u8 +U16_t: Final[DataType] = DataType.u16 +U32_t: Final[DataType] = DataType.u32 +I8_t: Final[DataType] = DataType.i8 +I16_t: Final[DataType] = DataType.i16 +I32_t: Final[DataType] = DataType.i32 +F16_t: Final[DataType] = DataType.f16 +F_t: Final[DataType] = DataType.f + + # Internal data types definition, with its size in bytes, or -1 if it is variable (string) # Compound types are only arrays, and have the t -YY_TYPES = { - "u8": 1, # 8 bit unsigned integer - "u16": 2, # 16 bit unsigned integer - "u32": 4, # 32 bit unsigned integer - "i8": 1, # 8 bit SIGNED integer - "i16": 2, # 16 bit SIGNED integer - "i32": 4, # 32 bit SIGNED integer - "f16": 4, # -32768.9999 to 32767.9999 -aprox.- fixed point decimal (step = 1/2^16) - "f": 5, # Floating point -} +YY_TYPES: Final[MappingProxyType[DataType, int]] = MappingProxyType( + { + BOOL_t: 1, + U8_t: 1, # 8 bit unsigned integer + U16_t: 2, # 16 bit unsigned integer + U32_t: 4, # 32 bit unsigned integer + I8_t: 1, # 8 bit SIGNED integer + I16_t: 2, # 16 bit SIGNED integer + I32_t: 4, # 32 bit SIGNED integer + F16_t: 4, # -32768.9999 to 32767.9999 -aprox.- fixed point decimal (step = 1/2^16) + F_t: 5, # Floating point + } +) # Matches a boolean instruction like 'equ16' or 'andi32' RE_BOOL: Final[re.Pattern] = re.compile(r"^(eq|ne|lt|le|gt|ge|and|or|xor|not)(([ui](8|16|32))|(f16|f|str))$") @@ -109,14 +137,14 @@ def is_2n(x: float) -> bool: return n == int(n) -def tmp_remove(label: str): +def tmp_remove(label: str) -> None: if label not in TMP_STORAGES: raise TempAlreadyFreedError(label) TMP_STORAGES.pop(TMP_STORAGES.index(label)) -def runtime_call(label: str): +def runtime_call(label: str) -> str: assert label in RUNTIME_LABELS, f"Invalid runtime label '{label}'" if label in LABEL_REQUIRED_MODULES: REQUIRES.add(LABEL_REQUIRED_MODULES[label]) @@ -129,7 +157,7 @@ def runtime_call(label: str): # ------------------------------------------------------------------ -def is_int(op: Any) -> bool: +def is_int(op: str) -> bool: """Returns True if the given operand (string) contains an integer number """ @@ -143,7 +171,7 @@ def is_int(op: Any) -> bool: return False -def is_float(op: Any) -> bool: +def is_float(op: str) -> bool: """Returns True if the given operand (string) contains a floating point number """ @@ -161,7 +189,7 @@ def _int_ops(op1: str, op2: str) -> tuple[str, str | int] | None: """Receives a list with two strings (operands). If none of them contains integers, returns None. Otherwise, returns a t-uple with (op[0], op[1]), - where op[1] (2nd operan) is always the integer one (the list is swapped) + where op[1] (2nd operand) is always the integer one (the list is swapped) This cannot be used by non-commutative operations like sub and div used this because they're not commutative). @@ -198,7 +226,7 @@ def _f_ops(op1: str, op2: str, *, swap: bool = True) -> tuple[str | float, str | return None -def is_int_type(stype: str) -> bool: +def is_int_type(stype: DataType) -> bool: """Returns whether a given type is integer""" return stype[0] in ("u", "i") @@ -268,65 +296,65 @@ def get_bytes_size(elements: list[str]) -> int: return len(get_bytes(elements)) -def to_byte(stype: str) -> list[str]: +def to_byte(stype: DataType) -> list[str]: """Returns the instruction sequence for converting from the given type to byte. """ output = [] - if stype in ("i8", "u8"): + if stype in (I8_t, U8_t): return [] if is_int_type(stype): output.append("ld a, l") - elif stype == "f16": + elif stype == F16_t: output.append("ld a, e") - elif stype == "f": # Converts C ED LH to byte + elif stype == F_t: # Converts C ED LH to byte output.append(runtime_call(RuntimeLabel.FTOU32REG)) output.append("ld a, l") return output -def to_word(stype: str) -> list[str]: +def to_word(stype: DataType) -> list[str]: """Returns the instruction sequence for converting the given type stored in DE,HL to word (unsigned) HL. """ output = [] # List of instructions - if stype == "u8": # Byte to word + if stype == U8_t: # Byte to word output.append("ld l, a") output.append("ld h, 0") - elif stype == "i8": # Signed byte to word + elif stype == I8_t: # Signed byte to word output.append("ld l, a") output.append("add a, a") output.append("sbc a, a") output.append("ld h, a") - elif stype == "f16": # Must MOVE HL into DE + elif stype == F16_t: # Must MOVE HL into DE output.append("ex de, hl") - elif stype == "f": + elif stype == F_t: output.append(runtime_call(RuntimeLabel.FTOU32REG)) return output -def to_long(stype: str) -> list[str]: +def to_long(stype: DataType) -> list[str]: """Returns the instruction sequence for converting the given type stored in DE,HL to long (DE, HL). """ output = [] # List of instructions - if stype in ("i8", "u8", "f16"): # Byte to word + if stype in {I8_t, U8_t, F16_t}: # Byte to word output = to_word(stype) - if stype != "f16": # If its a byte, just copy H to D,E + if stype != F16_t: # If it's a byte, just copy H to D,E output.append("ld e, h") output.append("ld d, h") - if stype in ("i16", "f16"): # Signed byte or fixed to word + if stype in (I16_t, F16_t): # Signed byte or fixed to word output.append("ld a, h") output.append("add a, a") output.append("sbc a, a") @@ -336,13 +364,13 @@ def to_long(stype: str) -> list[str]: elif stype == "u16": output.append("ld de, 0") - elif stype == "f": + elif stype == F_t: output.append(runtime_call(RuntimeLabel.FTOU32REG)) return output -def to_fixed(stype: str) -> list[str]: +def to_fixed(stype: DataType) -> list[str]: """Returns the instruction sequence for converting the given type stored in DE,HL to fixed DE,HL. """ @@ -352,33 +380,33 @@ def to_fixed(stype: str) -> list[str]: output = to_word(stype) output.append("ex de, hl") output.append("ld hl, 0") # 'Truncate' the fixed point - elif stype == "f": + elif stype == F_t: output.append(runtime_call(RuntimeLabel.FTOF16REG)) return output -def to_float(stype: str) -> list[str]: +def to_float(stype: DataType) -> list[str]: """Returns the instruction sequence for converting the given type stored in DE,HL to fixed DE,HL. """ output: list[str] = [] # List of instructions - if stype == "f": + if stype == F_t: return output # Nothing to do - if stype == "f16": + if stype == F16_t: output.append(runtime_call(RuntimeLabel.F16TOFREG)) return output # If we reach this point, it's an integer type - if stype == "u8": + if stype == U8_t: output.append(runtime_call(RuntimeLabel.U8TOFREG)) - elif stype == "i8": + elif stype == I8_t: output.append(runtime_call(RuntimeLabel.I8TOFREG)) else: output = to_long(stype) - if stype in ("i16", "i32"): + if stype in (I16_t, I32_t): output.append(runtime_call(RuntimeLabel.I32TOFREG)) else: output.append(runtime_call(RuntimeLabel.U32TOFREG)) diff --git a/src/arch/z80/visitor/translator.py b/src/arch/z80/visitor/translator.py index 745367e1b..86f735e72 100644 --- a/src/arch/z80/visitor/translator.py +++ b/src/arch/z80/visitor/translator.py @@ -1,4 +1,6 @@ from collections import namedtuple +from collections.abc import Callable +from typing import Any import src.api.errmsg import src.api.global_ as gl @@ -145,8 +147,29 @@ def visit_BINARY(self, node): yield node.right ins = {"PLUS": "add", "MINUS": "sub"}.get(node.operator, node.operator.lower()) - s = self.TSUFFIX(node.left.type_) # Operands type - self.emit(ins + s, node.t, str(node.left.t), str(node.right.t)) + ins_t: dict[str, Callable[[TYPE | symbols.BASICTYPE, Any, Any, Any], None]] = { + "add": self.ic_add, + "sub": self.ic_sub, + "mul": self.ic_mul, + "div": self.ic_div, + "or": self.ic_or, + "xor": self.ic_xor, + "and": self.ic_and, + "eq": self.ic_eq, + "ne": self.ic_ne, + "gt": self.ic_gt, + "lt": self.ic_lt, + "le": self.ic_le, + "ge": self.ic_ge, + "band": self.ic_band, + "bor": self.ic_bor, + "bxor": self.ic_bxor, + "shl": self.ic_shl, + "shr": self.ic_shr, + "pow": self.ic_pow, + "mod": self.ic_mod, + } + ins_t[ins](node.left.type_, node.t, str(node.left.t), str(node.right.t)) def visit_TYPECAST(self, node): yield node.operand diff --git a/src/arch/z80/visitor/translator_inst_visitor.py b/src/arch/z80/visitor/translator_inst_visitor.py index d731de347..a16a89640 100644 --- a/src/arch/z80/visitor/translator_inst_visitor.py +++ b/src/arch/z80/visitor/translator_inst_visitor.py @@ -2,6 +2,7 @@ from src.api.debug import __DEBUG__ from src.arch.interface.quad import Quad from src.arch.z80.backend import Backend +from src.arch.z80.backend.common import BOOL_t, F16_t, F_t, I8_t, I16_t, I32_t, U8_t, U16_t, U32_t from src.ast import NodeVisitor from src.symbols import sym as symbols @@ -10,26 +11,27 @@ class TranslatorInstVisitor(NodeVisitor): def __init__(self, backend: Backend): self.backend = backend - def emit(self, *args): + def emit(self, *args: str) -> None: """Convert the given args to a Quad (3 address code) instruction""" quad = Quad(*args) - __DEBUG__("EMIT " + str(quad)) + __DEBUG__(f"EMIT {quad!s}") self.backend.MEMORY.append(quad) @staticmethod - def TSUFFIX(type_): + def TSUFFIX(type_: TYPE | symbols.TYPEREF | symbols.BASICTYPE) -> str: assert isinstance(type_, symbols.TYPE) or TYPE.is_valid(type_) _TSUFFIX = { - TYPE.byte: "i8", - TYPE.ubyte: "u8", - TYPE.integer: "i16", - TYPE.uinteger: "u16", - TYPE.long: "i32", - TYPE.ulong: "u32", - TYPE.fixed: "f16", - TYPE.float: "f", + TYPE.byte: I8_t, + TYPE.ubyte: U8_t, + TYPE.integer: I16_t, + TYPE.uinteger: U16_t, + TYPE.long: I32_t, + TYPE.ulong: U32_t, + TYPE.fixed: F16_t, + TYPE.float: F_t, TYPE.string: "str", + TYPE.boolean: BOOL_t, } if isinstance(type_, symbols.TYPEREF): @@ -41,200 +43,205 @@ def TSUFFIX(type_): return _TSUFFIX[type_] - def ic_aaddr(self, t1, t2): - return self.emit("aaddr", t1, t2) + @classmethod + def _no_bool(cls, type_: TYPE | symbols.TYPEREF | symbols.BASICTYPE) -> str: + """Returns the corresponding type suffix except for bool which maps to U8_t""" + return cls.TSUFFIX(type_) if cls.TSUFFIX(type_) != BOOL_t else U8_t - def ic_abs(self, type_, t1, t2): - return self.emit("abs" + self.TSUFFIX(type_), t1, t2) + def ic_aaddr(self, t1, t2) -> None: + self.emit("aaddr", t1, t2) - def ic_add(self, type_, t1, t2, t3): - return self.emit("add" + self.TSUFFIX(type_), t1, t2, t3) + def ic_abs(self, type_: TYPE | symbols.BASICTYPE, t1, t2) -> None: + self.emit("abs" + self.TSUFFIX(type_), t1, t2) - def ic_aload(self, type_, t1, mangle: str): - return self.emit("aload" + self.TSUFFIX(type_), t1, mangle) + def ic_add(self, type_: TYPE | symbols.BASICTYPE, t1, t2, t3) -> None: + self.emit("add" + self.TSUFFIX(type_), t1, t2, t3) - def ic_and(self, type_): - return self.emit("and" + self.TSUFFIX(type_)) + def ic_aload(self, type_: TYPE | symbols.BASICTYPE, t1, mangle: str) -> None: + self.emit("aload" + self.TSUFFIX(type_), t1, mangle) - def ic_astore(self, type_, addr: str, t): - return self.emit("astore" + self.TSUFFIX(type_), addr, t) + def ic_and(self, type_: TYPE | symbols.BASICTYPE, t, t1, t2) -> None: + self.emit(f"and{self._no_bool(type_)}", t, t1, t2) - def ic_band(self, type_): - return self.emit("band" + self.TSUFFIX(type_)) + def ic_astore(self, type_: TYPE | symbols.BASICTYPE, addr: str, t) -> None: + self.emit("astore" + self.TSUFFIX(type_), addr, t) - def ic_bnot(self, type_, t1, t2): - return self.emit("bnot" + self.TSUFFIX(type_), t1, t2) + def ic_band(self, type_: TYPE | symbols.BASICTYPE, t, t1, t2) -> None: + self.emit("band" + self.TSUFFIX(type_), t, t1, t2) - def ic_bor(self, type_): - return self.emit("bor" + self.TSUFFIX(type_)) + def ic_bnot(self, type_: TYPE | symbols.BASICTYPE, t1, t2) -> None: + self.emit("bnot" + self.TSUFFIX(type_), t1, t2) - def ic_bxor(self, type_): - return self.emit("bxor" + self.TSUFFIX(type_)) + def ic_bor(self, type_: TYPE | symbols.BASICTYPE, t, t1, t2) -> None: + self.emit("bor" + self.TSUFFIX(type_), t, t1, t2) - def ic_call(self, label: str, num: int): - return self.emit("call", label, num) + def ic_bxor(self, type_: TYPE | symbols.BASICTYPE, t, t1, t2) -> None: + self.emit("bxor" + self.TSUFFIX(type_), t, t1, t2) - def ic_cast(self, t1, type1, type2, t2): + def ic_call(self, label: str, num: int) -> None: + self.emit("call", label, num) + + def ic_cast(self, t1, type1, type2, t2) -> None: self.emit("cast", t1, self.TSUFFIX(type1), self.TSUFFIX(type2), t2) - def ic_data(self, type_, data: list): - return self.emit("data", self.TSUFFIX(type_), data) + def ic_data(self, type_: TYPE | symbols.BASICTYPE, data: list) -> None: + self.emit("data", self.TSUFFIX(type_), data) - def ic_deflabel(self, label: str, t): - return self.emit("deflabel", label, t) + def ic_deflabel(self, label: str, t) -> None: + self.emit("deflabel", label, t) - def ic_div(self, type_): - return self.emit("div" + self.TSUFFIX(type_)) + def ic_div(self, type_: TYPE | symbols.BASICTYPE, t, t1, t2) -> None: + self.emit("div" + self.TSUFFIX(type_), t, t1, t2) - def ic_end(self, t): - return self.emit("end", t) + def ic_end(self, t) -> None: + self.emit("end", t) - def ic_enter(self, arg): - return self.emit("enter", arg) + def ic_enter(self, arg) -> None: + self.emit("enter", arg) - def ic_eq(self, type_, t, t1, t2): - return self.emit("eq" + self.TSUFFIX(type_), t, t1, t2) + def ic_eq(self, type_: TYPE | symbols.BASICTYPE, t, t1, t2) -> None: + self.emit("eq" + self.TSUFFIX(type_), t, t1, t2) - def ic_exchg(self): - return self.emit("exchg") + def ic_exchg(self) -> None: + self.emit("exchg") - def ic_fparam(self, type_, t): - return self.emit("fparam" + self.TSUFFIX(type_), t) + def ic_fparam(self, type_: TYPE | symbols.BASICTYPE, t) -> None: + self.emit("fparam" + self.TSUFFIX(type_), t) - def ic_fpload(self, type_, t, offset): - return self.emit("fpload" + self.TSUFFIX(type_), t, offset) + def ic_fpload(self, type_: TYPE | symbols.BASICTYPE, t, offset) -> None: + self.emit("fpload" + self.TSUFFIX(type_), t, offset) - def ic_ge(self, type_, t, t1, t2): - return self.emit("ge" + self.TSUFFIX(type_), t, t1, t2) + def ic_ge(self, type_: TYPE | symbols.BASICTYPE, t, t1, t2) -> None: + self.emit("ge" + self.TSUFFIX(type_), t, t1, t2) - def ic_gt(self, type_, t, t1, t2): - return self.emit("gt" + self.TSUFFIX(type_), t, t1, t2) + def ic_gt(self, type_: TYPE | symbols.BASICTYPE, t, t1, t2) -> None: + self.emit("gt" + self.TSUFFIX(type_), t, t1, t2) - def ic_in(self, t): - return self.emit("in", t) + def ic_in(self, t) -> None: + self.emit("in", t) - def ic_inline(self, asm_code: str): - return self.emit("inline", asm_code) + def ic_inline(self, asm_code: str) -> None: + self.emit("inline", asm_code) - def ic_jgezero(self, type_, t, label: str): - return self.emit("jgezero" + self.TSUFFIX(type_), t, label) + def ic_jgezero(self, type_: TYPE | symbols.BASICTYPE, t, label: str) -> None: + self.emit(f"jgezero{self._no_bool(type_)}", t, label) - def ic_jnzero(self, type_, t, label: str): - return self.emit("jnzero" + self.TSUFFIX(type_), t, label) + def ic_jnzero(self, type_: TYPE | symbols.BASICTYPE, t, label: str) -> None: + self.emit(f"jnzero{self._no_bool(type_)}", t, label) - def ic_jump(self, label: str): - return self.emit("jump", label) + def ic_jump(self, label: str) -> None: + self.emit("jump", label) - def ic_jzero(self, type_, t, label: str): - return self.emit("jzero" + self.TSUFFIX(type_), t, label) + def ic_jzero(self, type_: TYPE | symbols.BASICTYPE, t, label: str) -> None: + self.emit(f"jzero{self._no_bool(type_)}", t, label) - def ic_label(self, label: str): - return self.emit("label", label) + def ic_label(self, label: str) -> None: + self.emit("label", label) - def ic_larrd(self, offset, arg1, size, arg2, bound_ptrs): - return self.emit("larrd", offset, arg1, size, arg2, bound_ptrs) + def ic_larrd(self, offset, arg1, size, arg2, bound_ptrs) -> None: + self.emit("larrd", offset, arg1, size, arg2, bound_ptrs) - def ic_le(self, type_, t, t1, t2): - return self.emit("le" + self.TSUFFIX(type_), t, t1, t2) + def ic_le(self, type_: TYPE | symbols.BASICTYPE, t, t1, t2) -> None: + self.emit("le" + self.TSUFFIX(type_), t, t1, t2) - def ic_leave(self, convention: str): - return self.emit("leave", convention) + def ic_leave(self, convention: str) -> None: + self.emit("leave", convention) - def ic_lenstr(self, t1, t2): - return self.emit("lenstr", t1, t2) + def ic_lenstr(self, t1, t2) -> None: + self.emit("lenstr", t1, t2) - def ic_load(self, type_, t1, t2): - return self.emit("load" + self.TSUFFIX(type_), t1, t2) + def ic_load(self, type_: TYPE | symbols.BASICTYPE, t1, t2) -> None: + self.emit("load" + self.TSUFFIX(type_), t1, t2) - def ic_lt(self, type_, t, t1, t2): - return self.emit("lt" + self.TSUFFIX(type_), t, t1, t2) + def ic_lt(self, type_: TYPE | symbols.BASICTYPE, t, t1, t2) -> None: + self.emit("lt" + self.TSUFFIX(type_), t, t1, t2) - def ic_lvard(self, offset, default_value: list): - return self.emit("lvard", offset, default_value) + def ic_lvard(self, offset, default_value: list) -> None: + self.emit("lvard", offset, default_value) - def ic_lvarx(self, type_, offset, default_value: list): + def ic_lvarx(self, type_: TYPE | symbols.BASICTYPE, offset, default_value: list) -> None: self.emit("lvarx", offset, self.TSUFFIX(type_), default_value) - def ic_memcopy(self, t1, t2, t3): - return self.emit("memcopy", t1, t2, t3) + def ic_memcopy(self, t1, t2, t3) -> None: + self.emit("memcopy", t1, t2, t3) - def ic_mod(self, type_): - return self.emit("mod" + self.TSUFFIX(type_)) + def ic_mod(self, type_: TYPE | symbols.BASICTYPE, t, t1, t2) -> None: + self.emit("mod" + self.TSUFFIX(type_), t, t1, t2) - def ic_mul(self, type_): - return self.emit("mul" + self.TSUFFIX(type_)) + def ic_mul(self, type_: TYPE | symbols.BASICTYPE, t, t1, t2) -> None: + self.emit("mul" + self.TSUFFIX(type_), t, t1, t2) - def ic_ne(self, type_, t, t1, t2): - return self.emit("ne" + self.TSUFFIX(type_), t, t1, t2) + def ic_ne(self, type_: TYPE | symbols.BASICTYPE, t, t1, t2) -> None: + self.emit("ne" + self.TSUFFIX(type_), t, t1, t2) - def ic_neg(self, type_, t1, t2): - return self.emit("neg" + self.TSUFFIX(type_), t1, t2) + def ic_neg(self, type_: TYPE | symbols.BASICTYPE, t1, t2) -> None: + self.emit("neg" + self.TSUFFIX(type_), t1, t2) - def ic_nop(self): - return self.emit("nop") + def ic_nop(self) -> None: + self.emit("nop") - def ic_not(self, type_, t1, t2): - return self.emit("not" + self.TSUFFIX(type_), t1, t2) + def ic_not(self, type_: TYPE | symbols.BASICTYPE, t1, t2) -> None: + self.emit("not" + self.TSUFFIX(type_), t1, t2) - def ic_or(self, type_): - return self.emit("or" + self.TSUFFIX(type_)) + def ic_or(self, type_: TYPE | symbols.BASICTYPE, t, t1, t2) -> None: + self.emit(f"or{self._no_bool(type_)}", t, t1, t2) - def ic_org(self, type_): - return self.emit("org" + self.TSUFFIX(type_)) + def ic_org(self, type_: TYPE | symbols.BASICTYPE) -> None: + self.emit("org" + self.TSUFFIX(type_)) - def ic_out(self, t1, t2): - return self.emit("out", t1, t2) + def ic_out(self, t1, t2) -> None: + self.emit("out", t1, t2) - def ic_paaddr(self, t1, t2): - return self.emit("paaddr", t1, t2) + def ic_paaddr(self, t1, t2) -> None: + self.emit("paaddr", t1, t2) - def ic_paddr(self, t1, t2): - return self.emit("paddr", t1, t2) + def ic_paddr(self, t1, t2) -> None: + self.emit("paddr", t1, t2) - def ic_paload(self, type_, t, offset: int): - return self.emit("paload" + self.TSUFFIX(type_), t, offset) + def ic_paload(self, type_: TYPE | symbols.BASICTYPE, t, offset: int) -> None: + self.emit("paload" + self.TSUFFIX(type_), t, offset) - def ic_param(self, type_, t): - return self.emit("param" + self.TSUFFIX(type_), t) + def ic_param(self, type_: TYPE | symbols.BASICTYPE, t) -> None: + self.emit("param" + self.TSUFFIX(type_), t) - def ic_pastore(self, type_, offset, t): - return self.emit("pastore" + self.TSUFFIX(type_), offset, t) + def ic_pastore(self, type_: TYPE | symbols.BASICTYPE, offset, t) -> None: + self.emit("pastore" + self.TSUFFIX(type_), offset, t) - def ic_pload(self, type_, t1, offset): - return self.emit("pload" + self.TSUFFIX(type_), t1, offset) + def ic_pload(self, type_: TYPE | symbols.BASICTYPE, t1, offset) -> None: + self.emit("pload" + self.TSUFFIX(type_), t1, offset) - def ic_pow(self, type_): - return self.emit("pow" + self.TSUFFIX(type_)) + def ic_pow(self, type_: TYPE | symbols.BASICTYPE, t, t1, t2) -> None: + self.emit("pow" + self.TSUFFIX(type_), t, t1, t2) - def ic_pstore(self, type_, offset, t): - return self.emit("pstore" + self.TSUFFIX(type_), offset, t) + def ic_pstore(self, type_: TYPE | symbols.BASICTYPE, offset, t) -> None: + self.emit("pstore" + self.TSUFFIX(type_), offset, t) - def ic_ret(self, type_, t, addr): - return self.emit("ret" + self.TSUFFIX(type_), t, addr) + def ic_ret(self, type_: TYPE | symbols.BASICTYPE, t, addr) -> None: + self.emit("ret" + self.TSUFFIX(type_), t, addr) - def ic_return(self, addr): - return self.emit("ret", addr) + def ic_return(self, addr) -> None: + self.emit("ret", addr) - def ic_shl(self, type_): - return self.emit("shl" + self.TSUFFIX(type_)) + def ic_shl(self, type_: TYPE | symbols.BASICTYPE, t, t1, t2) -> None: + self.emit("shl" + self.TSUFFIX(type_), t, t1, t2) - def ic_shr(self, type_): - return self.emit("shr" + self.TSUFFIX(type_)) + def ic_shr(self, type_: TYPE | symbols.BASICTYPE, t, t1, t2) -> None: + self.emit("shr" + self.TSUFFIX(type_), t, t1, t2) - def ic_store(self, type_, t1, t2): - return self.emit("store" + self.TSUFFIX(type_), t1, t2) + def ic_store(self, type_: TYPE | symbols.BASICTYPE, t1, t2) -> None: + self.emit("store" + self.TSUFFIX(type_), t1, t2) - def ic_sub(self, type_): - return self.emit("sub" + self.TSUFFIX(type_)) + def ic_sub(self, type_: TYPE | symbols.BASICTYPE, t, t1, t2) -> None: + self.emit("sub" + self.TSUFFIX(type_), t, t1, t2) - def ic_var(self, name: str, size_): - return self.emit("var", name, size_) + def ic_var(self, name: str, size_) -> None: + self.emit("var", name, size_) - def ic_vard(self, name: str, data: list): - return self.emit("vard", name, data) + def ic_vard(self, name: str, data: list) -> None: + self.emit("vard", name, data) - def ic_varx(self, name: str, type_, default_value: list): - return self.emit("varx", name, self.TSUFFIX(type_), default_value) + def ic_varx(self, name: str, type_: TYPE | symbols.BASICTYPE, default_value: list) -> None: + self.emit("varx", name, self.TSUFFIX(type_), default_value) - def ic_xor(self, type_): - return self.emit("xor" + self.TSUFFIX(type_)) + def ic_xor(self, type_: TYPE | symbols.BASICTYPE, t, t1, t2) -> None: + self.emit("xor" + self.TSUFFIX(type_), t, t1, t2) diff --git a/src/zxbc/args_parser.py b/src/zxbc/args_parser.py index e50047a74..bbd1f66ac 100644 --- a/src/zxbc/args_parser.py +++ b/src/zxbc/args_parser.py @@ -86,7 +86,7 @@ def parser() -> argparse.ArgumentParser: "-f", "--output-format", type=str, - choices=FileType, + choices=[str(x) for x in FileType], required=False, help="Output format", )