Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/api/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
31 changes: 27 additions & 4 deletions src/arch/z80/visitor/translator.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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

Expand All @@ -30,7 +31,10 @@
"Translator",
)

LabelledData = namedtuple("LabelledData", ("label", "data"))

class LabelledData(NamedTuple):
label: str
data: list[str]


class Translator(TranslatorVisitor):
Expand Down Expand Up @@ -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()
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/arch/z80/visitor/translator_inst_visitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion src/symbols/argument.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 15 additions & 12 deletions src/symbols/arrayaccess.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
3 changes: 2 additions & 1 deletion src/symbols/arrayload.py
Original file line number Diff line number Diff line change
Expand Up @@ -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