implemented @pragma startup ...

This commit is contained in:
hyung-hwan 2020-01-11 05:24:07 +00:00
parent d5cb858e04
commit cf741c1525
7 changed files with 185 additions and 27 deletions

View File

@ -1204,9 +1204,20 @@ static HAWK_INLINE int execute_hawk (int argc, hawk_bch_t* argv[])
set_intr_run ();
#if 0
retv = arg.call?
hawk_rtx_callwithbcstrarr(rtx, arg.call, (const hawk_bch_t**)arg.icf.ptr, arg.icf.size):
hawk_rtx_loop(rtx);
hawk_rtx_loop(rtx); /* this doesn't support @pragma startup ... */
#else
/* note about @pragma startup ...
* hawk_rtx_execwithbcstrarr() invokes the specified function is @pragma startup ... is set
* in the source code. becuase arg.icf.ptr has been passed to hawk_rtx_openstdwithbcstr() when
* arg.call is HAWK_NULL, arg.icf.ptr serves as parameters to the startup function and
* affects input consoles */
retv = arg.call?
hawk_rtx_callwithbcstrarr(rtx, arg.call, (const hawk_bch_t**)arg.icf.ptr, arg.icf.size):
hawk_rtx_execwithbcstrarr(rtx, (const hawk_bch_t**)arg.icf.ptr, arg.icf.size);
#endif
unset_intr_run ();

View File

@ -239,6 +239,7 @@ struct hawk_t
{
int trait;
hawk_oow_t rtx_stack_limit;
hawk_ooch_t startup[128];
} pragma;
/* function calls */

View File

@ -379,8 +379,9 @@ void hawk_clear (hawk_t* awk)
awk->parse.depth.loop = 0;
awk->parse.depth.expr = 0;
awk->parse.depth.incl = 0;
awk->parse.pragma.trait = (awk->opt.trait & HAWK_IMPLICIT);
awk->parse.pragma.trait = (awk->opt.trait & HAWK_IMPLICIT); /* implicit on if you didn't mask it off in awk->opt.trait with hawk_setopt */
awk->parse.pragma.rtx_stack_limit = 0;
awk->parse.pragma.startup[0] = '\0';
awk->parse.incl_hist.count =0;

View File

@ -2198,12 +2198,45 @@ HAWK_EXPORT hawk_val_t* hawk_rtx_callwithbcstrarr (
hawk_oow_t nargs /**< the number of arguments */
);
HAWK_EXPORT hawk_val_t* hawk_rtx_callwithooucstrarr (
hawk_rtx_t* rtx, /**< runtime context */
const hawk_ooch_t* name, /**< function name */
const hawk_uch_t* args[], /**< arguments to the function */
hawk_oow_t nargs /**< the number of arguments */
);
HAWK_EXPORT hawk_val_t* hawk_rtx_callwithoobcstrarr (
hawk_rtx_t* rtx, /**< runtime context */
const hawk_ooch_t* name, /**< function name */
const hawk_bch_t* args[], /**< arguments to the function */
hawk_oow_t nargs /**< the number of arguments */
);
/**
* The hawk_rtx_execwithucstrarr() function calls the starup function
* if the @pragma startup directive is found in a top-level source
* code or run hawk_rtx_loop() to enter the standard pattern loop
* otherwise */
HAWK_EXPORT hawk_val_t* hawk_rtx_execwithucstrarr (
hawk_rtx_t* rtx, /**< runtime context */
const hawk_uch_t* args[], /**< arguments to the function */
hawk_oow_t nargs /**< the number of arguments */
);
HAWK_EXPORT hawk_val_t* hawk_rtx_execwithbcstrarr (
hawk_rtx_t* rtx, /**< runtime context */
const hawk_bch_t* args[], /**< arguments to the function */
hawk_oow_t nargs /**< the number of arguments */
);
#if defined(HAWK_OOCH_IS_UCH)
# define hawk_rtx_callwithoocstr hawk_rtx_callwithucstr
# define hawk_rtx_callwithoocstrarr hawk_rtx_callwithucstrarr
# define hawk_rtx_execwithoocstrarr hawk_rtx_execwithucstrarr
#else
# define hawk_rtx_callwithoocstr hawk_rtx_callwithbcstr
# define hawk_rtx_callwithoocstrarr hawk_rtx_callwithbcstrarr
# define hawk_rtx_execwithoocstrarr hawk_rtx_execwithbcstrarr
#endif
/**

View File

@ -902,6 +902,7 @@ oops:
static int parse_progunit (hawk_t* awk)
{
/*
@pragma ....
@include "xxxx"
@global xxx, xxxx;
BEGIN { action }
@ -1016,6 +1017,31 @@ static int parse_progunit (hawk_t* awk)
if (sl > awk->parse.pragma.rtx_stack_limit) awk->parse.pragma.rtx_stack_limit = sl;
}
else if (hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("startup")) == 0)
{
if (get_token(awk) <= -1) return -1;
if (!MATCH(awk, TOK_IDENT))
{
hawk_seterrfmt (awk, &awk->ptok.loc, HAWK_EIDENT, HAWK_T("function name expected for 'startup'"));
return -1;
}
if (HAWK_OOECS_LEN(awk->tok.name) >= HAWK_COUNTOF(awk->parse.pragma.startup))
{
hawk_seterrfmt (awk, &awk->tok.loc, HAWK_EFUNNAM, HAWK_T("startup function name too long"));
return -1;
}
if (awk->sio.inp == &awk->sio.arg)
{
/* only the top level source */
if (awk->parse.pragma.startup[0] == '\0')
{
/* honor the first encounter only */
hawk_copy_oochars_to_oocstr (awk->parse.pragma.startup, HAWK_COUNTOF(awk->parse.pragma.startup), HAWK_OOECS_PTR(awk->tok.name), HAWK_OOECS_LEN(awk->tok.name));
}
}
}
else
{
hawk_seterrfmt (awk, &awk->ptok.loc, HAWK_EIDENT, HAWK_T("unknown @pragma identifier - %.*js"), name.len, name.ptr);

View File

@ -1460,21 +1460,45 @@ static hawk_val_t* run_bpae_loop (hawk_rtx_t* rtx)
/* start the BEGIN-pattern block-END loop */
hawk_val_t* hawk_rtx_loop (hawk_rtx_t* rtx)
{
if (rtx->awk->parse.pragma.startup[0] != '\0')
{
/* @pragma startup xxxx specified.
* divert hawk_rtx_loop() to call the specified function */
return hawk_rtx_callwithoocstrarr(rtx, rtx->awk->parse.pragma.startup, HAWK_NULL, 0); /* TODO: pass argument */
}
else
{
hawk_val_t* retv = HAWK_NULL;
rtx->exit_level = EXIT_NONE;
if (enter_stack_frame (rtx) == 0)
if (enter_stack_frame(rtx) == 0)
{
retv = run_bpae_loop (rtx);
retv = run_bpae_loop(rtx);
exit_stack_frame (rtx);
}
/* reset the exit level */
rtx->exit_level = EXIT_NONE;
return retv;
}
}
hawk_val_t* hawk_rtx_execwithucstrarr (hawk_rtx_t* rtx, const hawk_uch_t* args[], hawk_oow_t nargs)
{
return (rtx->awk->parse.pragma.startup[0] != '\0')?
hawk_rtx_callwithooucstrarr(rtx, rtx->awk->parse.pragma.startup, args, nargs):
hawk_rtx_loop(rtx);
}
hawk_val_t* hawk_rtx_execwithbcstrarr (hawk_rtx_t* rtx, const hawk_bch_t* args[], hawk_oow_t nargs)
{
return (rtx->awk->parse.pragma.startup[0] != '\0')?
hawk_rtx_callwithoobcstrarr(rtx, rtx->awk->parse.pragma.startup, args, nargs):
hawk_rtx_loop(rtx);
}
/* find an AWK function by name */
static hawk_fun_t* find_fun (hawk_rtx_t* rtx, const hawk_ooch_t* name)
{
@ -1548,7 +1572,7 @@ hawk_val_t* hawk_rtx_callfun (hawk_rtx_t* rtx, hawk_fun_t* fun, hawk_val_t* args
{
/* this function contains pass-by-reference parameters.
* i don't support the call here as it requires variables */
hawk_rtx_seterrfmt (rtx, HAWK_EPERM, HAWK_NULL, HAWK_T("not allowed to call '%.*js' with pass-by-reference parameters"), fun->name.len, fun->name.ptr);
hawk_rtx_seterrfmt (rtx, HAWK_NULL, HAWK_EPERM, HAWK_T("not allowed to call '%.*js' with pass-by-reference parameters"), fun->name.len, fun->name.ptr);
return HAWK_NULL;
}
#endif
@ -1680,6 +1704,68 @@ oops:
return ret;
}
hawk_val_t* hawk_rtx_callwithooucstrarr (hawk_rtx_t* rtx, const hawk_ooch_t* name, const hawk_uch_t* args[], hawk_oow_t nargs)
{
hawk_oow_t i;
hawk_val_t** v, * ret;
v = hawk_rtx_allocmem(rtx, HAWK_SIZEOF(*v) * nargs);
if (!v) return HAWK_NULL;
for (i = 0; i < nargs; i++)
{
v[i] = hawk_rtx_makestrvalwithucstr(rtx, args[i]);
if (!v[i])
{
ret = HAWK_NULL;
goto oops;
}
hawk_rtx_refupval (rtx, v[i]);
}
ret = hawk_rtx_callwithoocstr(rtx, name, v, nargs);
oops:
while (i > 0)
{
hawk_rtx_refdownval (rtx, v[--i]);
}
hawk_rtx_freemem (rtx, v);
return ret;
}
hawk_val_t* hawk_rtx_callwithoobcstrarr (hawk_rtx_t* rtx, const hawk_ooch_t* name, const hawk_bch_t* args[], hawk_oow_t nargs)
{
hawk_oow_t i;
hawk_val_t** v, * ret;
v = hawk_rtx_allocmem(rtx, HAWK_SIZEOF(*v) * nargs);
if (!v) return HAWK_NULL;
for (i = 0; i < nargs; i++)
{
v[i] = hawk_rtx_makestrvalwithbcstr(rtx, args[i]);
if (!v[i])
{
ret = HAWK_NULL;
goto oops;
}
hawk_rtx_refupval (rtx, v[i]);
}
ret = hawk_rtx_callwithoocstr(rtx, name, v, nargs);
oops:
while (i > 0)
{
hawk_rtx_refdownval (rtx, v[--i]);
}
hawk_rtx_freemem (rtx, v);
return ret;
}
static int run_pblocks (hawk_rtx_t* rtx)
{
int n;

View File

@ -350,22 +350,22 @@ static int handle_cmdline (MyHawk& awk, int argc, hawk_bch_t* argv[], cmdline_t*
}
static int hawk_main (MyHawk& awk, int argc, hawk_bch_t* argv[])
static int hawk_main (MyHawk& hawk, int argc, hawk_bch_t* argv[])
{
MyHawk::Run* run;
cmdline_t cmdline;
int n;
awk.setTrait (awk.getTrait() | HAWK_FLEXMAP | HAWK_RWPIPE | HAWK_NEXTOFILE);
hawk.setTrait (hawk.getTrait() | HAWK_FLEXMAP | HAWK_RWPIPE | HAWK_NEXTOFILE);
// ARGV[0]
if (awk.addArgument(HAWK_T("hawk25")) <= -1)
if (hawk.addArgument(HAWK_T("hawk51")) <= -1)
{
print_error (awk);
print_error (hawk);
return -1;
}
if ((n = handle_cmdline(awk, argc, argv, &cmdline)) <= 0) return n;
if ((n = handle_cmdline(hawk, argc, argv, &cmdline)) <= 0) return n;
MyHawk::Source* in, * out;
MyHawk::SourceString in_str(cmdline.ins);
@ -374,10 +374,10 @@ static int hawk_main (MyHawk& awk, int argc, hawk_bch_t* argv[])
in = (cmdline.ins)? (MyHawk::Source*)&in_str: (MyHawk::Source*)&in_file;
out = (cmdline.outf)? (MyHawk::Source*)&out_file: &MyHawk::Source::NONE;
run = awk.parse (*in, *out);
run = hawk.parse (*in, *out);
if (run == HAWK_NULL)
{
print_error (awk);
print_error (hawk);
return -1;
}
@ -386,29 +386,29 @@ static int hawk_main (MyHawk& awk, int argc, hawk_bch_t* argv[])
MyHawk::Value fs (run);
if (fs.setStr(cmdline.fs) <= -1)
{
print_error (awk);
print_error (hawk);
return -1;
}
if (awk.setGlobal(HAWK_GBL_FS, fs) <= -1)
if (hawk.setGlobal(HAWK_GBL_FS, fs) <= -1)
{
print_error (awk);
print_error (hawk);
return -1;
}
}
if (cmdline.outc)
{
if (awk.addConsoleOutput(cmdline.outc) <= -1)
if (hawk.addConsoleOutput(cmdline.outc) <= -1)
{
print_error (awk);
print_error (hawk);
return -1;
}
}
MyHawk::Value ret;
if (awk.loop(&ret) <= -1)
if (hawk.loop(&ret) <= -1)
{
print_error (awk);
print_error (hawk);
return -1;
}