wiz-lang / wiz

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

Allow and correctly sequence inner assignments/increments #48

Open Bananattack opened 5 years ago

Bananattack commented 5 years ago

Right now, it is only possible to use pre/post-increment in either a top-level position, or as part of an addressing mode.

It would neat if pre-increments and post-increments were allowed in any subexpression. This would mean the number of intermediate statements needed can be greatly simplified, and it will still sequence the correct thing.

// 6502
array[x++] = a;
// short for: array[x] = a; x++;

// Z80 / GB:
*(hl++ as *u8) = a = *(de++ as *u8);
// short for:
//
// (On Z80)
// a = *(de as *u8);
// de++;
// *(hl as *u8) = a;
// hl++;
//
// (On GB)
// a = *(de as *u8);
// de++;
// *(hl++ as *u8) = a;

The Z80 + GB example shows how it can be useful for writing code that takes advantage of specialized instructions when they exist (hl post-increment indirect on GB). However, it still generates valid compiling code if the specialized instruction does not exist, but another valid sequence of instructions that does the same thing is found.

The sequencing will try to be as close as possible to the site of use, rather than delaying side-effects until the full outermost expression is finished. So things can be written with left-to-right evaluation in mind, no weird "sequence points" to figure out.

This would also be possible:

a = *((hl = 0xFF80) as *u8); // ld hl, imm; ld a, [hl]
*((hl = 0xFF80) as *u8) = 0; // ld hl, imm; ld [hl], imm
a = *((hl = 0xFF80)++ as *u8); // ld hl, imm; ld a, [hl+]

Cutting down on the number of intermediate statements needed to use hl-assignment operators. Some of these are subjectively less readable than separate statements, but I think it should be up to the user's discretion to write separate assignment statements or do a one-liner, and the compiler's job to do what it can to allow it.

Bananattack commented 4 years ago

As far as I can tell, the remaining issue is that any nested side-effects to the destination operand are currently not validated to only happen once.

eg.

// This:
dest[x++] = a + b + c;
// Should be rewritten into either:
// dest[x] = a;
// dest[x] += b;
// dest[x++] += c;
//
// or:
//
// dest[x] = a;
// dest[x] += b;
// dest[x] += c;
// x++;
//
// but instead becomes:
// dest[x++] = a;
// dest[x++] += b;
// dest[x++] += c;