More JNI vs. Pika comparison Jim Blandy (17 Feb 2004 23:22 UTC)
|
Re: More JNI vs. Pika comparison
Matthew Dempsky
(18 Feb 2004 08:09 UTC)
|
Re: More JNI vs. Pika comparison
Jim Blandy
(18 Feb 2004 08:39 UTC)
|
Re: More JNI vs. Pika comparison
Matthew Dempsky
(18 Feb 2004 15:46 UTC)
|
Re: More JNI vs. Pika comparison
Tom Lord
(20 Feb 2004 17:32 UTC)
|
Re: More JNI vs. Pika comparison
Jim Blandy
(24 Feb 2004 22:13 UTC)
|
Re: More JNI vs. Pika comparison
Tom Lord
(24 Feb 2004 22:32 UTC)
|
Re: More JNI vs. Pika comparison
Jim Blandy
(24 Feb 2004 23:23 UTC)
|
Re: More JNI vs. Pika comparison
Tom Lord
(25 Feb 2004 00:16 UTC)
|
I've come across a situation which is reasonably straightforward to handle in a JNI-style interface, but which I think requires machinery I haven't seen yet in Pika-style. I'd like to see the Pika folks' solution here. When I write actions for a Bison grammar, it's pretty straightforward to use Minor references in the semantic actions. I've included most of the .y file here in case someone wanted all the details, but skip down to the list_data nonterminal to see what I'm talking about. (I'm inflicting untested code on you folks again. I'll earn some kind of gonzo reward eventually. Sorry. But I think the point is safe enough.) %{ /* The type of Bison semantic values. */ #define YYSTYPE mn_ref * /* Our parser takes an mn_call, cast to a void *, as a parameter. */ #define YYPARSE_PARAM untyped_call #define c ((mn_call *) untyped_call) %} %pure_parser %token CHARACTER %token FALSE %token IDENTIFIER %token NEWLINE_CHARACTER %token NUMBER %token SPACE_CHARACTER %token START_VECTOR %token STRING %token TRUE %token UNQUOTE_SPLICING %% datum: simple_datum | compound_datum; simple_datum: boolean | NUMBER | character | STRING | symbol; boolean: TRUE | FALSE; character: SPACE_CHARACTER | NEWLINE_CHARACTER | CHARACTER ; symbol: IDENTIFIER; compound_datum: list | vector; list: '(' list_data ')' { $$ = $2 }; list_data: datum list_data { $$ = mn_to_cons (c, $1, $2); } | datum '.' datum { $$ = mn_to_cons (c, $1, $3); } | { $$ = mn_null (c); } ; vector: START_VECTOR vector_data ')' { $$ = mn_list_to_vector (c, $2); mn_free_local_ref (c, $2); } ; vector_data: datum vector_data { $$ = mn_to_cons (c, $1, $2); } | { $$ = mn_null (c); } ; %% The underlying issue here is that we want the generated parser's stack of semantic values to hold references to Scheme objects. Since a JNI-style interface works on pointers to dynamically allocated references, one can simply declare semantic values to be such pointers, as we do with the #definition of YYSTYPE above. We use "linear" functions like mn_to_cons to free intermediate references. If the parser exits with an error, any local references on the stack are freed properly when the mn_call returns. It seems to me that handling this in Pika requires one to use a separate facility that hasn't been described on this list before, which allows Pika references to appear inside other data structures, gives them dynamic lifetimes, and requires them to be explicitly freed --- much as with a JNI-style interface. Then, one writes code much like the above. And the user would need to write their own mechanism for cleaning things up in the case of a parser error. It seems to me similar problems will occur working with any third-party tool that presumes it is sufficient to let people pass around pointers to data of their own definition. So, in the end, it looks to me as if Pika will need to provide a JNI-style interface anyway, in addition to the C compound-statement- bound interface, which would still be the preferred interface for C code written against Pika interfaces.