wiz-lang / wiz

A high-level assembly language for writing homebrew software and games on retro console platforms.
http://wiz-lang.org/
Other
405 stars 40 forks source link

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

Closed Bananattack closed 3 years ago

Bananattack commented 3 years ago

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.

lhsazevedo commented 3 years ago

Great! 🔥