Comments (2)
Hello @stellarpower !
I've been long out of the Crystal game.. Anyway, that's what SWIG is basically capable of (In theory, not that it can do it today).
I guess that you could recycle the architecture of bindgen, and parts of some modules. Parsing C++ was really finicky, I guess that Rusts tooling is much better in that regard. Still, that's barely half the battle, the (semi-)automatic mapping is much harder. On the upside, Rust is much simpler than C++, if only by not having accumulated as much cruft.
Nowadays I'm still doing C++ for the most part .. and the other part Rust, actually. And I actually had ample projects where I could actually apply the knowledge gained through bindgen in the industry, so it's surely not all in vain ;)
If you were to take such an undertaking (Even if just for educational purposes), here's what I'd do:
- Fork bindgen and throw out like half of it (The really C++ specific parts)
- Get a rust parser to work which outputs a format similar as the current Clang-one does. That is, output as much information as useful (not as possible) in JSON. Every bit complexity you introduce here will have ripple effects to every line of code you write later on.
- Start small, write the code to generate calling a simple function like
add(x: i32, y: i32) -> i32
. This is also where you will meet the type system of bindgen. Ensure to understand it thoroughly - You should be able to greatly simplify it, as C++ does crazy things Rust doesn't. Again: The type stuff has ripple effects. Add as many convenience functions here as possible, a few highly complex pieces is much easier to maintain than scattering those complexities across the code base. - Map structures next, maybe simple C-style enums too. This gets finicky fast (You're seeing a theme yet?), so start with
#[repr(C, packed)]
structures. - You'll at latest now want to think how you map Rust-style enums over. And especially: Make them fun to use in Crystal!
- Extend the static run-time code to map Option, Result, et al over in a Crystal-idiomatic fashion. Same applies here: If the generated code sucks to use, then no one will use it.
- Still not tired? You still need to adapt traits and their impls. You may have already added initial support for this earlier, now it's the time to patch things up.
- Things will break later on. Write unit-tests. Annoying, but less so than playing what feels like Jenga all the time.
Honestly this seems daunting. I'm not sugar coating it. If you still think this sounds like a good project, please try it! I learned a lot about about code generation, and translating things that weren't meant to be translatable (Doing fun things in the process, those where everyone says "Don't try them at home"). Last but not least, I attribute my knowledge about Software Architecture to complex projects like this. It's a great learning experience, and for that alone, if you have the will and time, I say: Go for it!
from bindgen.
Thanks for the detailed reply! Appreciate it.
I have been out of the Crystal game a bit myself, can be hard to write projects in it sometimes, without starting and then finding you need a library that isn't available.
So, all this probably more than I have time for - and crucially, I don't actually speak any Rust. I may learn some some day but I've only dabbled thus far, so main motivation for asking, beyond the hypothetical, was the point of view of benefitting from using some crates. If google carbon or something like that comes along in the next few years, I probably would spend the time learning that through and through, as I think modern C++ with all the legacy bits dropped and full backwards-compatibility would be a hell of a language.
FYI magnus may be useful for a few of those items you enumerate above. If they already have the logic of mapping Rust types to Ruby, then whilst the backend would be very different, the semantics could probably be immitated.
I attribute my knowledge about Software Architecture to complex projects like this.
I agree, I think working at levels like this gives one a fundamentally different view on programming. I think sometimes people write their projects and like keeping the code very "simple", and would always think my approach is overcomplicating things. But code you can perhaps read very quickly then ends up being lots of copy-paste, doesn't scale well and breaks easily. All the stuff you read about in books when learning about breaking it up into small steps and chaining it together really is true as soon as you are working on a large-ish codebase doing something sufficiently complicated. You have to architect it, just throwing the idea out onto the page in a terse but hardcoded form that solves today's exact problem won't cut it.
I wonder if clang has evolved at all since you first attempted this. I know the folks at ROOT merged cint into cling using clang's modular architecture, and last time I looked at that project, they were a way behind the clang/LLVM mainline, but, were gradually planning on merging more back and forth between the projects to reduce the duplication and bring clang itself closer to being able to run the interpreter. I'd guess the basic parsing classes etc. haven't changed enormously, but you'd think it'd get more language-agnostic and more self-contained as time moves on. From memory, I thought the rust compiler used LLVM, but looking at it I guess the whole parsing architecture here wouldn't be re-usable. Unless there's some way to output an AST from a crate that does just that, but still many holes to fill in.
Anyway, thanks a lot! I am unlikely to attempt this, but it is interesting to think about nonetheless.
from bindgen.
Related Issues (20)
- Rebuilding Qt bindings for upcoming Crystal 1.0 release HOT 5
- Issues with container spec HOT 1
- [Question] Dealing with classes containing template arguments
- Does not work with LLVM/Clang 14 and multi-LLVM setup
- [proposal] Update and automate documentation HOT 8
- Update or remove the Contributors section in the README HOT 1
- Overloaded Qt signals HOT 3
- `find_clang` fails to find libraries HOT 1
- CrystalProc ignores Crystal-side type conversions HOT 4
- Issues wrapping namespaced classes HOT 1
- Stack overflow due to calling superclass method inside virtual override HOT 4
- Public instance properties HOT 1
- Potential premature collection of wrapped types
- Undefined reference to GC_throw_bad_alloc()
- Bindgen::Graph::Path edge cases
- Support nested anonymous types
- Destructors not called on GC-enabled instances HOT 3
- Support downcasting between Crystal wrapper types
- Some namespaced class hierarchies are not realizable
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bindgen.