From c67bb853e8db3700646125ca4bedbf30307f3cf1 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 26 Feb 2026 00:14:36 +0100 Subject: [PATCH 1/2] fix: Detect static expressions better. Now all non-static expressions are also allowed as initializers. They are just a hiden lazy LET --- src/api/check.py | 24 ++++++++++++++++++++++-- src/zxbc/zxbparser.py | 7 +++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/api/check.py b/src/api/check.py index c9425fcb1..b52092332 100644 --- a/src/api/check.py +++ b/src/api/check.py @@ -160,7 +160,7 @@ def check_call_arguments(lineno: int, id_: str, args: symbols.ARGLIST, filename: return False if param.byref: - if not isinstance(arg.value, (symbols.ID, symbols.ARRAYLOAD)): + 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 ) @@ -310,11 +310,31 @@ def is_CONST(*p: symbols.SYMBOL) -> bool: return is_SYMBOL("CONSTEXPR", *p) +def _is_static_unary(x: symbols.SYMBOL) -> bool: + if x.token != "UNARY": + return False + + if x.operator != "ADDRESS": + return False + + if x.operand.token == "LABEL": + return True + + if x.operand.token in ("ID", "VAR"): + return x.operand.scope == SCOPE.global_ + + if x.operand.token == "ARRAYACCESS": + return is_static(*(arg.value for arg in x.operand.args)) + + return False + + def is_static(*p: symbols.SYMBOL) -> bool: """A static value (does not change at runtime) which is known at compile time """ - return all(is_CONST(x) or is_number(x) or is_const(x) for x in p) + assert all(isinstance(x, symbols.SYMBOL) for x in p) + return all(is_CONST(x) or is_number(x) or is_const(x) or _is_static_unary(x) for x in p) def is_number(*p): diff --git a/src/zxbc/zxbparser.py b/src/zxbc/zxbparser.py index d8c9195c7..ab63938ac 100755 --- a/src/zxbc/zxbparser.py +++ b/src/zxbc/zxbparser.py @@ -246,7 +246,7 @@ def make_builtin( type_: sym.TYPE | None = None, ) -> sym.BUILTIN | sym.NUMBER: """Wrapper: returns a Builtin function node. - Can be a Symbol, tuple or list of Symbols + Can be a Symbol, tuple, or list of Symbols If operand is an iterable, they will be expanded. """ if operands is None: @@ -736,9 +736,8 @@ def p_var_decl_ini(p): if expr is None: return - if not is_static(expr): - if isinstance(expr, sym.UNARY): - expr = make_constexpr(p.lineno(4), expr) # Delayed constant evaluation + if is_static(expr) and isinstance(expr, sym.UNARY): + expr = make_constexpr(p.lineno(4), expr) # Delayed constant evaluation if typedef.implicit: typedef = sym.TYPEREF(expr.type_, p.lexer.lineno, implicit=True) From 2cebfac09c91cd41cb424c9f187b78c4757c77ec Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 26 Feb 2026 00:29:57 +0100 Subject: [PATCH 2/2] Add tests With this update tests must be also updated. --- tests/functional/arch/zx48k/dim_at0.bas | 2 + tests/functional/arch/zx48k/dim_at1.bas | 6 +++ tests/functional/arch/zx48k/dimconst2.bas | 3 +- tests/functional/arch/zx48k/dimconst2b.asm | 62 ++++++++++++++++++++++ tests/functional/arch/zx48k/dimconst2b.bas | 4 +- tests/functional/arch/zx48k/dimconst2c.bas | 4 +- tests/functional/arch/zx48k/dimconst2d.bas | 4 +- tests/functional/arch/zx48k/dimconst2f.asm | 50 +++++++++++++++++ tests/functional/arch/zx48k/dimconst2f.bas | 6 +++ tests/functional/arch/zx48k/dimconst2g.asm | 59 ++++++++++++++++++++ tests/functional/arch/zx48k/dimconst2g.bas | 7 +++ tests/functional/arch/zx48k/dimconst2h.asm | 51 ++++++++++++++++++ tests/functional/arch/zx48k/dimconst2h.bas | 6 +++ tests/functional/arch/zx48k/dimconst2i.asm | 53 ++++++++++++++++++ tests/functional/arch/zx48k/dimconst2i.bas | 6 +++ 15 files changed, 315 insertions(+), 8 deletions(-) create mode 100644 tests/functional/arch/zx48k/dim_at1.bas create mode 100644 tests/functional/arch/zx48k/dimconst2b.asm create mode 100644 tests/functional/arch/zx48k/dimconst2f.asm create mode 100644 tests/functional/arch/zx48k/dimconst2f.bas create mode 100644 tests/functional/arch/zx48k/dimconst2g.asm create mode 100644 tests/functional/arch/zx48k/dimconst2g.bas create mode 100644 tests/functional/arch/zx48k/dimconst2h.asm create mode 100644 tests/functional/arch/zx48k/dimconst2h.bas create mode 100644 tests/functional/arch/zx48k/dimconst2i.asm create mode 100644 tests/functional/arch/zx48k/dimconst2i.bas diff --git a/tests/functional/arch/zx48k/dim_at0.bas b/tests/functional/arch/zx48k/dim_at0.bas index 774c6b6fd..551aa5165 100644 --- a/tests/functional/arch/zx48k/dim_at0.bas +++ b/tests/functional/arch/zx48k/dim_at0.bas @@ -1,3 +1,5 @@ +declare sub test2 + sub test1() DIM dummy as Uinteger = @test2 end sub diff --git a/tests/functional/arch/zx48k/dim_at1.bas b/tests/functional/arch/zx48k/dim_at1.bas new file mode 100644 index 000000000..774c6b6fd --- /dev/null +++ b/tests/functional/arch/zx48k/dim_at1.bas @@ -0,0 +1,6 @@ +sub test1() + DIM dummy as Uinteger = @test2 +end sub + +sub test2 +end sub diff --git a/tests/functional/arch/zx48k/dimconst2.bas b/tests/functional/arch/zx48k/dimconst2.bas index 40bf15053..4a2bd3400 100644 --- a/tests/functional/arch/zx48k/dimconst2.bas +++ b/tests/functional/arch/zx48k/dimconst2.bas @@ -1,6 +1,5 @@ +Map: Function q DIM q as Uinteger = @Map End Function - -Map: diff --git a/tests/functional/arch/zx48k/dimconst2b.asm b/tests/functional/arch/zx48k/dimconst2b.asm new file mode 100644 index 000000000..cc5304501 --- /dev/null +++ b/tests/functional/arch/zx48k/dimconst2b.asm @@ -0,0 +1,62 @@ + org 32768 +.core.__START_PROGRAM: + di + push ix + push iy + exx + push hl + exx + ld (.core.__CALL_BACK__), sp + ei + jp .core.__MAIN_PROGRAM__ +.core.__CALL_BACK__: + DEFW 0 +.core.ZXBASIC_USER_DATA: + ; Defines USER DATA Length in bytes +.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA + .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN + .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA +_Map: + DEFB 00 +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + ld a, 2 + ld (_Map), a + ld hl, 0 + ld b, h + ld c, l +.core.__END_PROGRAM: + di + ld hl, (.core.__CALL_BACK__) + ld sp, hl + exx + pop hl + exx + pop iy + pop ix + ei + ret +_q: + push ix + ld ix, 0 + add ix, sp + ld hl, 0 + push hl + push ix + pop hl + ld bc, -2 + add hl, bc + ex de, hl + ld hl, .LABEL.__LABEL0 + ld bc, 2 + ldir + ld a, 1 + ld (_Map), a +_q__leave: + ld sp, ix + pop ix + ret + ;; --- end of user code --- +.LABEL.__LABEL0: + DEFW _Map + END diff --git a/tests/functional/arch/zx48k/dimconst2b.bas b/tests/functional/arch/zx48k/dimconst2b.bas index ac72a71da..74f1e4f02 100644 --- a/tests/functional/arch/zx48k/dimconst2b.bas +++ b/tests/functional/arch/zx48k/dimconst2b.bas @@ -1,6 +1,6 @@ +Map = 2 + Function q DIM q as Uinteger = @Map Map = 1 End Function - -Map = 2 diff --git a/tests/functional/arch/zx48k/dimconst2c.bas b/tests/functional/arch/zx48k/dimconst2c.bas index 8729561d4..c4f87b10f 100644 --- a/tests/functional/arch/zx48k/dimconst2c.bas +++ b/tests/functional/arch/zx48k/dimconst2c.bas @@ -1,5 +1,5 @@ +Let Map = 1 + Function q DIM q as Uinteger = @Map End Function - -Let Map = 1 diff --git a/tests/functional/arch/zx48k/dimconst2d.bas b/tests/functional/arch/zx48k/dimconst2d.bas index 2554fa064..98c175ccf 100644 --- a/tests/functional/arch/zx48k/dimconst2d.bas +++ b/tests/functional/arch/zx48k/dimconst2d.bas @@ -1,5 +1,5 @@ +Dim Map = 1 + Function q DIM q as Uinteger = @Map End Function - -Dim Map = 1 diff --git a/tests/functional/arch/zx48k/dimconst2f.asm b/tests/functional/arch/zx48k/dimconst2f.asm new file mode 100644 index 000000000..6c23bcac0 --- /dev/null +++ b/tests/functional/arch/zx48k/dimconst2f.asm @@ -0,0 +1,50 @@ + org 32768 +.core.__START_PROGRAM: + di + push ix + push iy + exx + push hl + exx + ld (.core.__CALL_BACK__), sp + ei + jp .core.__MAIN_PROGRAM__ +.core.__CALL_BACK__: + DEFW 0 +.core.ZXBASIC_USER_DATA: + ; Defines USER DATA Length in bytes +.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA + .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN + .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: +.LABEL._Map: + ld hl, 0 + ld b, h + ld c, l +.core.__END_PROGRAM: + di + ld hl, (.core.__CALL_BACK__) + ld sp, hl + exx + pop hl + exx + pop iy + pop ix + ei + ret +_q: + push ix + ld ix, 0 + add ix, sp + ld hl, 0 + push hl + ld hl, .LABEL._Map + ld (ix-2), l + ld (ix-1), h +_q__leave: + ld sp, ix + pop ix + ret + ;; --- end of user code --- + END diff --git a/tests/functional/arch/zx48k/dimconst2f.bas b/tests/functional/arch/zx48k/dimconst2f.bas new file mode 100644 index 000000000..40bf15053 --- /dev/null +++ b/tests/functional/arch/zx48k/dimconst2f.bas @@ -0,0 +1,6 @@ + +Function q + DIM q as Uinteger = @Map +End Function + +Map: diff --git a/tests/functional/arch/zx48k/dimconst2g.asm b/tests/functional/arch/zx48k/dimconst2g.asm new file mode 100644 index 000000000..568a7700c --- /dev/null +++ b/tests/functional/arch/zx48k/dimconst2g.asm @@ -0,0 +1,59 @@ + org 32768 +.core.__START_PROGRAM: + di + push ix + push iy + exx + push hl + exx + ld (.core.__CALL_BACK__), sp + ei + jp .core.__MAIN_PROGRAM__ +.core.__CALL_BACK__: + DEFW 0 +.core.ZXBASIC_USER_DATA: + ; Defines USER DATA Length in bytes +.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA + .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN + .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA +_Map: + DEFB 00 +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + ld a, 2 + ld (_Map), a + ld hl, 0 + ld b, h + ld c, l +.core.__END_PROGRAM: + di + ld hl, (.core.__CALL_BACK__) + ld sp, hl + exx + pop hl + exx + pop iy + pop ix + ei + ret +_q: + push ix + ld ix, 0 + add ix, sp + ld hl, 0 + push hl + push hl + inc sp + push ix + pop hl + ld de, -1 + add hl, de + ld (ix-3), l + ld (ix-2), h + ld (ix-1), 1 +_q__leave: + ld sp, ix + pop ix + ret + ;; --- end of user code --- + END diff --git a/tests/functional/arch/zx48k/dimconst2g.bas b/tests/functional/arch/zx48k/dimconst2g.bas new file mode 100644 index 000000000..0e92770c4 --- /dev/null +++ b/tests/functional/arch/zx48k/dimconst2g.bas @@ -0,0 +1,7 @@ + +Function q + DIM q as Uinteger = @Map + Map = 1 +End Function + +Map = 2 diff --git a/tests/functional/arch/zx48k/dimconst2h.asm b/tests/functional/arch/zx48k/dimconst2h.asm new file mode 100644 index 000000000..e059d96a8 --- /dev/null +++ b/tests/functional/arch/zx48k/dimconst2h.asm @@ -0,0 +1,51 @@ + org 32768 +.core.__START_PROGRAM: + di + push ix + push iy + exx + push hl + exx + ld (.core.__CALL_BACK__), sp + ei + jp .core.__MAIN_PROGRAM__ +.core.__CALL_BACK__: + DEFW 0 +.core.ZXBASIC_USER_DATA: + ; Defines USER DATA Length in bytes +.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA + .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN + .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA +_Map: + DEFB 01h +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + ld hl, 0 + ld b, h + ld c, l +.core.__END_PROGRAM: + di + ld hl, (.core.__CALL_BACK__) + ld sp, hl + exx + pop hl + exx + pop iy + pop ix + ei + ret +_q: + push ix + ld ix, 0 + add ix, sp + ld hl, 0 + push hl + ld hl, _Map + ld (ix-2), l + ld (ix-1), h +_q__leave: + ld sp, ix + pop ix + ret + ;; --- end of user code --- + END diff --git a/tests/functional/arch/zx48k/dimconst2h.bas b/tests/functional/arch/zx48k/dimconst2h.bas new file mode 100644 index 000000000..1a4d33db9 --- /dev/null +++ b/tests/functional/arch/zx48k/dimconst2h.bas @@ -0,0 +1,6 @@ + +Function q + DIM q as Uinteger = @Map +End Function + +Dim Map = 1 diff --git a/tests/functional/arch/zx48k/dimconst2i.asm b/tests/functional/arch/zx48k/dimconst2i.asm new file mode 100644 index 000000000..d81572224 --- /dev/null +++ b/tests/functional/arch/zx48k/dimconst2i.asm @@ -0,0 +1,53 @@ + org 32768 +.core.__START_PROGRAM: + di + push ix + push iy + exx + push hl + exx + ld (.core.__CALL_BACK__), sp + ei + jp .core.__MAIN_PROGRAM__ +.core.__CALL_BACK__: + DEFW 0 +.core.ZXBASIC_USER_DATA: + ; Defines USER DATA Length in bytes +.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA + .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN + .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA +_Map: + DEFB 00 +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + ld a, 1 + ld (_Map), a + ld hl, 0 + ld b, h + ld c, l +.core.__END_PROGRAM: + di + ld hl, (.core.__CALL_BACK__) + ld sp, hl + exx + pop hl + exx + pop iy + pop ix + ei + ret +_q: + push ix + ld ix, 0 + add ix, sp + ld hl, 0 + push hl + ld hl, _Map + ld (ix-2), l + ld (ix-1), h +_q__leave: + ld sp, ix + pop ix + ret + ;; --- end of user code --- + END diff --git a/tests/functional/arch/zx48k/dimconst2i.bas b/tests/functional/arch/zx48k/dimconst2i.bas new file mode 100644 index 000000000..2829da970 --- /dev/null +++ b/tests/functional/arch/zx48k/dimconst2i.bas @@ -0,0 +1,6 @@ + +Function q + DIM q as Uinteger = @Map +End Function + +Let Map = 1