/*
* Copyright 2011 Jeffrey Kegler
* This file is part of Marpa::XS. Marpa::XS is free software: you can
* redistribute it and/or modify it under the terms of the GNU Lesser
* General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* Marpa::XS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser
* General Public License along with Marpa::XS. If not, see
* http://www.gnu.org/licenses/.
*/
#include <gperl.h>
#include "config.h"
#include "marpa.h"
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "Marpa"
#define DEBUG 0
#if !DEBUG
#if defined(G_HAVE_GNUC_VARARGS)
#undef g_debug
#define g_debug(...)
#endif /* defined G_HAVE_GNUC_VARARGS */
#endif /* if !DEBUG */
typedef struct marpa_g Grammar;
typedef struct {
Grammar *g;
GArray* gint_array;
} G_Wrapper;
typedef struct marpa_r Recce;
typedef struct {
Recce *r;
SV *g_sv;
GArray* gint_array;
} R_Wrapper;
static const char grammar_c_class_name[] = "Marpa::XS::Internal::G_C";
static const char recce_c_class_name[] = "Marpa::XS::Internal::R_C";
static void
xs_g_message_callback(Grammar *g, Marpa_Message_ID id)
{
SV* cb = marpa_g_message_callback_arg(g);
if (!cb) return;
if (!SvOK(cb)) return;
{
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSViv( marpa_grammar_id(g))));
XPUSHs(sv_2mortal(newSVpv(id, 0)));
PUTBACK;
call_sv(cb, G_DISCARD);
FREETMPS;
LEAVE;
}
}
static void
xs_r_message_callback(struct marpa_r *r, Marpa_Message_ID id)
{
SV* cb = marpa_r_message_callback_arg(r);
if (!cb) return;
if (!SvOK(cb)) return;
{
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSViv( marpa_r_id(r))));
XPUSHs(sv_2mortal(newSVpv(id, 0)));
PUTBACK;
call_sv(cb, G_DISCARD);
FREETMPS;
LEAVE;
}
}
static void
xs_rule_callback(Grammar *g, Marpa_Rule_ID id)
{
SV* cb = marpa_rule_callback_arg(g);
if (!cb) return;
if (!SvOK(cb)) return;
{
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSViv( marpa_grammar_id(g))));
XPUSHs(sv_2mortal(newSViv(id)));
PUTBACK;
call_sv(cb, G_DISCARD);
FREETMPS;
LEAVE;
}
}
static void
xs_symbol_callback(Grammar *g, Marpa_Symbol_ID id)
{
SV* cb = marpa_symbol_callback_arg(g);
if (!cb) return;
if (!SvOK(cb)) return;
{
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv_2mortal(newSViv( marpa_grammar_id(g))));
XPUSHs(sv_2mortal(newSViv(id)));
PUTBACK;
call_sv(cb, G_DISCARD);
FREETMPS;
LEAVE;
}
}
MODULE = Marpa::XS PACKAGE = Marpa::XS
PROTOTYPES: DISABLE
void
version()
PPCODE:
{
int version[3];
marpa_version(version);
EXTEND(SP, 3);
mPUSHi( version[0] );
mPUSHi( version[1] );
mPUSHi( version[2] );
}
MODULE = Marpa::XS PACKAGE = Marpa::XS::Internal::G_C
G_Wrapper *
new( class, non_c_sv )
char * class;
PREINIT:
struct marpa_g *g;
SV *sv;
G_Wrapper *g_wrapper;
PPCODE:
g = marpa_g_new();
marpa_g_message_callback_set( g, &xs_g_message_callback );
marpa_rule_callback_set( g, &xs_rule_callback );
marpa_symbol_callback_set( g, &xs_symbol_callback );
Newx( g_wrapper, 1, G_Wrapper );
g_wrapper->g = g;
g_wrapper->gint_array = g_array_new( FALSE, FALSE, sizeof(gint));
sv = sv_newmortal();
sv_setref_pv(sv, grammar_c_class_name, (void*)g_wrapper);
XPUSHs(sv);
void
DESTROY( g_wrapper )
G_Wrapper *g_wrapper;
PREINIT:
struct marpa_g * grammar;
CODE:
grammar = g_wrapper->g;
{
SV *sv = marpa_g_message_callback_arg(grammar);
marpa_g_message_callback_arg_set( grammar, NULL );
if (sv) {
SvREFCNT_dec(sv);
}
}
{
SV *sv = marpa_rule_callback_arg(grammar);
marpa_rule_callback_arg_set( grammar, NULL );
if (sv) {
SvREFCNT_dec(sv); }
}
{
SV *sv = marpa_symbol_callback_arg(grammar);
marpa_symbol_callback_arg_set( grammar, NULL );
if (sv) {
SvREFCNT_dec(sv); }
}
g_array_free(g_wrapper->gint_array, TRUE);
marpa_g_free( grammar );
Safefree( g_wrapper );
# Note the Perl callback closure
# is, in the libmarpa context, the *ARGUMENT* of the callback,
# not the callback itself.
# The libmarpa callback is a wrapper
# that calls the Perl closure.
void
message_callback_set( g, sv )
Grammar *g;
SV *sv;
PPCODE:
{
SV *old_sv = marpa_g_message_callback_arg(g);
if (old_sv) { SvREFCNT_dec(old_sv); }
}
marpa_g_message_callback_arg_set( g, sv );
SvREFCNT_inc(sv);
void
rule_callback_set( g, sv )
Grammar *g;
SV *sv;
PPCODE:
{
SV *old_sv = marpa_rule_callback_arg(g);
if (old_sv) {
SvREFCNT_dec(old_sv); }
}
marpa_rule_callback_arg_set( g, sv );
SvREFCNT_inc(sv);
void
symbol_callback_set( g, sv )
Grammar *g;
SV *sv;
PPCODE:
{
SV *old_sv = marpa_symbol_callback_arg(g);
if (old_sv) {
SvREFCNT_dec(old_sv); }
}
marpa_symbol_callback_arg_set( g, sv );
SvREFCNT_inc(sv);
Marpa_Grammar_ID
id( g )
Grammar *g;
CODE:
RETVAL = marpa_grammar_id(g);
OUTPUT:
RETVAL
void
start_symbol_set( g, id )
Grammar *g;
Marpa_Symbol_ID id;
PPCODE:
{ gboolean result = marpa_start_symbol_set(g, id);
if (result) XSRETURN_YES;
}
XSRETURN_NO;
void
start_symbol( g )
Grammar *g;
PPCODE:
{ Marpa_Symbol_ID id = marpa_start_symbol( g );
if (id < 0) { XSRETURN_UNDEF; }
XPUSHs( sv_2mortal( newSViv(id) ) );
}
void
is_precomputed( g )
Grammar *g;
PPCODE:
{ gint boolean = marpa_is_precomputed( g );
if (boolean) XSRETURN_YES;
XSRETURN_NO;
}
void
has_loop( g )
Grammar *g;
PPCODE:
{ gint boolean = marpa_has_loop( g );
if (boolean) XSRETURN_YES;
XSRETURN_NO;
}
void
is_lhs_terminal_ok_set( g, boolean )
Grammar *g;
int boolean;
PPCODE:
{ gboolean result = marpa_is_lhs_terminal_ok_set(
g, (boolean ? TRUE : FALSE));
if (result) XSRETURN_YES;
}
XSRETURN_NO;
void
is_lhs_terminal_ok( g )
Grammar *g;
PPCODE:
{ gboolean boolean = marpa_is_lhs_terminal_ok( g );
if (boolean) XSRETURN_YES;
XSRETURN_NO;
}
Marpa_Symbol_ID
symbol_new( g )
Grammar *g;
CODE:
RETVAL = marpa_symbol_new(g);
OUTPUT:
RETVAL
void
symbol_lhs_rule_ids( g, symbol_id )
Grammar *g;
Marpa_Symbol_ID symbol_id;
PPCODE:
{ GArray *rule_id_array = marpa_symbol_lhs_peek( g, symbol_id );
guint len = rule_id_array->len;
Marpa_Rule_ID* rule_ids = (Marpa_Rule_ID*)rule_id_array->data;
if (GIMME == G_ARRAY) {
int i;
EXTEND(SP, len);
for (i = 0; i < len; i++) {
PUSHs( sv_2mortal( newSViv(rule_ids[i]) ) );
}
} else {
XPUSHs( sv_2mortal( newSViv(len) ) );
}
}
# In scalar context, returns the RHS length
void
symbol_rhs_rule_ids( g, symbol_id )
Grammar *g;
Marpa_Symbol_ID symbol_id;
PPCODE:
{ GArray *rule_id_array = marpa_symbol_rhs_peek( g, symbol_id );
guint len = rule_id_array->len;
Marpa_Rule_ID* rule_ids = (Marpa_Rule_ID*)rule_id_array->data;
if (GIMME == G_ARRAY) {
int i;
EXTEND(SP, len);
for (i = 0; i < len; i++) {
PUSHs( sv_2mortal( newSViv(rule_ids[i]) ) );
}
} else {
XPUSHs( sv_2mortal( newSViv(len) ) );
}
}
void
symbol_is_accessible_set( g, symbol_id, boolean )
Grammar *g;
Marpa_Symbol_ID symbol_id;
int boolean;
PPCODE:
marpa_symbol_is_accessible_set( g, symbol_id, (boolean ? TRUE : FALSE));
void
symbol_is_accessible( g, symbol_id )
Grammar *g;
Marpa_Symbol_ID symbol_id;
PPCODE:
{ gboolean boolean = marpa_symbol_is_accessible( g, symbol_id );
if (boolean) XSRETURN_YES;
XSRETURN_NO;
}
void
symbol_is_counted( g, symbol_id )
Grammar *g;
Marpa_Symbol_ID symbol_id;
PPCODE:
{ gboolean boolean = marpa_symbol_is_counted( g, symbol_id );
if (boolean) XSRETURN_YES;
XSRETURN_NO;
}
void
symbol_is_nullable_set( g, symbol_id, boolean )
Grammar *g;
Marpa_Symbol_ID symbol_id;
int boolean;
PPCODE:
marpa_symbol_is_nullable_set( g, symbol_id, (boolean ? TRUE : FALSE));
void
symbol_is_nullable( g, symbol_id )
Grammar *g;
Marpa_Symbol_ID symbol_id;
PPCODE:
{ gboolean boolean = marpa_symbol_is_nullable( g, symbol_id );
if (boolean) XSRETURN_YES;
XSRETURN_NO;
}
void
symbol_is_nulling_set( g, symbol_id, boolean )
Grammar *g;
Marpa_Symbol_ID symbol_id;
int boolean;
PPCODE:
marpa_symbol_is_nulling_set( g, symbol_id, (boolean ? TRUE : FALSE));
void
symbol_is_nulling( g, symbol_id )
Grammar *g;
Marpa_Symbol_ID symbol_id;
PPCODE:
{ gint result = marpa_symbol_is_nulling( g, symbol_id );
if (result < 0) { croak("Invalid symbol %d", symbol_id); }
if (result) XSRETURN_YES;
XSRETURN_NO;
}
void
symbol_is_terminal_set( g, symbol_id, boolean )
Grammar *g;
Marpa_Symbol_ID symbol_id;
int boolean;
PPCODE:
marpa_symbol_is_terminal_set( g, symbol_id, (boolean ? TRUE : FALSE));
void
symbol_is_terminal( g, symbol_id )
Grammar *g;
Marpa_Symbol_ID symbol_id;
PPCODE:
{ gint result = marpa_symbol_is_terminal( g, symbol_id );
if (result < 0) { croak("Invalid symbol %d", symbol_id); }
if (result) XSRETURN_YES;
XSRETURN_NO;
}
void
symbol_is_productive_set( g, symbol_id, boolean )
Grammar *g;
Marpa_Symbol_ID symbol_id;
int boolean;
PPCODE:
marpa_symbol_is_productive_set( g, symbol_id, (boolean ? TRUE : FALSE));
void
symbol_is_productive( g, symbol_id )
Grammar *g;
Marpa_Symbol_ID symbol_id;
PPCODE:
{ gint result = marpa_symbol_is_productive( g, symbol_id );
if (result < 0) { croak("Invalid symbol %d", symbol_id); }
if (result) XSRETURN_YES;
XSRETURN_NO;
}
void
symbol_is_start( g, symbol_id )
Grammar *g;
Marpa_Symbol_ID symbol_id;
PPCODE:
{ gint result = marpa_symbol_is_start( g, symbol_id );
if (result < 0) { croak("Invalid symbol %d", symbol_id); }
if (result) XSRETURN_YES;
XSRETURN_NO;
}
Marpa_Symbol_ID
symbol_null_alias( g, symbol_id )
Grammar *g;
Marpa_Symbol_ID symbol_id;
CODE:
RETVAL = marpa_symbol_null_alias(g, symbol_id);
if (RETVAL < 0) { XSRETURN_UNDEF; }
OUTPUT:
RETVAL
Marpa_Symbol_ID
symbol_proper_alias( g, symbol_id )
Grammar *g;
Marpa_Symbol_ID symbol_id;
CODE:
RETVAL = marpa_symbol_proper_alias(g, symbol_id);
if (RETVAL < 0) { XSRETURN_UNDEF; }
OUTPUT:
RETVAL
# Rules
Marpa_Rule_ID
rule_new( g, lhs, rhs_av )
Grammar *g;
Marpa_Symbol_ID lhs;
AV *rhs_av;
PREINIT:
int length;
Marpa_Symbol_ID* rhs;
Marpa_Rule_ID new_rule_id;
PPCODE:
length = av_len(rhs_av)+1;
if (length <= 0) {
rhs = (Marpa_Symbol_ID*)NULL;
} else {
int i;
Newx(rhs, length, Marpa_Symbol_ID);
for (i = 0; i < length; i++) {
SV** elem = av_fetch(rhs_av, i, 0);
if (elem == NULL) {
Safefree(rhs);
XSRETURN_UNDEF;
} else {
rhs[i] = SvIV(*elem);
}
}
}
new_rule_id = marpa_rule_new(g, lhs, rhs, length);
Safefree(rhs);
if (new_rule_id < 0) { XSRETURN_UNDEF; }
XPUSHs( sv_2mortal( newSViv(new_rule_id) ) );
# This function invalidates any current iteration on
# the hash args. This seesm to be the way things are
# done in Perl -- in particular there seems to be no
# easy way to prevent that.
Marpa_Rule_ID
sequence_new( g, lhs, rhs, args )
Grammar *g;
Marpa_Symbol_ID lhs;
Marpa_Symbol_ID rhs;
HV *args;
PREINIT:
Marpa_Rule_ID new_rule_id;
Marpa_Symbol_ID separator = -1;
guint min = 1;
gint flags = 0;
PPCODE:
if (args) {
I32 retlen;
char* key;
SV* arg_value;
hv_iterinit(args);
while (arg_value = hv_iternextsv(args, &key, &retlen) ) {
if ((*key == 'k') && strnEQ(key, "keep", retlen)) {
if (SvTRUE(arg_value)) flags |= MARPA_KEEP_SEPARATION;
continue;
}
if ((*key == 'm') && strnEQ(key, "min", retlen)) {
gint raw_min = SvIV(arg_value);
if (raw_min < 0) {
croak("sequence_new(): min cannot be less than 0");
}
min = raw_min;
continue;
}
if ((*key == 'p') && strnEQ(key, "proper", retlen)) {
if (SvTRUE(arg_value)) flags |= MARPA_PROPER_SEPARATION;
continue;
}
if ((*key == 's') && strnEQ(key, "separator", retlen)) {
separator = SvIV(arg_value);
continue;
}
croak("unknown argument to sequence_new(): %.*s", retlen, key);
}
}
new_rule_id = marpa_sequence_new(g, lhs, rhs, separator, min, flags );
if (new_rule_id < 0) { XSRETURN_UNDEF; }
XPUSHs( sv_2mortal( newSViv(new_rule_id) ) );
Marpa_Symbol_ID
rule_lhs( g, rule_id )
Grammar *g;
Marpa_Rule_ID rule_id;
CODE:
RETVAL = marpa_rule_lhs(g, rule_id);
if (RETVAL < 0) { XSRETURN_UNDEF; }
OUTPUT:
RETVAL
Marpa_Symbol_ID
rule_rhs( g, rule_id, ix )
Grammar *g;
Marpa_Rule_ID rule_id;
unsigned int ix;
CODE:
RETVAL = marpa_rule_rh_symbol(g, rule_id, ix);
if (RETVAL < -1) { croak("Invalid call rule_rhs(%d, %u)", rule_id, ix); }
if (RETVAL == -1) { XSRETURN_UNDEF; }
OUTPUT:
RETVAL
int
rule_length( g, rule_id )
Grammar *g;
Marpa_Rule_ID rule_id;
CODE:
RETVAL = marpa_rule_length(g, rule_id);
if (RETVAL < 0) { XSRETURN_UNDEF; }
OUTPUT:
RETVAL
void
rule_is_accessible( g, rule_id )
Grammar *g;
Marpa_Rule_ID rule_id;
PPCODE:
{ gint result = marpa_rule_is_accessible( g, rule_id );
if (result < 0) { croak("Invalid rule %d", rule_id); }
if (result) XSRETURN_YES;
XSRETURN_NO;
}
void
rule_is_productive( g, rule_id )
Grammar *g;
Marpa_Rule_ID rule_id;
PPCODE:
{ gint result = marpa_rule_is_productive( g, rule_id );
if (result < 0) { croak("Invalid rule %d", rule_id); }
if (result) XSRETURN_YES;
XSRETURN_NO;
}
void
rule_is_loop( g, rule_id )
Grammar *g;
Marpa_Rule_ID rule_id;
PPCODE:
{ gint result = marpa_rule_is_loop( g, rule_id );
if (result < 0) { croak("Invalid rule %d", rule_id); }
if (result) XSRETURN_YES;
XSRETURN_NO;
}
void
rule_is_virtual_loop( g, rule_id )
Grammar *g;
Marpa_Rule_ID rule_id;
PPCODE:
{ gint result = marpa_rule_is_virtual_loop( g, rule_id );
if (result < 0) { croak("Invalid rule %d", rule_id); }
if (result) XSRETURN_YES;
XSRETURN_NO;
}
int
rule_virtual_start( g, rule_id )
Grammar *g;
Marpa_Rule_ID rule_id;
CODE:
RETVAL = marpa_virtual_start( g, rule_id );
if (RETVAL <= -2) { croak("Invalid rule %d", rule_id); }
OUTPUT:
RETVAL
int
rule_virtual_end( g, rule_id )
Grammar *g;
Marpa_Rule_ID rule_id;
CODE:
RETVAL = marpa_virtual_end( g, rule_id );
if (RETVAL <= -2) { croak("Invalid rule %d", rule_id); }
OUTPUT:
RETVAL
void
rule_is_used( g, rule_id )
Grammar *g;
Marpa_Rule_ID rule_id;
PPCODE:
{ gint result = marpa_rule_is_used( g, rule_id );
if (result < 0) { croak("Invalid rule %d", rule_id); }
if (result) XSRETURN_YES;
XSRETURN_NO;
}
void
rule_is_discard_separation( g, rule_id )
Grammar *g;
Marpa_Rule_ID rule_id;
PPCODE:
{ gint result = marpa_rule_is_discard_separation( g, rule_id );
if (result < 0) { croak("Invalid rule %d", rule_id); }
if (result) XSRETURN_YES;
XSRETURN_NO;
}
void
rule_is_virtual_lhs( g, rule_id )
Grammar *g;
Marpa_Rule_ID rule_id;
PPCODE:
{ gint result = marpa_rule_is_virtual_lhs( g, rule_id );
if (result < 0) { croak("Invalid rule %d", rule_id); }
if (result) XSRETURN_YES;
XSRETURN_NO;
}
void
rule_is_virtual_rhs( g, rule_id )
Grammar *g;
Marpa_Rule_ID rule_id;
PPCODE:
{ gint result = marpa_rule_is_virtual_rhs( g, rule_id );
if (result == -1) { croak("Invalid rule %d", rule_id); }
if (result) XSRETURN_YES;
XSRETURN_NO;
}
Marpa_Rule_ID
real_symbol_count( g, rule_id )
Grammar *g;
Marpa_Rule_ID rule_id;
CODE:
RETVAL = marpa_real_symbol_count(g, rule_id);
OUTPUT:
RETVAL
Marpa_Rule_ID
rule_original( g, rule_id )
Grammar *g;
Marpa_Rule_ID rule_id;
CODE:
RETVAL = marpa_rule_original(g, rule_id);
if (RETVAL < 0) { XSRETURN_UNDEF; }
OUTPUT:
RETVAL
Marpa_Rule_ID
semantic_equivalent( g, rule_id )
Grammar *g;
Marpa_Rule_ID rule_id;
CODE:
RETVAL = marpa_rule_semantic_equivalent(g, rule_id);
if (RETVAL < 0) { XSRETURN_UNDEF; }
OUTPUT:
RETVAL
int
AHFA_item_count( g )
Grammar *g;
CODE:
RETVAL = marpa_AHFA_item_count(g );
if (RETVAL < 0) { XSRETURN_UNDEF; }
OUTPUT:
RETVAL
Marpa_Rule_ID
AHFA_item_rule( g, item_id )
Grammar *g;
Marpa_AHFA_Item_ID item_id;
CODE:
RETVAL = marpa_AHFA_item_rule(g, item_id);
if (RETVAL < 0) { XSRETURN_UNDEF; }
OUTPUT:
RETVAL
# -1 is a valid return value, so -2 indicates an error
int
AHFA_item_position( g, item_id )
Grammar *g;
Marpa_AHFA_Item_ID item_id;
CODE:
RETVAL = marpa_AHFA_item_position(g, item_id);
if (RETVAL <= -2) { XSRETURN_UNDEF; }
OUTPUT:
RETVAL
int
AHFA_item_sort_key( g, item_id )
Grammar *g;
Marpa_AHFA_Item_ID item_id;
CODE:
RETVAL = marpa_AHFA_item_sort_key(g, item_id);
if (RETVAL < 0) { XSRETURN_UNDEF; }
OUTPUT:
RETVAL
# -1 is a valid return value, and -2 indicates an error
Marpa_Symbol_ID
AHFA_item_postdot( g, item_id )
Grammar *g;
Marpa_AHFA_Item_ID item_id;
CODE:
RETVAL = marpa_AHFA_item_postdot(g, item_id);
if (RETVAL <= -2) { XSRETURN_UNDEF; }
OUTPUT:
RETVAL
int
AHFA_state_count( g )
Grammar *g;
CODE:
RETVAL = marpa_AHFA_state_count(g );
if (RETVAL < 0) { XSRETURN_UNDEF; }
OUTPUT:
RETVAL
# In scalar context, returns the count
void
AHFA_state_items( g, AHFA_state_id )
Grammar *g;
Marpa_AHFA_State_ID AHFA_state_id;
PPCODE:
{ gint count = marpa_AHFA_state_item_count(g, AHFA_state_id);
if (count < 0) { croak("Invalid AHFA state %d", AHFA_state_id); }
if (GIMME == G_ARRAY) {
guint item_ix;
EXTEND(SP, count);
for (item_ix = 0; item_ix < count; item_ix++) {
Marpa_AHFA_Item_ID item_id
= marpa_AHFA_state_item(g, AHFA_state_id, item_ix);
PUSHs( sv_2mortal( newSViv(item_id) ) );
}
} else {
XPUSHs( sv_2mortal( newSViv(count) ) );
}
}
# In scalar context, returns the count
void
AHFA_state_transitions( g_wrapper, AHFA_state_id )
G_Wrapper *g_wrapper;
Marpa_AHFA_State_ID AHFA_state_id;
PPCODE:
{
Grammar *g = g_wrapper->g;
GArray* const gint_array = g_wrapper->gint_array;
const gint result = marpa_AHFA_state_transitions(g, AHFA_state_id, gint_array);
if (result < 0) {
croak ("Problem in AHFA_state_transitions(): %s", marpa_g_error (g));
}
if (GIMME == G_ARRAY) {
const gint count = gint_array->len;
gint ix;
for (ix = 0; ix < count; ix++) {
XPUSHs (sv_2mortal (newSViv (g_array_index (gint_array, gint, ix))));
}
} else {
XPUSHs( sv_2mortal( newSViv(gint_array->len) ) );
}
}
# -1 is a valid return value, and -2 indicates an error
Marpa_AHFA_State_ID
AHFA_state_empty_transition( g, AHFA_state_id )
Grammar *g;
Marpa_AHFA_State_ID AHFA_state_id;
CODE:
RETVAL = marpa_AHFA_state_empty_transition(g, AHFA_state_id);
if (RETVAL <= -2) { XSRETURN_UNDEF; }
OUTPUT:
RETVAL
void
AHFA_state_is_predict( g, AHFA_state_id )
Grammar *g;
Marpa_AHFA_State_ID AHFA_state_id;
PPCODE:
{ gint result = marpa_AHFA_state_is_predict( g, AHFA_state_id );
if (result < 0) { croak("Invalid AHFA state %d", AHFA_state_id); }
if (result) XSRETURN_YES;
XSRETURN_NO;
}
void
AHFA_state_leo_lhs_symbol( g, AHFA_state_id )
Grammar *g;
Marpa_AHFA_State_ID AHFA_state_id;
PPCODE:
{ gint result = marpa_AHFA_state_leo_lhs_symbol( g, AHFA_state_id );
if (result < -1) { croak("Invalid AHFA state %d", AHFA_state_id); }
if (result == -1) XSRETURN_UNDEF;
XPUSHs( sv_2mortal( newSViv(result) ) );
}
Marpa_Rule_ID
AHFA_completed_start_rule( g, AHFA_state_id )
Grammar *g;
Marpa_AHFA_State_ID AHFA_state_id;
PPCODE:
{ gint result = marpa_AHFA_completed_start_rule(g, AHFA_state_id);
if (result == -1) { XSRETURN_UNDEF; }
if (result < -1) { croak("Invalid AHFA state %d", AHFA_state_id); }
XPUSHs( sv_2mortal( newSViv(result) ) );
}
void
context( g, key )
Grammar *g;
char *key;
PREINIT:
union marpa_context_value* value;
const char *string;
PPCODE:
value = marpa_g_context_value(g, key);
if (!value) {
XSRETURN_UNDEF;
}
string = MARPA_CONTEXT_STRING_VALUE(value);
if (string) {
XPUSHs( sv_2mortal( newSVpv( string, 0 ) ) );
goto finished;
}
if (MARPA_IS_CONTEXT_INT(value)) {
gint payload = MARPA_CONTEXT_INT_VALUE(value);
XPUSHs( sv_2mortal( newSViv( payload ) ) );
} else { XSRETURN_UNDEF; }
finished: ;
char *error( g )
Grammar *g;
CODE:
RETVAL = (gchar*)marpa_g_error(g);
OUTPUT:
RETVAL
void precompute( g )
Grammar *g;
PPCODE:
if (marpa_precompute(g)) { XSRETURN_YES; }
XSRETURN_NO;
MODULE = Marpa::XS PACKAGE = Marpa::XS::Internal::R_C
void
new( class, g_sv )
char * class;
SV *g_sv;
PREINIT:
G_Wrapper *g_wrapper;
struct marpa_g* g;
IV tmp;
SV *sv;
R_Wrapper *r_wrapper;
struct marpa_r* r;
PPCODE:
if (! sv_isa(g_sv, grammar_c_class_name)) {
g_debug("Marpa::Recognizer::new grammar arg is not in class %s",
grammar_c_class_name);
}
tmp = SvIV((SV*)SvRV(g_sv));
g_wrapper = INT2PTR(G_Wrapper *, tmp);
g = g_wrapper->g;
r = marpa_r_new(g);
if (!r) { XSRETURN_UNDEF; }
marpa_r_message_callback_set( r, &xs_r_message_callback );
Newx( r_wrapper, 1, R_Wrapper );
r_wrapper->r = r;
r_wrapper->g_sv = g_sv;
r_wrapper->gint_array = g_array_new( FALSE, FALSE, sizeof(gint));
SvREFCNT_inc(g_sv);
sv = sv_newmortal();
sv_setref_pv(sv, recce_c_class_name, (void*)r_wrapper);
XPUSHs(sv);
void
DESTROY( r_wrapper )
R_Wrapper *r_wrapper;
PREINIT:
SV *g_sv;
struct marpa_r *r;
CODE:
g_sv = r_wrapper->g_sv;
r = r_wrapper->r;
{
SV *sv = marpa_r_message_callback_arg(r);
marpa_r_message_callback_arg_set( r, NULL );
if (sv) { SvREFCNT_dec(sv); }
}
g_array_free(r_wrapper->gint_array, TRUE);
marpa_r_free( r );
SvREFCNT_dec(g_sv);
Safefree( r_wrapper );
# Note the Perl callback closure
# is, in the libmarpa context, the *ARGUMENT* of the callback,
# not the callback itself.
# The libmarpa callback is a wrapper
# that calls the Perl closure.
void
message_callback_set( r_wrapper, sv )
R_Wrapper *r_wrapper;
SV *sv;
PPCODE:
{
struct marpa_r* r = r_wrapper->r;
SV *old_sv = marpa_r_message_callback_arg(r);
if (old_sv) {
SvREFCNT_dec(old_sv); }
marpa_r_message_callback_arg_set( r, sv );
SvREFCNT_inc(sv);
}
Marpa_Recognizer_ID
id( r_wrapper )
R_Wrapper *r_wrapper;
CODE:
RETVAL = marpa_r_id(r_wrapper->r);
OUTPUT:
RETVAL
# Someday replace this with a function which translates the
# error
char *error( r_wrapper )
R_Wrapper *r_wrapper;
CODE:
RETVAL = (gchar*)marpa_r_error(r_wrapper->r);
OUTPUT:
RETVAL
char *raw_error( r_wrapper )
R_Wrapper *r_wrapper;
CODE:
RETVAL = (gchar*)marpa_r_error(r_wrapper->r);
OUTPUT:
RETVAL
char *
phase( r_wrapper )
R_Wrapper *r_wrapper;
CODE:
Marpa_Phase phase = marpa_phase(r_wrapper->r);
RETVAL = "unknown";
switch(phase) {
case no_such_phase: RETVAL = "undefined"; break;
case initial_phase: RETVAL = "initial"; break;
case input_phase: RETVAL = "read"; break;
case evaluation_phase: RETVAL = "evaluation"; break;
case error_phase: RETVAL = "error"; break;
}
OUTPUT:
RETVAL
Marpa_Earleme
current_earleme( r_wrapper )
R_Wrapper *r_wrapper;
CODE:
RETVAL = marpa_current_earleme(r_wrapper->r);
OUTPUT:
RETVAL
Marpa_Earleme
furthest_earleme( r_wrapper )
R_Wrapper *r_wrapper;
CODE:
RETVAL = marpa_furthest_earleme(r_wrapper->r);
OUTPUT:
RETVAL
void
is_use_leo_set( r_wrapper, boolean )
R_Wrapper *r_wrapper;
int boolean;
PPCODE:
{
struct marpa_r *r = r_wrapper->r;
gboolean result = marpa_is_use_leo_set (r, (boolean ? TRUE : FALSE));
if (!result)
{
croak ("Problem in is_use_leo_set(): %s", marpa_r_error (r));
}
}
XSRETURN_YES;
void
is_use_leo( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
gint boolean = marpa_is_use_leo( r );
if (boolean < 0) {
croak("Problem in is_use_leo(): %s", marpa_r_error(r)); }
if (boolean) XSRETURN_YES;
XSRETURN_NO;
}
void
is_exhausted( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
gint boolean = marpa_is_exhausted( r );
if (boolean < 0) {
croak("Problem in is_exhausted(): %s", marpa_r_error(r)); }
if (boolean) XSRETURN_YES;
XSRETURN_NO;
}
void
start_input( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ gboolean result = marpa_start_input(r_wrapper->r);
if (result) XSRETURN_YES;
}
XSRETURN_NO;
# current earleme on success -- return that directly
# -1 means rejected because unexpected -- return undef
# -3 means rejected as duplicate -- return that directly
# because Perl can do better error message for this
# -2 means some other failure -- call croak
void
alternative( r_wrapper, symbol_id, slot, length )
R_Wrapper *r_wrapper;
Marpa_Symbol_ID symbol_id;
int slot;
int length;
PPCODE:
{
struct marpa_r *r = r_wrapper->r;
gint result =
marpa_alternative (r, symbol_id, GINT_TO_POINTER (slot), length);
if (result == -1)
{
XSRETURN_UNDEF;
}
if (result < 0 && result != -3)
{
croak ("Invalid alternative: %s", marpa_r_error (r));
}
XPUSHs (sv_2mortal (newSViv (result)));
}
void
earley_item_warning_threshold_set( r_wrapper, too_many_earley_items )
R_Wrapper *r_wrapper;
unsigned int too_many_earley_items;
PPCODE:
{ gboolean result = marpa_earley_item_warning_threshold_set(r_wrapper->r, too_many_earley_items);
if (result) XSRETURN_YES;
}
XSRETURN_NO;
void
too_many_earley_items( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ guint too_many_earley_items = marpa_earley_item_warning_threshold( r_wrapper->r );
XPUSHs( sv_2mortal( newSViv(too_many_earley_items) ) );
}
void
latest_earley_set( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{
struct marpa_r *r = r_wrapper->r;
gint latest_earley_set = marpa_latest_earley_set(r);
if (latest_earley_set < 0)
{
croak ("Problem with r->latest_earley_set(): %s",
marpa_r_error (r));
}
XPUSHs (sv_2mortal (newSViv (latest_earley_set)));
}
void
earley_set_size( r_wrapper, set_ordinal )
R_Wrapper *r_wrapper;
Marpa_Earley_Set_ID set_ordinal;
PPCODE:
{
struct marpa_r *r = r_wrapper->r;
gint earley_set_size = marpa_earley_set_size (r, set_ordinal);
if (earley_set_size < 0) {
croak ("Problem in r->earley_set_size(): %s", marpa_r_error (r));
}
XPUSHs (sv_2mortal (newSViv (earley_set_size)));
}
void
earley_set_trace( r_wrapper, set_ordinal )
R_Wrapper *r_wrapper;
Marpa_Earley_Set_ID set_ordinal;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
Marpa_AHFA_State_ID result = marpa_earley_set_trace(
r, set_ordinal );
if (result == -1) { XSRETURN_UNDEF; }
if (result < 0) { croak("problem with r->earley_set_trace: %s", marpa_r_error(r)); }
XPUSHs( sv_2mortal( newSViv(result) ) );
}
void
earley_item_trace( r_wrapper, item_ordinal )
R_Wrapper *r_wrapper;
Marpa_Earley_Item_ID item_ordinal;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
Marpa_AHFA_State_ID result = marpa_earley_item_trace(
r, item_ordinal);
if (result == -1) { XSRETURN_UNDEF; }
if (result < 0) { croak("problem with r->earley_item_trace: %s", marpa_r_error(r)); }
XPUSHs( sv_2mortal( newSViv(result) ) );
}
void
old_earley_item_trace( r_wrapper, origin, ahfa_id )
R_Wrapper *r_wrapper;
Marpa_Earleme origin;
Marpa_AHFA_State_ID ahfa_id;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
Marpa_AHFA_State_ID result = marpa_old_earley_item_trace(r, origin, ahfa_id);
if (result == -1) { XSRETURN_UNDEF; }
if (result < 0) { croak("Trace earley item problem: %s", marpa_r_error(r)); }
XPUSHs( sv_2mortal( newSViv(result) ) );
}
void
earley_item_origin( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{
struct marpa_r *r = r_wrapper->r;
gint origin_earleme = marpa_earley_item_origin (r);
if (origin_earleme < 0)
{
croak ("Problem with r->earley_item_origin(): %s",
marpa_r_error (r));
}
XPUSHs (sv_2mortal (newSViv (origin_earleme)));
}
void
first_token_link_trace( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
gint token_id = marpa_first_token_link_trace(r);
if (token_id <= -2) { croak("Trace first token link problem: %s", marpa_r_error(r)); }
if (token_id == -1) { XSRETURN_UNDEF; }
XPUSHs( sv_2mortal( newSViv(token_id) ) );
}
void
next_token_link_trace( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
gint token_id = marpa_next_token_link_trace(r);
if (token_id <= -2) { croak("Trace next token link problem: %s", marpa_r_error(r)); }
if (token_id == -1) { XSRETURN_UNDEF; }
XPUSHs( sv_2mortal( newSViv(token_id) ) );
}
void
first_completion_link_trace( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
gint AHFA_state_id = marpa_first_completion_link_trace(r);
if (AHFA_state_id <= -2) { croak("Trace first completion link problem: %s", marpa_r_error(r)); }
if (AHFA_state_id == -1) { XSRETURN_UNDEF; }
XPUSHs( sv_2mortal( newSViv(AHFA_state_id) ) );
}
void
next_completion_link_trace( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
gint AHFA_state_id = marpa_next_completion_link_trace(r);
if (AHFA_state_id <= -2) { croak("Trace next completion link problem: %s", marpa_r_error(r)); }
if (AHFA_state_id == -1) { XSRETURN_UNDEF; }
XPUSHs( sv_2mortal( newSViv(AHFA_state_id) ) );
}
void
first_leo_link_trace( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
gint AHFA_state_id = marpa_first_leo_link_trace(r);
if (AHFA_state_id <= -2) { croak("Trace first completion link problem: %s", marpa_r_error(r)); }
if (AHFA_state_id == -1) { XSRETURN_UNDEF; }
XPUSHs( sv_2mortal( newSViv(AHFA_state_id) ) );
}
void
next_leo_link_trace( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
gint AHFA_state_id = marpa_next_leo_link_trace(r);
if (AHFA_state_id <= -2) { croak("Trace next completion link problem: %s", marpa_r_error(r)); }
if (AHFA_state_id == -1) { XSRETURN_UNDEF; }
XPUSHs( sv_2mortal( newSViv(AHFA_state_id) ) );
}
void
source_predecessor_state( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
gint state_id = marpa_source_predecessor_state(r);
if (state_id <= -2) { croak("Problem finding trace source predecessor state: %s", marpa_r_error(r)); }
if (state_id == -1) { XSRETURN_UNDEF; }
XPUSHs( sv_2mortal( newSViv(state_id) ) );
}
void
source_leo_transition_symbol( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
gint symbol_id = marpa_source_leo_transition_symbol(r);
if (symbol_id <= -2) { croak("Problem finding trace source leo transition symbol: %s", marpa_r_error(r)); }
if (symbol_id == -1) { XSRETURN_UNDEF; }
XPUSHs( sv_2mortal( newSViv(symbol_id) ) );
}
void
source_middle( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
gint middle = marpa_source_middle(r);
if (middle <= -2) { croak("Problem with r->source_middle(): %s", marpa_r_error(r)); }
if (middle == -1) { XSRETURN_UNDEF; }
XPUSHs( sv_2mortal( newSViv(middle) ) );
}
# In this interface, the value of a token is always an integer representing the
# "slot" where the real value resides.
void
source_value( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
gpointer value;
gboolean result = marpa_source_token_value(r, &value);
if (!result) { croak("Problem finding trace source token value: %s", marpa_r_error(r)); }
XPUSHs( sv_2mortal( newSViv(GPOINTER_TO_INT(value)) ) );
}
void
first_postdot_item_trace( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
gint postdot_symbol_id = marpa_first_postdot_item_trace(r);
if (postdot_symbol_id <= -2) { croak("Trace first postdot item problem: %s", marpa_r_error(r)); }
if (postdot_symbol_id == -1) { XSRETURN_UNDEF; }
XPUSHs( sv_2mortal( newSViv(postdot_symbol_id) ) );
}
void
next_postdot_item_trace( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
gint postdot_symbol_id = marpa_next_postdot_item_trace(r);
if (postdot_symbol_id <= -2) { croak("Trace next postdot item problem: %s", marpa_r_error(r)); }
if (postdot_symbol_id == -1) { XSRETURN_UNDEF; }
XPUSHs( sv_2mortal( newSViv(postdot_symbol_id) ) );
}
void
postdot_symbol_trace( r, symid )
Recce *r;
Marpa_Symbol_ID symid;
PPCODE:
{
gint postdot_symbol_id = marpa_postdot_symbol_trace(r, symid);
if (postdot_symbol_id == -1) { XSRETURN_UNDEF; }
if (postdot_symbol_id <= 0) { croak("Problem in r->postdot_symbol_trace: %s", marpa_r_error(r)); }
XPUSHs( sv_2mortal( newSViv(postdot_symbol_id) ) );
}
void
leo_base_state( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{
struct marpa_r *r = r_wrapper->r;
gint leo_base_state = marpa_leo_base_state (r);
if (leo_base_state == -1) { XSRETURN_UNDEF; }
if (leo_base_state < 0) {
croak ("Problem in r->leo_base_state(): %s", marpa_r_error (r));
}
XPUSHs (sv_2mortal (newSViv (leo_base_state)));
}
void
leo_base_origin( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{
struct marpa_r *r = r_wrapper->r;
gint leo_base_origin = marpa_leo_base_origin (r);
if (leo_base_origin == -1) { XSRETURN_UNDEF; }
if (leo_base_origin < 0) {
croak ("Problem in r->leo_base_origin(): %s", marpa_r_error (r));
}
XPUSHs (sv_2mortal (newSViv (leo_base_origin)));
}
void
leo_expansion_ahfa( r )
Recce *r;
PPCODE:
{
gint leo_expansion_ahfa = marpa_leo_expansion_ahfa(r);
if (leo_expansion_ahfa == -1) { XSRETURN_UNDEF; }
if (leo_expansion_ahfa < 0) {
croak ("Problem in r->leo_expansion_ahfa(): %s", marpa_r_error (r));
}
XPUSHs (sv_2mortal (newSViv (leo_expansion_ahfa)));
}
void
trace_earley_set( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{
struct marpa_r *r = r_wrapper->r;
gint trace_earley_set = marpa_trace_earley_set (r);
if (trace_earley_set < 0) {
croak ("Problem in r->trace_earley_set(): %s", marpa_r_error (r));
}
XPUSHs (sv_2mortal (newSViv (trace_earley_set)));
}
void
postdot_item_symbol( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{
struct marpa_r *r = r_wrapper->r;
gint postdot_item_symbol = marpa_postdot_item_symbol (r);
if (postdot_item_symbol < 0) {
croak ("Problem in r->postdot_item_symbol(): %s", marpa_r_error (r));
}
XPUSHs (sv_2mortal (newSViv (postdot_item_symbol)));
}
void
leo_predecessor_symbol( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{
struct marpa_r *r = r_wrapper->r;
gint leo_predecessor_symbol = marpa_leo_predecessor_symbol (r);
if (leo_predecessor_symbol == -1) { XSRETURN_UNDEF; }
if (leo_predecessor_symbol < 0) {
croak ("Problem in r->leo_predecessor_symbol(): %s", marpa_r_error (r));
}
XPUSHs (sv_2mortal (newSViv (leo_predecessor_symbol)));
}
void
terminals_expected( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
GArray* terminal_ids = r_wrapper->gint_array;
gint count = marpa_terminals_expected(r, terminal_ids);
if (count < 0) {
croak ("Problem in r->terminals_expected(): %s", marpa_r_error (r));
}
if (GIMME == G_ARRAY) {
int i;
EXTEND(SP, count);
for (i = 0; i < count; i++) {
PUSHs (sv_2mortal (newSViv (g_array_index (terminal_ids, gint, i))));
}
} else {
XPUSHs( sv_2mortal( newSViv(count) ) );
}
}
void
earleme_complete( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
Marpa_Earleme result = marpa_earleme_complete(r);
if (result < 0) {
croak ("Problem in r->earleme_complete(): %s", marpa_r_error (r));
}
XPUSHs( sv_2mortal( newSViv(result) ) );
}
void
leo_completion_expand( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
gint result = marpa_leo_completion_expand(r);
if (result == -1) { XSRETURN_UNDEF; }
if (result < 0) {
croak ("Problem in r->leo_completion_expand(): %s", marpa_r_error (r));
}
XPUSHs( sv_2mortal( newSViv(result) ) );
}
void
earleme( r_wrapper, ordinal )
R_Wrapper *r_wrapper;
Marpa_Earley_Set_ID ordinal;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
gint result = marpa_earleme(r, ordinal);
if (result == -1) { XSRETURN_UNDEF; }
if (result < 0) {
croak ("Problem in r->earleme(): %s", marpa_r_error (r));
}
XPUSHs( sv_2mortal( newSViv(result) ) );
}
void
eval_setup( r_wrapper, rule_id, ordinal )
R_Wrapper *r_wrapper;
Marpa_Rule_ID rule_id;
Marpa_Earley_Set_ID ordinal;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
gint result = marpa_bocage_new(r, rule_id, ordinal);
if (result == -1) { XSRETURN_UNDEF; }
if (result < 0) {
croak ("Problem in r->eval_setup(): %s", marpa_r_error (r));
}
XPUSHs( sv_2mortal( newSViv(result) ) );
}
void
eval_clear( r_wrapper )
R_Wrapper *r_wrapper;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
gint result = marpa_bocage_free(r);
if (result < 0) {
croak ("Problem in r->eval_clear(): %s", marpa_r_error (r));
}
XPUSHs( sv_2mortal( newSViv(result) ) );
}
# In scalar context, returns the count
void
or_node( r_wrapper, or_node_id )
R_Wrapper *r_wrapper;
Marpa_Or_Node_ID or_node_id;
PPCODE:
{ struct marpa_r* r = r_wrapper->r;
const gint data_count = 6;
gint data[data_count];
gint result = marpa_or_node(r, or_node_id, data);
if (result == -1) { XSRETURN_UNDEF; }
if (result <= -2) { croak("Problem in r->or_node(): %s", marpa_r_error(r)); }
{
guint ix;
EXTEND(SP, data_count);
for (ix = 0; ix < data_count; ix++) {
PUSHs( sv_2mortal( newSViv(data[ix]) ) );
}
}
}
BOOT:
gperl_handle_logs_for(G_LOG_DOMAIN);