1. My frustration
- Posted by BRyan May 16, 2014
- 1335 views
My frustration is that is no documentation to explain in detail how to add one function WRITTEN in Euphoria with one parameter ( a sequence ) that returns an ATOM.
I have been told that all I have to do is pass the routine_id is to look at the way coverage in version 4.1. Well that may be easy if you are a developer that understands everything about the details of using coverage but it is hopeless.
The user needs to know where to put the function written in euphoria.
Where is the callback is initially executed in the backend .
Someone has to write a DETAILED how to ADD a euphoria function to the interpreter
showing how to pass its routine_id from the backend to the frontend;
It must show ever file and place that needs code.
Don't say write the function in 'C' !
I had the idea that you could use the translator to translate a euphoria function to 'C'
and just place the translated function and compile into the interpreter.
But as you know the 'C' output from the translator splits across many files and uses
numbers for variables and etc.
Forked into: Hacking Euphoria
2. Re: My frustration
- Posted by mattlewis (admin) May 19, 2014
- 1274 views
I had the idea that you could use the translator to translate a euphoria function to 'C'
and just place the translated function and compile into the interpreter.
But as you know the 'C' output from the translator splits across many files and uses
numbers for variables and etc.
You could still do this. Of course, if your routine relies on other routines, you'll need those, too.
One challenge in generating code is avoiding naming conflicts. C has different namespace rules than euphoria, so we need to make sure it all works when we translate the symbol names from euphoria to C. We do that by including the symbol's index in the symbol table in its name, so all of your variables are guaranteed unique. Even so, you should be able to simplify that with some search and replace.
Symbols that are all numbers / underscores are temporary variables. _0, _1 and _2 are created and used automatically by the translator. The others are temporary variables from the IL code. Of course, a human could probably optimize them down to fewer distinct variables, but so will a compiler, and it keeps the translator simpler to not worry about those.
You could also get help here on specifics and maybe find someone more comfortable with C to collaborate with. But as the back end of euphoria really is C, the best way is just to write stuff in C to begin with.
Matt
3. Re: My frustration
- Posted by ghaberek (admin) May 19, 2014
- 1214 views
You could also get help here on specifics and maybe find someone more comfortable with C to collaborate with. But as the back end of euphoria really is C, the best way is just to write stuff in C to begin with.
I'm afraid Matt's probably right. You'll probably end up having to do it this way. What function are you trying to add?
Also, I don't understand your comments about coverage. Could you elaborate?
-Greg
4. Re: My frustration
- Posted by mattlewis (admin) May 19, 2014
- 1217 views
Also, I don't understand your comments about coverage. Could you elaborate?
The front end of the interpreter has a feature to instrument your code for the purpose of measuring code coverage for your tests (see coverage.e). These are written as part of the front end, but need to be called by the back end. The back end is started by a machine call from the front end. We pass along the routine id of the routines we need to call as specific parameters in the start_backend machine call. There are a few others. Here is the call from backend.e:
-- M_BACKEND: machine_proc(65, { st, sl, ms, lit, include_info, get_switches(), Argv, routine_id( "cover_line" ), routine_id( "cover_routine" ), routine_id( "write_coverage_db" ), routine_id( "DisplayColorLine" ), external_debugger_ptr, routine_id( "map:new" ), routine_id( "map:put" ), routine_id( "map:get" ), trace_lines, $ })
These routines are handled as translated routine ids, and are separate from the normal routine ids that happen in the users code. The translator keeps a lookup table for these routines, and we use that to call the translated functions. There's no reason why this couldn't be done for other things.
In be_machine.c, start_backend(), we save these values:
// Front End CallBacks: cover_line = get_pos_int(w, *(x_ptr->base+8)); cover_routine = get_pos_int(w, *(x_ptr->base+9)); write_coverage_db = get_pos_int(w, *(x_ptr->base+10)); syncolor = get_pos_int(w, *(x_ptr->base+11));
You can look at be_coverage.c for the wrappers around these callbacks (there are a few others in other parts, too, but they give you an idea of what's going on):
void COVER_LINE(int line) { if (cover_line != -1) { internal_general_call_back(cover_line, line,0,0, 0,0,0, 0,0,0); } }
Matt