Is there a way to translate C code to Ruby? - c

I'm sitting with massive amounts of legacy C code that needs to be converted to Ruby for a project.
I've seen Ruby to C translators online, but not the other way around. Would there be a simple way to approach this particular problem?

You'll either have to write a C to Ruby translator, which is possible but the effort might not be justifiable, or you could split the C code up into smaller modules that you can create Ruby wrappers for as a first step. Once they're all wrapped in Ruby and the main control flow is done in Ruby, you can write a test harness (both to verify correctness of your replacement code and to aid reverse engineering) and start replacing the C modules with Ruby modules.
The divide & conquer approach should work with regular Ruby if you use the modules as native extensions but obviously this will cause further problems if you're targeting something like JRuby as your runtime environment. If you want to do something similar in JRuby as per your comment, you're looking at wrapping the C modules in JNI and calling through from the JVM that way. Either way will allow your C code to interact with the Ruby code, but the two approaches are not interchangeable.
Neither approach is going to be quick and both are going to be a lot of work.

You could:
Write a C interpreter in Ruby (very hard).
Wrap the compiled C code with something like SWIG (much easier).

Programming in C and programming in Ruby bear completely different programming paradigms. So while the old saying that you can write Fortran (or C in this case) code in any language is true, the Ruby code that you would eventually get by machine translation wouldn't be Ruby at all, except syntactically.
So, IMHO, any way other than manual (and done by proficient Rubyists, I might add) would be either impossible, or at least not useful at all.

Maybe you can try this https://github.com/jackieju/CPP2Ruby/
It's fresh for cpp but existed longer for c to ruby

You can try Abap2Ruby. It can also convert cpp to ruby.

Related

Turning strings into code?

So let's say I have a string containing some code in C, predictably read from a file that has other things in it besides normal C code. How would I turn this string into code usable by the program? Do I have to write an entire interpreter, or is there a library that already does this for me? The code in question may call subroutines that I declared in my actual C file, so one that only accounts for stock C commands may not work.
Whoo. With C this is actually pretty hard.
You've basically got a couple of options:
interpret the code
To do this, you'll hae to write an interpreter, and interpreting C is a fairly hard problem. There have been C interpreters available in the past, but I haven't read about one recently. In any case, unless you reallY really need this, writing your own interpreter is a big project.
Googling does show a couple of open-source (partial) C interpreters, like picoc
compile and dynamically load
If you can capture the code and wrap it so it makes a syntactically complete C source file, then you can compile it into a C dynamically loadable library: a DLL in Windows, or a .so in more variants of UNIX. Then you could load the result at runtime.
Now, what normally would lead someone to do this is a need to be able to express some complicated scripting functions. Have you considered the possibility of using a different language? Python, Scheme (guile) and Lua are easily available to add as a scripting language to a C application.
C has nothing of this nature. That's because C is compiled, and the compiler needs to do a lot of building of the code before the code starts running (hence receives a string as input) that it can't really change on the fly that easily. Compiled languages have a rigidity to them while interpreted languages have a flexibility.
You're thinking of Perl, Python PHP etc. and so called "fourth generation languages." I'm sure there's a technical term in c.s. for this flexibility, but C doesn't have it. You'll need to switch to one of these languages (and give up performance) if you have a task that requires this sort of string use much. Check out Perl's /e flag with regexes, for instance.
In C, you'll need to design your application so you don't need to do this. This is generally quite doable, as for its non-OO-ness and other deficiencies many huge, complex applications run on well-written C just fine.

Coming from an OOP background, what would be some C programs/libraries to help me get the "C way"?

I have been doing OOP (C++/Java/PHP/Ruby) for a long time and really have a hard time imagining how large programs and libraries such as Linux or Apache can be written entirely in an imperative style. What would be small open source C projects I could look at to get a feel of how things are done in C?
Bonus points if the project is hosted on GitHub.
Things are done exactly the same way in C, but with less overt support from the language. Instead of creating a class to encapsulate some state, you create a struct. Instead of creating class members, with implicit this parameters, you create functions that you explicitly pass a struct* as the first parameter, that then operate on the struct.
To ensure that encapsulation is not broken you can declare the struct in a header, but only define it in the .c file where it is used. Virtual functions require more work - but again, its just a case of putting function pointers in the struct. Which is actually more convenient in C than C++ because in C you get to fill in your vtables manually, getting quite a fine level of control over which part of code implements part of what COM interface (if you are into COM in C of course).
You might find the ccan (Comprehensive C Archive Network, modeled after Perl's CPAN) interesting.
It's small at the moment, but the contributions are of high quality. Many of the contributions are by linux kernel developers.
Almost everything in there falls into the "few thousand LOC" or less category, too.
If you want a small example to start with, try looking at the source for the basic Linux CLI utilities. GNU binutils, make, or any of the other GNU utilities have full source code available and are relatively small code bases (some are larger than others). The easiest thing is usually to start with a utility that you have used before and are already familiar with.
Look at GLib for an almost canonical example of how to do object oriented programming in C.

Why does Ruby FFI need attach_function calls when there are header files?

Is there a way to point Ruby FFI to a header file instead of writing attach_function calls? A header file basically has the same exact information.
temp_convert.rb:
attach_function :temp_convert, [:float], :float
temp_convert.h:
float temp_convert(float temp);
Because C header files are written in C but Ruby interpreters only interpret Ruby. Also, the header files might not even be available at runtime.
There has been talk about automatically generating attach_function calls from headers. However, as I hinted at above, this basically means that you must implement a full C compiler (well, the full front half of one, to be precise). At the moment, the Ruby implementers are more focused on making Ruby run as fast as C to alleviate the need to use FFI in the first place than writing their own C compiler (which is a non-trivial undertaking even though you only need to do the lexing, parsing, semantic analysis and typing parts, not the actual code generation or optimization).
As Jörg says, implementing a header scanner means implementing quite a bit of the C compiler, to get everything right.
One thing you might like to try to ease the pain is the FFI Swig Generator. It uses swig to generate the FFI interface. It still means you need to do a bit of work, which can boil down to a cut'n'paste job to generate the swig input file for simple interfaces.

What are the pitfalls and gotchas of mixing Objective-C and C?

At the risk of oversimplifying something I'm worried might be ridiculously complex, what should I be aware of when mixing C and Objective-C?
Edit: Just to clarify, I've never worked with C before, and I'm learning Objective-C through Cocoa. Also I'm using the Chipmunk Dynamics engine, which is C.
I'd put it the other way around: you might be risking overcomplicating something that is ridiculously simple :-)
Ok, I'm being a bit glib. As others are pointing out, Objective-C is really just a minimal set of language extensions to C. When you are writing Objective-C code, you are actually writing C. You can even access the internal machinations of the Objective-C runtime support using some handy C functions that are part of the language (no... I don't recommend you actually DO this unless you really know what you're doing).
About the only time I've ever had mildly tricky moments is when I wanted to pass an Objective-C instance method as a callback to a C function. Say, for example, I'm using a pure-C cross platform library that has functions which accept a callback. I might call the function from within an object instance to process some data, and then want that C function to call my instance BACK when its done, or as part of getting additional input etc etc (a common paradigm in C). This can be done with funky function wrapping, and some other creative methods I've seen, and if you ever need to do it googling "objective-c method for c callback" or something like that will give you the goods.
The only other word of advice is to make sure your objects appropriately manage any manually malloced memory that they create for use by C functions. You'll want your objective-c classes to tidy up that memory on dealloc if, indeed, it is finished.
Other than that, dust off any reference on C and have fun!
You can't 'mix' C and Objective-C: Objective-C is a superset of C.
Now, C++ and Objective-C on the other hand...
Objective C is a superset of C, so it shouldn't conflict.
Except that, as pointed here pure C has different conventions (obviously, since there is no built-in mechanism) to handle OO programming. In C, an object is simply a (struct *) with function pointers.

How do I access the Ruby AST from C level code?

I understand that the Ruby 1.8 AST is traversed at runtime using a big switch statement, and many things like calling a method in a class or parent module involve the interpreter looking up and down the tree as it goes. Is there a straightforward way of accessing this AST in a Ruby C extension? Does it involve the Ruby extension API, or necessitate hacking the internal data structures directly?
A good starting point is probably to read the source of the ParseTree library, which lets you get at and mess with the AST from ruby.
Thanks for the tip. You're right - ParseTree seems to be the only code out there with any manipulation of the AST going on, except that it's actually written in RubyInline.
So, it's a strange mixture between Ruby and C code. Very interesting reading, though.
The other reference of course is eval.c from Ruby itself.
It's going to take a fair bit of reading of both, to get my head around it.

Resources