Dotneteer / spectnetide

ZX Spectrum IDE with Visual Studio 2017 and 2019 integration
MIT License
206 stars 27 forks source link

[FEATURE REQUEST] specific register Parse-time macro parameter tests #186

Closed nww02 closed 4 years ago

nww02 commented 4 years ago

This is just a little sugar to help with some optimisation.. Not a priority at all.... And I bet this'll be one you tell me is already implemented, but I've not read the docs :D haha.

I'm writing a piece of code which I'd like to abstract out to a macro. I'd like to know which 16 (or 8) bit register is being passed in, as this would alter the start of the section...

myfunc:
.macro(param1)
>>>> preloading of BC would happen here <<<<<
ld      a,b
and     0f8h
add     a,40h
ld      h,a
ld      a,b
and     7
rrca
rrca
rrca
add     a,c
ld      l,a
.endm

If I know I'll only ever call it with a static value or a 16 bit reg, I can do this:-

.if isreg16({{param1}})
          push  {{param1}}
          pop   bc
.else
          ld      bc,{{param1}}
.endif

but if I am using this inline, and passing "bc" to the macro:

myfunc(bc)

Then I don't actually want anything to happen, cos the value's already in bc, so pushing and popping the same register would just be a waste of 20-or-so T-states.

What would be nice is if I could do:-

.if isreg16({{param1}})
   .if isbc(param1)
     ; do nothing
   .else
      push  {{param1}}
      pop   bc
   .endif
.else
  .if isexpr(param1)
          ld   bc,{{param1}}
   .else
       .error "You can only pass in a 16-bit register or a memory address to myfunc()"
   .endif
.endif
.
.
.
.

If course, another way would be to overload isreg16() and the other tests to also take a second parameter, such as:

.if isreg16(param1,bc)

nww02 commented 4 years ago

I thought I'd found a way to solve it... but it turns out it doesn't work.. It throws an "unexpected token: 'BC'" error.

.if isreg16({{param1}})
    .if {{param1}} == "bc"
                ;
    .else
        push    {{param1}}
        pop     bc
    .endif
.else
    ld      bc,{{param1}}
.endif            
Dotneteer commented 4 years ago

Soon, I will add parse-time function for all these registers: A, AF, B, C, BC, D, E, DE, H, L, HL, I, R, XH, XL, IX, YH, YL, IY, SP.

Dotneteer commented 4 years ago

Here is the private build to try these new parse-time functions.

Spect.Net.VsPackage.zip

You can find the documentation here: https://dotneteer.github.io/spectnetide/documents/macros#macro-related-parse-time-functions (see the last row)

nww02 commented 4 years ago

Awesome! Thank you! I'm trying to make some generic code I can call from wherever, and I have to spend less time planning on which register to have my parameters in. A macro that can pull in the values from different registers and work on them intelligently would make later coding a lot easier. I'll give this a try as soon as I can!! :)

Dotneteer commented 4 years ago

Released in v2 Preview 6.

nww02 commented 4 years ago

Awesome, thank you! I'll simplify my macro code. With this, I can now easily use library code from books and sites without needing to rewrite it for each application. Libraries can be used together, with just enough glue code to move values around registers if needed. Thank you! :)