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

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Post Reply
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

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

Post by GradualGames »

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: Select all

        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.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

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

Post by tokumaru »

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: Select all

.if macro0 parameter0, {parameter1} || macro1 parameter2, {parameter3}
  ;(...)
.endif
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

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

Post by GradualGames »

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: Select all

.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: Select all

.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.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

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

Post by tokumaru »

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...
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?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

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

Post by tokumaru »

Now this is weird... I just tried this exact code and it works just fine:

Code: Select all

.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: Select all

Prefix found!
Prefix found!
Prefix not found!
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

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

Post by GradualGames »

tokumaru wrote:Now this is weird... I just tried this exact code and it works just fine:

Code: Select all

.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: Select all

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: Select all


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

User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

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

Post by tokumaru »

Ah, my bad. I thought you said the workaround didn't work, but now I see this wasn't the case.
Post Reply