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.75k stars 55 forks source link

[Bug] "native" blocks outside of class inject code in wrong place #169

Closed al1-ce closed 2 months ago

al1-ce commented 2 months ago

This code:

// main.fu
native { A }
class Test {}
native { B }

Would produce:

// main.d
 A B
class Test {}

When I'd expect it to produce:

 A
class Test {}
 B

Tested in all languages and in all of them it's incorrect. C and C++ suffer especially if there are includes, with above code it'd be something like this:

 A B #include <stdio.h>
... 
pfusik commented 2 months ago

This is by design. Top-level native blocks are meant for adding #include-like directives and helper functions/classes.

Could you give an example where the order of native blocks with respect to classes/enums matters?

Some targets reorder the enums and classes. For example, C and C++ do not support implicit forward references, so for code such as:

public class Foo
{
    internal Bar Quux;
}

public enum Bar
{
...
}

the enum is emitted first in C/C++. Where would you expect the native block if it's between the class and the enum?

In JavaScript, TypeScript and Python, the base classes must be defined before the derived class. So fut does a topological sort. This also creates a problem where to land native blocks between the classes?

al1-ce commented 2 months ago

Could you give an example where the order of native blocks with respect to classes/enums matters?

To be honest with you I was trying to get rid of outputed class declaration by surrounding it and it's closing bracket with native blocks as an experiment of what I can do.

the enum is emitted first in C/C++. Where would you expect the native block if it's between the class and the enum? In JavaScript, TypeScript and Python, the base classes must be defined before the derived class. So fut does a topological sort. This also creates a problem where to land native blocks between the classes?

I didn't think about this...

But if to consider declaration flow I'd say that best place to put it is before enum, as it was defined before it. So, what I'd think it'd do with reordering (in languages where order matters) is:

/// sample.fu
native { a } // topmost stays in place (may contain includes)
class A: B {}

native { c } // follows class C
class C {}

native { b } // follows class B
class B: C {}
/// sample.cpp
 a // will be first since it was declared at top
 c // followed C
class C {};
 b // followed B
class B: C {};
class A: B {};

So, native blocks would "stick" to any succeeding declaration with exception of topmost declaration where native block would stay as is.


Also another thing I'd kind of expect is that if native blocks are on different lines they'd output onto different lines, but I'm not sure since you might've made it intentional, but it's kind of clunky of making new lines with native blocks:

// Current
native {a}
native {b}
/* will become
ab
*/

native {a
}
native {
b}
native {
c
}
/* will become
a

b

c

*/
--------------------------------
// Kind of imo expected
native {a}
native {b}
/* will become
a
b
*/

native {a
}
native {
b}
native {
c
}
/* will become
a
b
c
*/
pfusik commented 2 months ago

To be honest with you I was trying to get rid of outputed class declaration by surrounding it and it's closing bracket with native blocks as an experiment of what I can do.

Why? We need an example of real code that would justify this change.

fut accepts multiple source files. If the different files have native blocks with #include / import, they will be placed at the top of the output. While this is just a convention for C and C++, it is a strict requirement of Java and C#. import / using following a class is a syntax error.

with exception of topmost declaration where native block would stay as is

This is counter-intuitive.

As for the newlines, I expect the closing brace to be on a new line, just like you usually format closing braces.

al1-ce commented 2 months ago

I don't have one...

It's all fair, I'll close this issue