stardot / beebasm

A portable 6502 assembler with BBC Micro style syntax
http://www.retrosoftware.co.uk/wiki/index.php/BeebAsm
GNU General Public License v3.0
83 stars 26 forks source link

Macro names can't begin with instruction mnemonics #80

Open Homo-carbonis opened 1 year ago

Homo-carbonis commented 1 year ago

Macro names which begin with mnemonics cause problems when you try to use them. If the mnenmonic is followed by a letter you just get a "Symbol not defined" error but if it is followed by a number beebasm tries to assemble the instruction rather than the macro, so

MACRO DEC1 ... ENDMACRO
...
DEC1

Results in DEC 1, rather than the macro DEC1.

mungre commented 1 year ago

You can work around this by passing the -w flag to beebasm. This insists on a space between mnemonics and parameters so you can use macro names starting with mnemonics.

Though it would be better if the macro definition failed with a meaningful error when you used a mnemonic and hadn't passed the -w flag.

Homo-carbonis commented 1 year ago

The -w option is useful to know about but I think an error would be a good idea. I couldn't work out why DEC16 macro resulted in a bad expression error until I resorted to experimenting with different names. Edit: I just noticed -w doesn't work with mnemonics followed by numbers. DEC16 is still parsed as DEC 16 by beebasm -w

ZornsLemma commented 1 year ago

I think the "problem" here is that beebasm is trying to be as compatible with the BBC BASIC assembler as possible by default, so you can take your old sources and assemble them with beebasm using minimal tweaks. The BBC BASIC assembler accepts "DEC16" to mean "DECrement zp address 16=&10" and so beebasm does as well.

We could make -w insist on a space after the instruction all the time. I implemented -w a while back, I can't remember if this different treatment of numeric and label operands was a deliberate choice or not - I think my motivating example was a macro starting "stack...", which was interpreted as "STA ck...", so I may have been trying to make the change as minimal as possible.

I don't think changing the default (i.e. without -w) behaviour is going to be acceptable, so even if we modify the -w behaviour, by default "DEC16" is always going to be interpreted as "DEC 16". We could refuse to allow a macro to be defined with a valid instruction as its name - then "macro dec16" would generate an error (unless a tweaked -w option was in effect) and ambiguity would be avoided. I don't know how easy implementing this would be though. (Edit: I see mungre suggested this already...)

mungre commented 1 year ago

When using -w, rather than insisting on a space I think it would be sufficient just to add digits to the things it doesn't allow after a mnemonic (so alphas, underscores and digits). Things like LDA#2 and LDA&70 aren't valid macro names anyway.

This would only break people who are using decimal addresses and omitting the spaces and using -w, which requires spaces everywhere else. Most addresses are symbolic or hex, so I'd be quite surprised if any code looked like this.

mungre commented 1 year ago

I'd forgotten, macro names can end in $ or %. So you'd also have to add these to the list of things that can't go after a mnemonic when using -w, which is starting to get a bit silly. Just insisting on a space is much more straightforward.

ZornsLemma commented 1 year ago

That seems sensible. I'm a bit tied up at the moment so if you (or anyone else) feels like having a go at implementing this please do, otherwise I will probably have some time later in the week.

I think it might be a good idea if we raise a separate issue for "disallow macro names which are valid instructions" to trap things like using "macro dec16" when not specifying -w. I'm happy to do that if we're all in agreement.

mungre commented 1 year ago

I can't think of an example of a macro name that starts with a mnemonic and wouldn't cause problems, so I think that should just be "disallow macro names that start with a mnemonic" when not using -w.

ZornsLemma commented 1 year ago

I think you're right - I did wonder if e.g. "macro inx2" would be OK given this is an implied instruction, but that doesn't work (not unreasonably) anyway.

ZornsLemma commented 1 year ago

I've raised https://github.com/stardot/beebasm/issues/85 for this.