This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

c style macros used with || in a ca65 macro...

c style macros used with || in a ca65 macro...
by on (#208998)
I have a macro which detects a prefix at the beginning of a symbol. These prefixes indicate a 16 bit value, arranged as structures of arrays, to direct how the macro generates code. I simply want to detect one prefix OR the other prefix. When I try to put the two below invocations of a c-style macro in an || expression, ca65 errors out. Even if I use parentheses around each macro invocation and around the entire expression itself. I was able to work around this using .set as in the below code snippet, but is ca65's expression parsing really this broken?
Code:
        entity_prefix .set starts_with .string(arg), "entity_"
        lut_prefix .set starts_with .string(arg), "lut_"
        .if entity_prefix || lut_prefix   ;I can't just put the two macros on either side of the || or I get errors, even with parentheses applied liberally. I had to use this workaround.
Re: c style macros used with || in a ca65 macro...
by on (#209000)
Can we have the definition of starts_with?

I believe that the reason you can't use the macros directly in the IF statement is because ca65 doesn't know when the last parameter of a c-style macro ends. In that case, delimiting the last parameter with {} should work. Something like this:

Code:
.if macro0 parameter0, {parameter1} || macro1 parameter2, {parameter3}
  ;(...)
.endif
Re: c style macros used with || in a ca65 macro...
by on (#209001)
tokumaru wrote:
Can we have the definition of starts_with?

I believe that the reason you can't use the macros directly in the IF statement is because ca65 doesn't know when the last parameter of a c-style macro ends. In that case, delimiting the last parameter with {} should work. Something like this:

Code:
.if macro0 parameter0, {parameter1} || macro1 parameter2, {parameter3}
  ;(...)
.endif

Cool, worked perfectly! Thanks sir! ca65's macros and directives are so gnarly...but I love them :D

For curiosity's sake, starts_with and ends_with are here:

Code:
.define starts_with(string, prefix) .xmatch(.sprintf(.sprintf("%%.%ds", .strlen(prefix)), string), prefix)
.define ends_with(string, suffix) .xmatch(.sprintf(.sprintf("%%.%ds%%s", (.strlen(suffix) < .strlen(string)) * (.strlen(string) - .strlen(suffix))), string, suffix), string)

These resulted from a conversation with thefox.
Re: c style macros used with || in a ca65 macro...
by on (#209003)
GradualGames wrote:
Cool, worked perfectly! Thanks sir! ca65's macros and directives are so gnarly...but I love them :D

Cool, but I still think it's weird that caching the results beforehand doesn't work...

Quote:
These resulted from a conversation with thefox.

Thanks. I remember that conversation, but I didn't know if you were using that exact same code or if you had made any changes since then.

Anyway, I really can't figure out why caching the 2 results using .set screws up the .if... .set should put the numeric results into those symbols, regardless of how the macros were written, right?
Re: c style macros used with || in a ca65 macro...
by on (#209004)
Now this is weird... I just tried this exact code and it works just fine:

Code:
.define starts_with(string, prefix) .xmatch(.sprintf(.sprintf("%%.%ds", .strlen(prefix)), string), prefix)

.macro Test arg
   entity_prefix .set starts_with .string(arg), "entity_"
   lut_prefix .set starts_with .string(arg), "lut_"
   .if entity_prefix || lut_prefix
      .out "Prefix found!"
   .else
      .out "Prefix not found!"
   .endif
.endmacro

Test lut_Whatever
Test entity_Something
Test prefix_Name


Output:

Code:
Prefix found!
Prefix found!
Prefix not found!
Re: c style macros used with || in a ca65 macro...
by on (#209033)
tokumaru wrote:
Now this is weird... I just tried this exact code and it works just fine:

Code:
.define starts_with(string, prefix) .xmatch(.sprintf(.sprintf("%%.%ds", .strlen(prefix)), string), prefix)

.macro Test arg
   entity_prefix .set starts_with .string(arg), "entity_"
   lut_prefix .set starts_with .string(arg), "lut_"
   .if entity_prefix || lut_prefix
      .out "Prefix found!"
   .else
      .out "Prefix not found!"
   .endif
.endmacro

Test lut_Whatever
Test entity_Something
Test prefix_Name


Output:

Code:
Prefix found!
Prefix found!
Prefix not found!


Sorry my OP was not terribly clear---doing this works for me, my question was why can't I just put the macro invocation directly surrounding the ||. Using the { } in each invocation as you suggested allows me to do so, so I've removed the two prefix variables. I now have:

Code:

        .if starts_with .string(arg), {"entity_"} || starts_with .string(arg), {"lut_"}

Re: c style macros used with || in a ca65 macro...
by on (#209038)
Ah, my bad. I thought you said the workaround didn't work, but now I see this wasn't the case.