Skip to content

It is not possible to get nested struct members or use byte/word-access on a struct pointer. #116

@Bananattack

Description

@Bananattack

Hey!

I'm trying to zero test a word pointed by ix with index.
Here is the source assembly:
ld a, (ix + Entity.isOffScreenFlags.low)
or (ix + Entity.isOffScreenFlags.high)

And the compiling Wiz code:
a = *((ix + 9) as *u8);
a |= *((ix + 10) as *u8);

It works :slight_smile:
When using an struct instance though, it fails:

a = >:monster.isOffScreenFlags;
a |= <:monster.isOffScreenFlags;

(some possible options ommited)
error: could not generate code for assignment =
note: got: a = *(((ix + 9) + 1) as *u8)
note: possible options:
a = *((ix + {-128..127}) as *u8)
a = *((iy + {-128..127}) as *u8)
note: assignment must be rewritten some other way
error: could not generate code for statement

error: could not generate code for bitwise or |
note: got: a |= *(((ix + 9) + 0) as *u8)
note: possible options:
a |= *((ix + {-128..127}) as *u8)
a |= *((iy + {-128..127}) as *u8)
note: expression must be rewritten some other way
Let me know if I am doing something wrong or it is not implemented yet.

The same issue happens for nested struct members.

struct Word { low : u8, high : u8 }
// ...
a = monster.isOffScreenFlags.low;
a |= monster.isOffScreenFlags.high;

This happens in both cases, because struct member access and those byte-access operators use the same logic internally to get an offset.

Wiz isn't folding those constant adds together. As shown in the error message, you get *((ix + offset1) + offset2), but we should simplify this by using associativity of addition to constant fold and make this *(ix + dd) form. We don't typically rearrange evaluation order like this when runtime expressions are involved on one-or-both sides of a binary operator (to preserve intent closer to the original source in the generated machine code, and so stuff can rely on runtime effects like generating carries happening), but we know that addition is commutative and associative, and we're folding constant leaf nodes together, and ONLY doing it within stuff that uses structs or byte/word-access operators, so I think it's okay.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions