customasm
customasm copied to clipboard
Output of subruledefs ignored in asm{...}
#subruledef subtest
{
{x: s32} =>
{
255`32
}
}
#ruledef test
{
test {a: s32} => a
testasm {a: subtest} => asm{test {a}}
test2 {a: subtest} => a
}
testasm 0
test2 0
outp | addr | data (base 16)
0:0 | 0 | 00 00 00 00 ; testasm 0
4:0 | 4 | 00 00 00 ff ; test2 0
Possibly related to #170
A slightly better example:
#subruledef subtest
{
{x: s32} =>
{
255`32
}
}
#ruledef test
{
test {a: s32} => a
testasm {a: subtest} => asm{test {a}}
testasm2 {a: subtest} =>
{
temp = a
asm{test {temp}}
}
}
testasm 0
testasm2 0
outp | addr | data (base 16)
0:0 | 0 | 00 00 00 00 ; testasm 0
4:0 | 4 | 00 00 00 ff ; testasm2 0
Simply assigning to a temporary changes the output versus just directly passing; so it seems when passing one subruledef to another, the input is run through the validation, then the input is copied to the input of the new subruledef, but the output of the original subruledef is discarded, when the desire is to chain the output into the input.
Looking at the above, I would expect most people would agree that the output of testasm
and testasm2
should be identical.
Yeah... This was by design, but it doesn't seem to have been the best idea.
The idea is that whenever the referenced variable comes directly from the instruction parameters (i.e. not a local variable declared in the body), the assembler will prioritize a "token-for-token substitution", ignoring the calculated value completely. This is needed when the nested instructions are also expecting some kind of special token (such as if you have a #subruledef
with register names like ax
, rax
etc.)
I'm thinking now that the best solution would be to use different syntax when you want token-for-token substitution. This would be a breaking change again, but I think it'd be clearer. Something like {a}
for using the calculated value (as is more natural, and would allow for complex expressions), and having to do {<a>}
to leverage token-for-token substitution.