[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

More JNI vs. Pika comparison

This page is part of the web mail archives of SRFI 50 from before July 7th, 2015. The new archives for SRFI 50 contain all messages, not just those from before July 7th, 2015.

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


/* 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)



%token FALSE
%token NUMBER
%token STRING
%token TRUE


datum: simple_datum | compound_datum;

simple_datum: boolean | NUMBER | character | STRING | symbol;

boolean: TRUE | FALSE;



compound_datum: list | vector;

list: '(' list_data ')' { $$ = $2 };

    datum list_data { $$ = mn_to_cons (c, $1, $2); }
  | datum '.' datum { $$ = mn_to_cons (c, $1, $3); }
  |                 { $$ = mn_null (c); }

    START_VECTOR vector_data ')'
        $$ = mn_list_to_vector (c, $2);
        mn_free_local_ref (c, $2);

    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.