oakc icon indicating copy to clipboard operation
oakc copied to clipboard

Adds a Ruby backend

Open dospunk opened this issue 3 years ago • 8 comments

dospunk avatar Aug 27 '20 21:08 dospunk

Whoa!!!!!! I'm absolutely ecstatic. You've written almost half of our backends now!!!

As an outsider who has implemented Oak for multiple targets, what are some of the strange bugs that you see sometimes while developing a backend? Is the backend code easy to port? What's been your overall experience with implementing the typescript and ruby backends?

adam-mcdaniel avatar Aug 27 '20 21:08 adam-mcdaniel

TypeScript and Ruby were both fairly easy to implement. The hardest part of both was implementing the getch function, since neither language has a built in version, but other than that the std and core code is very easy to port. Implementing a new backend takes about an afternoon, maybe less.

The most annoying part of the process is having to modify multiple Rust files to add a new backend. In bin.rs, you have to add in the use statement, the new flag, and the if statement for whether the flag was found. In lib.rs you have to add in a use statement, and in target/mod.rs you have to add the mod statement and the use statement. If there were a way to streamline that process a little bit, that would be awesome.

I also started work on a Python backend, but quickly hit a dead end. Because of the way that begin_while and end_while work, any language that uses significant whitespace to denote blocks is impossible to implement. If there were only ever one level of indentation it would be easy to work around, but the loops within functions and loops within loops would necessitate some sort of counter to keep track of the indentation level. I tried to hack around with it a bit, but I don't understand Rust well enough to get it working.

dospunk avatar Aug 27 '20 21:08 dospunk

Thats good to hear!! Also, with respect to the Python backend, you could use a static mut INDENT_LEVEL: i32 to keep track of the current indent level. I THINK this would work, anyways.

adam-mcdaniel avatar Aug 27 '20 22:08 adam-mcdaniel

I'll give that a shot!

dospunk avatar Aug 27 '20 22:08 dospunk

So the static mut idea for indentation level unfortunately didn't work, as static mut is apparently unsafe

dospunk avatar Oct 24 '20 17:10 dospunk

It is indeed 'unsafe' but that is just because Rust wants to be able to reason about the variables and its access in a multithreading environment. You can wrap code using this value in unsafe {} blocks to be able to use it.

kevinramharak avatar Oct 25 '20 18:10 kevinramharak

It is indeed 'unsafe' but that is just because Rust wants to be able to reason about the variables and its access in a multithreading environment. You can wrap code using this value in unsafe {} blocks to be able to use it.

The problem is you can't use unsafe code in a safe function. Unless I'm missing something, which is not unlikely, introducing this one piece of unsafe code would cause a decent chunk of the program to be unsafe just to use it.

dospunk avatar Oct 25 '20 20:10 dospunk

You can look at this commit https://github.com/kevinramharak/oakc/commit/c1727cbebf7926d435a0fcc6ceb189a5976d1418#diff-a0d44f3f45a877f81e862f4806d19f4c7b8f026afd68f98e5a1eb74b0a6f71ca to see how I used to use static without having to mark whole functions as unsafe. You could instead use a struct to keep track of your state during code generation. This does require you to change bin.rs to instantiate your target just a bit different from other targets.

kevinramharak avatar Oct 26 '20 11:10 kevinramharak