Hello, author of the language here. You are correct that the project is an early state, I wasn't planning on spreading the word publicly for some time but as long as it was posted here I can answer some questions.
You can extend the compiler's functions during compile-time by doing more than just messing with llvm-ir. You are free to implement an automatic linter, or garbage collector for example. You can even do an optimization pass without operating on the llvm-ir. To do this, you could walk the parse tree of a function before it compiles and change around any common node patterns you are looking for before it is translated to llvm-ir. Alternatively, you can muck around in the ir and do the same thing.
The goto construct in the example provided does not need to be deeply integrated because the existing API is setup largely separate from the internal structure of the compiler. For example the function ctStore stores a variable in a compile-time container separate from the scope-separated table used internally by the compiler for other variables. The primary advantage of Ante as a language is that these functions enable compiler extensions to be made within the program and thus allow the swapping out of, eg. a garbage collector, without recompiling the compiler itself. This lets each application developer decide what features they need for their application. Instead of changing languages for a gc or desired optimization pass, just swap out a library.
I share your concern with the LLVM library constantly updating and the need to update bindings with it. I plan sometime to use the clang api to make a C++ -> Ante converter program, although I expect there to be numerous difficulties with its implementation.
Hi! Always fun to see new language ideas and watch them grow.
I think the general idea is interesting. However, I suspect that you're underestimating the complexity of the things you've mentioned. I don't mean to be too negative, but have you implemented garbage collection? Getting it right for just one language takes lots of serious effort. With the added complication of needing to deal with other arbitrary user-designed language constructs, it might be an intractable problem.
Brainstorming ideas for language design is great. Trying new things is fantastic. But it's important to be humble and realistic, and to recognize that language design requires making thoughtful tradeoffs.
That's completely fine, negativity isn't inherently bad in the first place. I have done some work with a garbage collector for an interpreted language I had previously worked on before. It was very basic as far as garbage collectors go, it just had a simple mark-sweep algorithm, nothing too complex. I'm not denying that creating a garbage collector would be quite an ambitious process, my goal as a language developer is just to give enough control of the language to the user to make that possible.
That being said, by no means do I claim that all extensions will work together perfectly, or at all. For example, a garbage collector would be completely incompatible with a plugin that frees all variables once they go out of scope. Compatibility is left up to the plugin's author in the case of multiple plugins having conflicting goals.
I'm not sure where I stated I was opposed to making tradeoffs, I have done several (albeit mostly syntactic) already. I knew the project was ambitious when I first started it, that is part of the fun of working on it.
You can extend the compiler's functions during compile-time by doing more than just messing with llvm-ir. You are free to implement an automatic linter, or garbage collector for example. You can even do an optimization pass without operating on the llvm-ir. To do this, you could walk the parse tree of a function before it compiles and change around any common node patterns you are looking for before it is translated to llvm-ir. Alternatively, you can muck around in the ir and do the same thing.
The goto construct in the example provided does not need to be deeply integrated because the existing API is setup largely separate from the internal structure of the compiler. For example the function ctStore stores a variable in a compile-time container separate from the scope-separated table used internally by the compiler for other variables. The primary advantage of Ante as a language is that these functions enable compiler extensions to be made within the program and thus allow the swapping out of, eg. a garbage collector, without recompiling the compiler itself. This lets each application developer decide what features they need for their application. Instead of changing languages for a gc or desired optimization pass, just swap out a library.
I share your concern with the LLVM library constantly updating and the need to update bindings with it. I plan sometime to use the clang api to make a C++ -> Ante converter program, although I expect there to be numerous difficulties with its implementation.