diff --git a/src/api/check.py b/src/api/check.py index 6ec983812..228cddb04 100644 --- a/src/api/check.py +++ b/src/api/check.py @@ -160,13 +160,13 @@ def check_call_arguments(lineno: int, id_: str, args, filename: str): return False if param.byref: - if not isinstance(arg.value, symbols.ID): + if not isinstance(arg.value, (symbols.ID, symbols.ARRAYLOAD)): errmsg.error( lineno, "Expected a variable name, not an expression (parameter By Reference)", fname=arg.filename ) return False - if arg.class_ not in (CLASS.var, CLASS.array): + if arg.class_ not in (CLASS.var, CLASS.array, CLASS.unknown): errmsg.error(lineno, "Expected a variable or array name (parameter By Reference)") return False diff --git a/src/arch/z80/visitor/translator.py b/src/arch/z80/visitor/translator.py index 3ffe1a1ca..8b47a634b 100644 --- a/src/arch/z80/visitor/translator.py +++ b/src/arch/z80/visitor/translator.py @@ -1,6 +1,5 @@ -from collections import namedtuple from collections.abc import Callable -from typing import Any +from typing import Any, NamedTuple import src.api.errmsg import src.api.global_ as gl @@ -22,6 +21,8 @@ from src.arch.z80.visitor.translator_visitor import JumpTable, TranslatorVisitor from src.arch.z80.visitor.unary_op_translator import UnaryOpTranslator from src.symbols import sym as symbols +from src.symbols.arrayaccess import SymbolARRAYACCESS +from src.symbols.binary import SymbolBINARY from src.symbols.id_ import ref from src.symbols.type_ import Type @@ -30,7 +31,10 @@ "Translator", ) -LabelledData = namedtuple("LabelledData", ("label", "data")) + +class LabelledData(NamedTuple): + label: str + data: list[str] class Translator(TranslatorVisitor): @@ -210,7 +214,10 @@ def visit_ARGUMENT(self, node): else: yield node.value self.ic_param(node.type_, node.t) - else: + return + + # ByRef argument + if node.value.token not in ("ARRAYLOAD", "ARRAYACCESS"): scope = node.value.scope if node.t[0] == "_": t = optemps.new_t() @@ -229,6 +236,22 @@ def visit_ARGUMENT(self, node): self.ic_paddr(-node.value.offset, t) self.ic_param(TYPE.uinteger, t) + return + + # Must compute Address of @array(...) + if node.value.scope == SCOPE.global_ and self.O_LEVEL > 1: # Calculate offset if global variable + node.value = SymbolBINARY.make_node( + "PLUS", + symbols.UNARY("ADDRESS", node.value.entry, node.value.lineno, type_=self.TYPE(gl.PTR_TYPE)), + symbols.NUMBER(node.value.offset, lineno=node.value.lineno, type_=self.TYPE(gl.PTR_TYPE)), + lineno=node.lineno, + func=lambda x, y: x + y, + ) + else: + node.value = SymbolARRAYACCESS.copy_from(node.value) + node.value = symbols.UNARY("ADDRESS", node.value, node.lineno, type_=self.TYPE(gl.PTR_TYPE)) + + yield node.value def visit_ARRAYLOAD(self, node): scope = node.entry.scope diff --git a/src/arch/z80/visitor/translator_inst_visitor.py b/src/arch/z80/visitor/translator_inst_visitor.py index 538c9340e..b31d991f2 100644 --- a/src/arch/z80/visitor/translator_inst_visitor.py +++ b/src/arch/z80/visitor/translator_inst_visitor.py @@ -195,7 +195,7 @@ def ic_paaddr(self, t1, t2) -> None: def ic_paddr(self, t1, t2) -> None: self.emit("paddr", t1, t2) - def ic_paload(self, type_: TYPE | sym.BASICTYPE, t, offset: int) -> None: + def ic_paload(self, type_: TYPE | sym.BASICTYPE, t, offset: str) -> None: self.emit(f"paload{self.TSUFFIX(type_)}", t, offset) def ic_param(self, type_: TYPE | sym.BASICTYPE, t) -> None: diff --git a/src/symbols/argument.py b/src/symbols/argument.py index 87fbd014c..88be760d9 100644 --- a/src/symbols/argument.py +++ b/src/symbols/argument.py @@ -63,7 +63,7 @@ def byref(self): @byref.setter def byref(self, value): if value: - assert self.value.token in ("VAR", "VARARRAY") + assert self.value.token in ("VAR", "VARARRAY", "ARRAYLOAD") self._byref = value @property diff --git a/src/symbols/arrayaccess.py b/src/symbols/arrayaccess.py index b743c6c4a..f95806e06 100644 --- a/src/symbols/arrayaccess.py +++ b/src/symbols/arrayaccess.py @@ -1,6 +1,12 @@ -# vim: ts=4:et:sw=4: +# ---------------------------------------------------------------------- +# Copyleft (K), Jose M. Rodriguez-Rosa (a.k.a. Boriel) +# +# This program is Free Software and is released under the terms of +# the GNU General License +# ---------------------------------------------------------------------- + from functools import cached_property -from typing import Optional +from typing import Self import src.api.global_ as gl from src.api import check, errmsg @@ -10,13 +16,6 @@ from src.symbols.id_ import SymbolID from src.symbols.typecast import SymbolTYPECAST as TYPECAST -# ---------------------------------------------------------------------- -# Copyleft (K), Jose M. Rodriguez-Rosa (a.k.a. Boriel) -# -# This program is Free Software and is released under the terms of -# the GNU General License -# ---------------------------------------------------------------------- - class SymbolARRAYACCESS(SymbolCALL): """Defines an array access. It's pretty much like a function call @@ -38,7 +37,7 @@ def __init__(self, entry, arglist: SymbolARGLIST, lineno: int, filename: str): self.entry.ref.is_dynamically_accessed = True @property - def entry(self): + def entry(self) -> SymbolID: return self.children[0] @entry.setter @@ -54,7 +53,7 @@ def type_(self): return self.entry.type_ @property - def arglist(self): + def arglist(self) -> SymbolARGLIST: return self.children[1] @arglist.setter @@ -98,7 +97,7 @@ def is_constant(self) -> bool: return self.offset is None @classmethod - def make_node(cls, id_: str, arglist: SymbolARGLIST, lineno: int, filename: str) -> Optional["SymbolARRAYACCESS"]: + def make_node(cls, id_: str, arglist: SymbolARGLIST, lineno: int, filename: str) -> Self | None: """Creates an array access. A(x1, x2, ..., xn)""" assert isinstance(arglist, SymbolARGLIST) variable = gl.SYMBOL_TABLE.access_array(id_, lineno) @@ -129,3 +128,7 @@ def make_node(cls, id_: str, arglist: SymbolARGLIST, lineno: int, filename: str) # Returns the variable entry and the node return cls(variable, arglist, lineno, filename) + + @classmethod + def copy_from(cls, other: Self) -> Self | None: + return cls(entry=other.entry, arglist=other.arglist, lineno=other.lineno, filename=other.filename) diff --git a/src/symbols/arrayload.py b/src/symbols/arrayload.py index 171e34d93..d6c7f0738 100644 --- a/src/symbols/arrayload.py +++ b/src/symbols/arrayload.py @@ -12,7 +12,8 @@ class SymbolARRAYLOAD(SymbolARRAYACCESS): """This class is the same as SymbolARRAYACCESS, we just declare it to make - a distinction. (e.g. the Token is gotten from the class name) + a distinction. (e.g. the Token is gotten from the class name). + """ pass