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

Emit compiler directives based on language being compiled #142

Closed caesay closed 9 months ago

caesay commented 9 months ago

Right now it's a bit cumbersome to write implementations in native languages, one thing which could make it easier is if we could do something like #if JS or #if CPP out of the box.

I had a look at the command line and wasn't entirely sure, but I guess fut.cpp, fut.cs, fut.java, and fut.js are not being generated and are written by hand?

Because of the way parseAndResolve/emit/emitImplicitLang works we'll need to restructure things a bit, so that the source is parsed once for each file emitted. Do you have any issues with this? If you agree with the change I can submit a PR.

pfusik commented 9 months ago

What's the problem to pass -D JS etc?

Also, perhaps we could have a nicer syntax than:

#if JS
native { ... }
#endif

Maybe native (js, ts) { ... } ? or native "js | ts" { .... } ?

Yes, fut.* are hand-coded. They could probably be refactored to Fusion.

Only recently I changed per-language parsing to just once. I'd prefer to have as few #ifs as possible.

pfusik commented 9 months ago

Also, in my ~50 KLOC of Fusion code there's just one native. What is your use case?

caesay commented 9 months ago

Probably at least half of my code is in native{} blocks at the moment. There are some weird things too, because the parser doesn't completely ignore code in native blocks. For example "\0" in a native block gives a compiler error about it being an unknown escape sequence (and there are other oddities too - single quotes to name one other).

I think I've already mentioned a few of my use-cases. Right now I'm working on https://velopack.io/ which is a cross-platform, soon-to-be-cross-language installer/update framework for desktop apps. I am working on translating a small/minimal portion of the core update library which application authors will consume: https://github.com/velopack/velopack/tree/master/src/Velopack

So a lot of my code right now looks like this:

image

Or like this:

image

Or like this:

image

All of that platform native code is annoying, and is ultimately the reason I'm trying right now to start contributing some of the missing features myself to fusion directly. Even with the missing features and #if's and native blocks, it's still a time saver, because after the json parsing, process starting, and string utilities the rest of my library is mostly algorithmic / logic which I want to re-use and expose to application authors as a library.

caesay commented 9 months ago

And also, yes of course I can use -D, and I do. It just means my build script needs to look like this:

fut -o for-cpp\Velopack.cpp -n Velopack -D CPP Util.fu UpdateInfo.fu Platform.fu UpdateManager.fu || exit /b
fut -o for-js\Velopack.js -n Velopack -D JS Util.fu VelopackApp.fu UpdateInfo.fu Platform.fu UpdateManager.fu || exit /b
fut -o for-cs\Velopack.cs -n Velopack -D CS Util.fu VelopackApp.fu UpdateInfo.fu Platform.fu UpdateManager.fu || exit /b

and so on.

I just thought it was a feature that made sense. There will always be instances where fusion can't cover it and you need to break out into native code, and that should be as easy as possible imo.

pfusik commented 9 months ago

These three lines of build script don't look that bad. Thanks a lot for code examples! These look like what should be added to Fusion library, and we already made good progress on ToLower and JSON parsing.

caesay commented 9 months ago

Closing this since you don't seem keen on it