informedcitizenry / 6502.Net

A .Net-based Cross-Assembler for Several 8-Bit Microprocessors
MIT License
58 stars 17 forks source link

Has concatenating macro arguments changed? #9

Closed svallee-dev closed 2 years ago

svallee-dev commented 2 years ago

Hi, I'm back! I was able to update my project using your latest source code, and after a bit of finicking I got it to work :)

As a test I compiled my ongoing C64 project, and I'm now getting a new compile error, from this macro declaration:

GOTOMENU    .macro menuBlockName
            .SET16 zp_menu_request, \menuBlockName.Menu
            .endmacro

The way it work is that I pass the name of a block, and I'm setting a variable with the address of the label "Menu" inside the block.

It used to work, but now it's complaining with "Reference parameter not valid.", pointing at the \menuBlockName.Menu part. My assumption is that it's probably now including the ".Menu" with the macro name and therefore does not recognize it?

I've been going through the documentation up and down and can't find a way to concatenate macro arguments. Am I misunderstanding something, or is there an easy work around?

Thanks!

informedcitizenry commented 2 years ago

Sorry, been busy (with among other things, a complete rewrite of this application). I haven't touched that particular part of code that processes the macro references in a while, but I did dig back to a version from over a year ago, and it appears I did a lot of refactoring/simplification, but in doing so, broke something that was working for you.

To be honest, I had never considered your use case before, and it is interesting, it does remind me a bit of the C/C++ preprocessors ability to concat tokens onto macro arguments.

I would say, for now, you could hack your own version of the method that captures the arguments. It's in the file src/Preprocessing/Macro.cs, at about line 107. One quick solution I did that I think will work is:

var opName = op.Name.ToString();
if (opName[0] == '\\')
{
    if (i == line.Operands.Count - 1 || line.Operands[i + 1].Type != TokenType.Operand)
        throw new ExpressionException(op, "Reference parameter not specified.");
    op = line.Operands[++i];
    if (!int.TryParse(op.Name.ToString(), out var paramRef))
    {
        opName = op.Name.ToString()
    .Split('.', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)[0];
        paramRef = Params.FindIndex(p => p.Name.Equals(opName, comp));
        //paramRef = Params.FindIndex(p => p.Name.Equals(op.Name, comp));
        if (paramRef < 0)
            throw new ExpressionException(op, "Reference parameter not valid.");
    }
    else
    {
        paramRef--;
    }
    macroSource.ParamPlaces.Add((paramRef, "\\" + opName));
}
informedcitizenry commented 2 years ago

I believe this should now work again, can you confirm?