Coder Social home page Coder Social logo

Comments (5)

agg23 avatar agg23 commented on May 25, 2024

This fix appears to be optimized out by O3 or greater in some scenarios (though it does not repro for this example in particular). Resulted in some strange bugs though.

from millfork.

KarolS avatar KarolS commented on May 25, 2024

I finally found some time to sit down and think about it, and I think that it was a mistake to allow this to compile. Macro parameters are l-values, and those cannot be converted automatically in a sensible way.

However, to support more freeform macros, I decided to allow declaring macro parameters as void, which can be thought an arbitrary generic type, to allow reusing macros regardless of the actual argument types.

I'll tweak it a bit more in the upcoming week and I'm open to suggestions.

from millfork.

agg23 avatar agg23 commented on May 25, 2024

That seems reasonable. In scenarios such as this, what is the expected calling pattern?

from millfork.

KarolS avatar KarolS commented on May 25, 2024

Sorry for a long wait.
I was thinking for a bit about the macros in general and I decided to not change most of how they work now.
As for your example, then I can suggest you match the type of the parameter to the type of the variable you pass in, so either:

sbyte input @0

or

macro void test_signed_macro(byte value) {
    if sbyte(value) > 3 {
        output = 1
    }
}

This should always work.

I'm currently thinking about implementing macros that can take any right-hand-side parameter, with usual type conversions, but that's still not finalized.

from millfork.

KarolS avatar KarolS commented on May 25, 2024

I've added some new capabilities to macros. Similarly how you can declare parameters to asm macros as either ref, const or register, you can now declare parameters to non-asm macros as ref (default), const and call. ref is as before, a left-hand-side expression with strict type checking. const is simply required to be a constant, with standard type conversions. call is inserted as an expression evaluated at every occurrence within the macro body, cast to the declared type.

So now this should work: if you have

macro void test_signed_macro(sbyte call value) {
    if value > 3 {
        output = 1
    }
}

then test_signed_macro(input) expands to if sbyte(input) > 3 { output = 1 } and you get exactly what you wanted.

Note that the argument is evaluated at every occurrence, which might be dangerous, but also allows this silly thing:

macro twice(void call f) {
    f
    f
}
void inc() {
    output += 1
}
twice(inc())

Not all expressions can be used as such parameters (in particular, no assignments, so twice(output+=1) won't compile), but I think this is a neat emergent functionality.

Now you probably think about how to use this in conjunction with local variables declared within a macro, to avoid multiple evaluations while keeping the type casting, but macros aren't too hygienic right now and implementing that is an idea for a much further future.

Thanks for making me look deeper into this, I find what I arrived to a much better than what was before.

from millfork.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.