Anarres-Mud-Driver
view release on metacpan or search on metacpan
Compiler/parser.y view on Meta::CPAN
strcpy(buf, _AMD "::Compiler::Node::");
strcat(buf, type);
class = sv_2mortal(newSVpv(buf, 0));
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(class);
/* This unconventional formatting pushes the first few of argN
* which are not NULL. */
if (arg0) { XPUSHs(arg0);
if (arg1) { XPUSHs(arg1);
if (arg2) { XPUSHs(arg2);
if (arg3) { XPUSHs(arg3);
if (arg4) { XPUSHs(arg4);
} } } } }
if (rest) {
len = av_len(rest);
for (i = 0; i <= len; i++) {
svp = av_fetch(rest, i, FALSE);
if (svp)
XPUSHs(*svp);
}
}
PUTBACK;
count = call_method("new", G_SCALAR);
SPAGAIN;
if (count != 1)
croak("Didn't get a return value from constructing %s\n", type);
node = POPs;
PUTBACK;
SvREFCNT_inc(node);
FREETMPS;
LEAVE;
// sv_2mortal(node); /* This segfaults it at the moment. */
return node;
}
/* We have to make sure that 'type' coming into here is PV not RV */
static SV *
yyparse_type(const char *type, SV *stars)
{
static SV *class = NULL;
SV *sv;
dSP;
int count;
SV *node;
if (!class) {
class = newSVpv(_AMD "::Compiler::Type", 0);
}
// fprintf(stderr, "Type is %s, stars is %s\n", type, SvPV_nolen(stars));
/* XXX It's quite likely that we own the only ref to 'stars' here.
*/
sv = newSVsv(stars);
sv_catpv(sv, type);
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(class);
XPUSHs(sv); /* Does this get freed? */
PUTBACK;
count = call_method("new", G_SCALAR);
SPAGAIN;
if (count != 1)
croak("Didn't get a return value from constructing Type\n");
node = POPs;
PUTBACK;
SvREFCNT_inc(node);
FREETMPS;
LEAVE;
/* In the outer scope. Let's hope this doesn't get dested. */
sv_2mortal(node);
return node;
#if 0
return sv_bless(newRV_noinc(stars),
gv_stashpv(_AMD "::Compiler::Type", TRUE));
#endif
}
/* Can I pass mods as a primitive integer, and not bother if they
* are zero? This applies to functions as well. */
static SV *
yyparse_variable(SV *name, const char *type, SV *stars, SV *mods)
{
static SV *class = NULL;
static SV *k_type = NULL;
static SV *k_name = NULL;
static SV *k_flags = NULL;
SV *newtype;
dSP;
int count;
SV *node;
if (!class) {
class = newSVpv(_AMD "::Program::Variable", 0);
k_type = newSVpv("Type", 0);
k_name = newSVpv("Name", 0);
k_flags = newSVpv("Flags", 0);
}
newtype = yyparse_type(type, stars);
Compiler/parser.y view on Meta::CPAN
char buf[64];
snprintf(buf, 64, "%d", $1);
$$ = newSVpv(buf, 0);
}
;
string
: L_STRING
/* default */
| string L_STRING
{
sv_catpv($1, SvPVX($2));
SvREFCNT_dec($2);
$$ = $1;
}
;
integer
: L_INTEGER
| L_CHARACTER
;
array
: L_ARRAY_START opt_arg_list_comma L_ARRAY_END
{
$$ = $2;
}
;
mapping
: L_MAP_START opt_assoc_arg_list_comma L_MAP_END
{
/* This doesn't expand the pairs into a single list.
* There is a hack elsewhere. */
$$ = $2;
}
;
/* Also things like (: foo :) ? */
closure
: L_FUNCTION_START list_exp L_FUNCTION_END
{
$$ = $2;
}
;
%%
const char *
yytokname(int i)
{
return yytname[YYTRANSLATE(i)];
}
int
yyparser_parse(SV *program, const char *str)
{
amd_parse_param_t param;
int ret;
// fprintf(stderr, "Start of yyparser_parse\n");
// fflush(stderr);
memset(¶m, 0, sizeof(param));
param.program = program;
param.symtab = newHV();
yylex_init(str);
#if YYDEBUG != 0
yydebug = 1;
#endif
ret = yyparse((void *)(¶m));
/* Delete the HV but not the contents. */
hv_undef(param.symtab);
return ret;
}
( run in 2.651 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )