Re: Converting C to Euphoria
- Posted by ghaberek (admin) 6 days ago
- 244 views
Are there any tools for converting C to Euphoria? Or at least some discussion.
I don't recall anything specific, no. Rob often promoted the language as being able to find and solve problems when porting from C to Euphoria, though I'd imagine that was often done by hand.
Doing a perfect one-for-one translation from C isn't really worthwhile anyway, unless you need to somehow maintain some specific compatibility with C. You're better off translating the purpose of the program.
I was thinking of implementing the TRAC programming language, converting the nntrac at https://git.sr.ht/~luxferre/nntrac to Euphoria and compiling it to EXE ultimately for setting up as a Exercism language.
Overall it's quite possible. You could probably start with the C code as-is, considering you can build the code as a shared library, and then wrap that in Euphoria. Or use the executable version for testing against your Euphoria TRAC interpreter.
The code itself is less than 1200 lines and makes use of several global values and arrays. The primitives and forms arrays could easily be sequences and name lookup could probably be sped up with a map. The rest is mostly string parsing for the code and built-in primitives.
Here's a rough translation of the primitives registration functions. You can see how it's nearly but not entirely one-for-one. It's still very "C" but also very "Euphoria." I think the hardest part is going to be all of the strtok calls and ensuring the zero vs. one offsets are all correct.
enum PRIM_NAME, PRIM_FUNC sequence nnt_primitives /* find a primitive function index by name, -1 if not found */ public function nnt_findprimitive(sequence name) for i = 1 to length(nnt_primitives) do if equal(nnt_primitives[i][PRIM_NAME], name) then return i /* found */ end if end for return -1 /* nothing found */ end function /* register a primitive function, overwrite if already exists */ public procedure nnt_regprimitive(sequence name, integer func) integer pindex = nnt_findprimitive(name) sequence newprim = {"",-1} /* create a new primitive template */ newprim[PRIM_NAME] = name /* fill the name */ newprim[PRIM_FUNC] = func /* fill the handler id*/ if pindex = -1 then /* create a new table entry */ nnt_primitives = append(nnt_primitives, newprim) else /* replace the entry */ nnt_primitives[pindex] = newprim end if end procedure ... /* init the resources and built-in primitives */ public procedure nnt_init() nnt_forms = {} /* init the forms table */ nnt_primitives = {} /* init the primitives table */ --nnt_rngs = ??? /* init the PRNG */ nnt_regprimitive("ps", routine_id("prim_ps")) nnt_regprimitive("rc", routine_id("prim_rc")) nnt_regprimitive("rs", routine_id("prim_rs")) -- ... end procedure
Hope this helps!
-Greg
P.S. The Creole parser ate the tilde ~ in your URL. I've edited your post to correct it.
You can prevent this by escaping with another tilde or enclosing the URL in brackets, like this:
https://git.sr.ht/~~luxferre/nntrac -or- [[https://git.sr.ht/~luxferre/nntrac]]