Back in this thread I mentioned the idea of extending Inform 6’s assembly language to allow arbitrary bytes.
I now have a test implementation of this (see branch). I figured I’d run it by the forum to see what people think.
Context: Nobody has ever asked for this feature. Practically nobody will ever use it. But if you happen to need it, it’s hard to replace, and the comments in that thread are in favor.
This is the current proposal:
@ -> $8B $04 $D2;
Like other assembly statements, this can only be used inside a function. It just spits out those three bytes at that point in the function. Thus, it generates the same Z-code instruction as:
return 1234; ! ...or, in assembly form... @ret 1234;
@ -> syntax can be used in both Z-code and Glulx, but of course the Glulx opcode byte for
@return is different.)
I need hardly say that if you use this feature, it’s absolutely up to you whether the result is valid Z-code/Glulx. The compiler doesn’t check your work at all. It just copies in the bytes.
The values don’t have to be hex constants, but they do have to be constants. Compile-time constant arithmetic is okay. Backpatched values like functions, objects, strings, and forward-declared constants are not. It’s pretty much the same rules as for defining Arrays.
You can also generate bytes in word-size chunks. That’s two-byte chunks in Z-code, four-byte in Glulx.
@ --> $1234 $5;
This is the same as
@ -> $12 $34 $00 $05; ! in Z-code @ -> $00 $00 $12 $34 $00 $00 $00 $05; ! in Glulx
@ --> form (unlike the
@ -> form) accepts Inform symbols, and does appropriate backpatching to make sure they come out right. That is, if you wanted to return the address of function
FuncName, you could write:
@ -> $8B; ! @ret opcode, two-byte form @ --> FuncName; ! the argument of the opcode
But this isn’t allowed, because a function address (even packed) won’t fit in a byte:
@ -> $8B FuncName; ! error: Entries in code byte arrays must be known constants
All sound reasonable?