fusionlanguage / fut

Fusion programming language. Transpiling to C, C++, C#, D, Java, JavaScript, Python, Swift, TypeScript and OpenCL C.
https://fusion-lang.org
GNU General Public License v3.0
1.76k stars 55 forks source link

Unable to use "native" inside of class but outside of function #168

Closed al1-ce closed 4 months ago

al1-ce commented 4 months ago

As title says, this is invalid code, which I would consider a bug

class Test {
    native {}
}

Use case for this: injecting language-specific features

Example:

class Test {
    #if D
    native { @property }
    #endif
    int getval() 
    #if D
    native { @nogc @safe nothrow }
    #endif
        { return 2; } 
}

Which would generate following D code

class Test {
     @property
    int getval()
     @nogc @safe nothrow
        { return 2; }
}

But is unable to do so as of right now

pfusik commented 4 months ago

Thank you for proposing that.

The C++ backend reorders the class members, sorting by visibility (private/protected/public) because that's what idiomatic C++ code looks like. This poses a problem where to place the native blocks that are between members of different visibility?

In C, functions are emitted outside the struct. I could assume that native members are emitted inside the struct.

All other backends emit the class members in order.

al1-ce commented 4 months ago

I'd think for C++ it'd be the same as I described in https://github.com/fusionlanguage/fut/issues/169#issuecomment-2223687563, with exception on top statement which wouldn't make sense inside classes, so, I'd say that native blocks would follow whatever defined right after them. But there may be edge cases, where programmer would want things inserted at top (not sure how to handle that without introducing new preprocessor syntax or modifying native statements)...

For C, since there's no fancy attributes or something it'd make sense to keep it inside of struct, with, ..edge case.. of macros maybe (same for C++) (but it's so slim that it's barely an edge case)?

pfusik commented 4 months ago

For now, I implemented it except for C++. In addition to adding decorations to fut-generated members, you can add native fields and methods. Nice feature!

C++ does support forward references to class members. Putting it before the next fut-generated member makes sense if you are adding a decoration. If the native comes last in the class, it should probably be emitted last (and it won't mess with the visibility of generated members).

For C, since there's no fancy attributes or something

There's volatile, alignas etc.

pfusik commented 4 months ago

Implemented for C++ too. native blocks come with the following class member.

I was considering to unconditionally put native blocks at the end of the C++ class, but you can do that by putting them at the end of the Fusion class.

al1-ce commented 4 months ago

There's volatile, alignas etc.

Oh, right, forgot about that..

Implemented for C++ too. native blocks come with the following class member.

That's great!