It is currently Mon Sep 24, 2018 4:07 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Wed Nov 29, 2017 8:33 pm 
Offline
User avatar

Joined: Sun Nov 09, 2008 9:18 pm
Posts: 1107
Location: Pennsylvania, USA
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.


Top
 Profile  
 
PostPosted: Wed Nov 29, 2017 8:52 pm 
Offline
User avatar

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


Top
 Profile  
 
PostPosted: Wed Nov 29, 2017 9:01 pm 
Offline
User avatar

Joined: Sun Nov 09, 2008 9:18 pm
Posts: 1107
Location: Pennsylvania, USA
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.


Top
 Profile  
 
PostPosted: Wed Nov 29, 2017 9:11 pm 
Offline
User avatar

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


Top
 Profile  
 
PostPosted: Wed Nov 29, 2017 9:26 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10815
Location: Rio de Janeiro - Brazil
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!


Top
 Profile  
 
PostPosted: Thu Nov 30, 2017 7:05 am 
Offline
User avatar

Joined: Sun Nov 09, 2008 9:18 pm
Posts: 1107
Location: Pennsylvania, USA
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_"}



Top
 Profile  
 
PostPosted: Thu Nov 30, 2017 7:40 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10815
Location: Rio de Janeiro - Brazil
Ah, my bad. I thought you said the workaround didn't work, but now I see this wasn't the case.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group