vhelin / wla-dx

WLA DX - Yet Another GB-Z80/Z80/Z80N/6502/65C02/65CE02/65816/68000/6800/6801/6809/8008/8080/HUC6280/SPC-700/SuperFX Multi Platform Cross Assembler Package
Other
544 stars 98 forks source link

Best way to implement assemble-time or link-time assertions? #578

Closed rondnelson99 closed 1 year ago

rondnelson99 commented 1 year ago

In regular code and especially macros, often it's good to explicitly test assumptions. I'm used to RGBDS which has the assert directive which takes a condition and evaluates it at assemble time if possible, or link time it not. It terminates compilation if the condition is false, while giving you the line number to look at. I'm guessing WLA would make this possible via .IF and .FAIL (at least at assemble time), but is it possible to combine these into an assert macro? My attempt at this macro isn't working properly, and I'd like to better understand why. Here's what I have:

.macro assert ARGS condition
  .if !condition
    .fail
  .endif
.endm

I call it with a line like assert (<len == 0) where len is a variable.

The macro seems to always cause a fail, even if I use assert (0 == 0). I'm guessing this is because the result of the conditional doesn't get passed to the macro properly, but I'm really not sure. Is there a way to implement this using macros, or is this impossible? I know it's not at all essential for me to get this to work, but I'm hoping to learn a bit more about macros since my planned project will need a lot of them.

Thanks, Ron

vhelin commented 1 year ago

If I remember this correctly, .IF etc. force the parser into a special mode where A == B is calculated correctly. In this case when the parser parses the argument(s) for the .MACRO call the parser is in wrong mode and doesn't relay the argument correctly.

I need to double check this so that I'm not talking BS here. :)

Anyway, as a quick fix, I could add .ASSERT that does that parsing correctly.

vhelin commented 1 year ago

Yeah,

kuva

I think I'll add .ASSERT now, and add "make e.g., A == B to work everywhere" to my TODO list...

vhelin commented 1 year ago

If you now use .ASSERT, does it work?

rondnelson99 commented 1 year ago

Thank you!! Your dedication to this project is commendable. I was able to get my macro that contained an assertion to work, although my original .assert (<len == 0) didn't quite work, since it seems that the "get the low byte" operator doesn't work in an assertion. The docs say (or at least imply) that it doesn't work in .IF either, so I guess that makes sense. If I use .assert (len & $ff) == 0, everything works out nicely.

Again, thanks for adding this! RGBDS assert has caught many bugs before, and hopefully it can do the same here.

vhelin commented 1 year ago

I'll see if I can make the parser more intelligent and get the "get low byte" etc. operators to work with .IFs...

Mean while you could also try to use lobyte() and hibyte(), they should work with .IFs...

vhelin commented 1 year ago

I opened a new issue about this: https://github.com/vhelin/wla-dx/issues/579 - we'll continue this there...

vhelin commented 1 year ago

I don't think you need it any more, but if you now take the latest sources, the .MACRO in your initial post regarding this issue should work now... :)

vhelin commented 1 year ago

Also this should work now

.assert (<len == 0)