From 7ab7d14036d7bec95d9acaf4d0625a01bcb6e7c7 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Tue, 20 Jun 2006 15:27:50 +0000 Subject: [PATCH] *** empty log message *** --- ase/awk/awk.c | 20 ++++---- ase/awk/awk.h | 8 ++- ase/awk/awk_i.h | 4 +- ase/awk/func.c | 30 +++++++---- ase/awk/func.h | 6 +-- ase/awk/parse.c | 42 ++++++++-------- ase/awk/run.c | 129 +++++++++++++++++++++++++++++++++--------------- ase/awk/tree.h | 6 +-- ase/awk/val.h | 3 +- 9 files changed, 155 insertions(+), 93 deletions(-) diff --git a/ase/awk/awk.c b/ase/awk/awk.c index ecb5e112..eb384b08 100644 --- a/ase/awk/awk.c +++ b/ase/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c,v 1.54 2006-06-19 15:43:27 bacon Exp $ + * $Id: awk.c,v 1.55 2006-06-20 15:27:50 bacon Exp $ */ #include @@ -9,7 +9,7 @@ #include #endif -static void __free_func (void* awk, void* func); +static void __free_afn (void* awk, void* afn); xp_awk_t* xp_awk_open (void) { @@ -27,7 +27,7 @@ xp_awk_t* xp_awk_open (void) /* TODO: initial map size?? */ if (xp_awk_map_open ( - &awk->tree.funcs, awk, 256, __free_func) == XP_NULL) + &awk->tree.afns, awk, 256, __free_afn) == XP_NULL) { xp_str_close (&awk->token.name); xp_free (awk); @@ -37,7 +37,7 @@ xp_awk_t* xp_awk_open (void) if (xp_awk_tab_open (&awk->parse.globals) == XP_NULL) { xp_str_close (&awk->token.name); - xp_awk_map_close (&awk->tree.funcs); + xp_awk_map_close (&awk->tree.afns); xp_free (awk); return XP_NULL; } @@ -45,7 +45,7 @@ xp_awk_t* xp_awk_open (void) if (xp_awk_tab_open (&awk->parse.locals) == XP_NULL) { xp_str_close (&awk->token.name); - xp_awk_map_close (&awk->tree.funcs); + xp_awk_map_close (&awk->tree.afns); xp_awk_tab_close (&awk->parse.globals); xp_free (awk); return XP_NULL; @@ -54,7 +54,7 @@ xp_awk_t* xp_awk_open (void) if (xp_awk_tab_open (&awk->parse.params) == XP_NULL) { xp_str_close (&awk->token.name); - xp_awk_map_close (&awk->tree.funcs); + xp_awk_map_close (&awk->tree.afns); xp_awk_tab_close (&awk->parse.globals); xp_awk_tab_close (&awk->parse.locals); xp_free (awk); @@ -96,7 +96,7 @@ int xp_awk_close (xp_awk_t* awk) if (xp_awk_detsrc(awk) == -1) return -1; - xp_awk_map_close (&awk->tree.funcs); + xp_awk_map_close (&awk->tree.afns); xp_awk_tab_close (&awk->parse.globals); xp_awk_tab_close (&awk->parse.locals); xp_awk_tab_close (&awk->parse.params); @@ -121,7 +121,7 @@ void xp_awk_clear (xp_awk_t* awk) /* clear parse trees */ awk->tree.nglobals = 0; - xp_awk_map_clear (&awk->tree.funcs); + xp_awk_map_clear (&awk->tree.afns); if (awk->tree.begin != XP_NULL) { @@ -208,9 +208,9 @@ int xp_awk_detsrc (xp_awk_t* awk) return 0; } -static void __free_func (void* owner, void* func) +static void __free_afn (void* owner, void* afn) { - xp_awk_func_t* f = (xp_awk_func_t*)func; + xp_awk_afn_t* f = (xp_awk_afn_t*)afn; /* f->name doesn't have to be freed */ /*xp_free (f->name);*/ diff --git a/ase/awk/awk.h b/ase/awk/awk.h index d0464a1b..49f1332f 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.66 2006-06-19 09:08:50 bacon Exp $ + * $Id: awk.h,v 1.67 2006-06-20 15:27:50 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -14,6 +14,7 @@ typedef xp_ssize_t (*xp_awk_io_t) ( int cmd, void* arg, xp_char_t* data, xp_size_t count); typedef struct xp_awk_extio_t xp_awk_extio_t; +typedef struct xp_awk_val_t xp_awk_val_t; struct xp_awk_extio_t { @@ -153,6 +154,11 @@ xp_size_t xp_awk_getsrcline (xp_awk_t* awk); int xp_awk_parse (xp_awk_t* awk); int xp_awk_run (xp_awk_t* awk, xp_awk_io_t txtio, void* txtio_arg); +/* functions to access internal stack structure */ +xp_size_t xp_awk_getnargs (void* run); +xp_awk_val_t* xp_awk_getarg (void* run, xp_size_t idx); +void xp_awk_setretval (void* run, xp_awk_val_t* val); + /* utility functions exported by awk.h */ xp_long_t xp_awk_strtolong ( const xp_char_t* str, int base, const xp_char_t** endptr); diff --git a/ase/awk/awk_i.h b/ase/awk/awk_i.h index b16e6dc7..093cd6ec 100644 --- a/ase/awk/awk_i.h +++ b/ase/awk/awk_i.h @@ -1,5 +1,5 @@ /* - * $Id: awk_i.h,v 1.18 2006-06-19 15:43:27 bacon Exp $ + * $Id: awk_i.h,v 1.19 2006-06-20 15:27:50 bacon Exp $ */ #ifndef _XP_AWK_AWKI_H_ @@ -64,7 +64,7 @@ run with run_stack struct xp_awk_tree_t { xp_size_t nglobals; - xp_awk_map_t funcs; + xp_awk_map_t afns; /* awk function map */ xp_awk_nde_t* begin; xp_awk_nde_t* end; xp_awk_chain_t* chain; diff --git a/ase/awk/func.c b/ase/awk/func.c index 8093bf87..cae53c1d 100644 --- a/ase/awk/func.c +++ b/ase/awk/func.c @@ -1,5 +1,5 @@ /* - * $Id: func.c,v 1.1 2006-06-16 14:31:42 bacon Exp $ + * $Id: func.c,v 1.2 2006-06-20 15:27:50 bacon Exp $ */ #include @@ -9,17 +9,13 @@ #include #endif -enum -{ - BFN_SYSTEM, - BFN_CLOSE -}; +static int __bfn_close (void* run); static xp_awk_bfn_t __bfn[] = { - { XP_T("system"), BFN_SYSTEM, 0, 1, 1, XP_NULL }, - { XP_T("close"), BFN_CLOSE, 0, 1, 2, XP_NULL }, - { XP_NULL, 0, 0, 0, 0, XP_NULL } + { XP_T("system"), 0, 1, 1, XP_NULL }, + { XP_T("close"), XP_AWK_EXTIO, 1, 2, __bfn_close }, + { XP_NULL, 0, 0, 0, XP_NULL } }; xp_awk_bfn_t* xp_awk_getbfn (const xp_char_t* name) @@ -34,3 +30,19 @@ xp_awk_bfn_t* xp_awk_getbfn (const xp_char_t* name) return XP_NULL; } + +static int __bfn_close (void* run) +{ + xp_size_t nargs, i; + + nargs = xp_awk_getnargs (run); + for (i = 0; i < nargs; i++) + { + xp_printf (XP_T("arg %d => "), (int)i); + xp_awk_printval (xp_awk_getarg (run, i)); + xp_printf (XP_T("\n")); + } + + xp_awk_setretval (run, xp_awk_makeintval(run,10)); + return 0; +} diff --git a/ase/awk/func.h b/ase/awk/func.h index 037c5647..820f7eb8 100644 --- a/ase/awk/func.h +++ b/ase/awk/func.h @@ -1,5 +1,5 @@ /* - * $Id: func.h,v 1.1 2006-06-16 14:31:42 bacon Exp $ + * $Id: func.h,v 1.2 2006-06-20 15:27:50 bacon Exp $ */ #ifndef _XP_AWK_FUNC_H_ @@ -14,13 +14,11 @@ typedef struct xp_awk_bfn_t xp_awk_bfn_t; struct xp_awk_bfn_t { const xp_char_t* name; - - int type; int valid; /* the entry is valid when this option is set */ int max_args; int min_args; - xp_awk_val_t* (*handler) (); + int (*handler) (void* run); }; #ifdef __cplusplus diff --git a/ase/awk/parse.c b/ase/awk/parse.c index c1709df1..1c91e987 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.117 2006-06-19 15:43:27 bacon Exp $ + * $Id: parse.c,v 1.118 2006-06-20 15:27:50 bacon Exp $ */ #include @@ -281,19 +281,19 @@ static struct __kwent __bvtab[] = #endif static int __dump_func (xp_awk_pair_t* pair, void* arg) { - xp_awk_func_t* func = (xp_awk_func_t*)pair->val; + xp_awk_afn_t* afn = (xp_awk_afn_t*)pair->val; xp_size_t i; - xp_assert (xp_strcmp(pair->key, func->name) == 0); - xp_printf (XP_T("function %s ("), func->name); - for (i = 0; i < func->nargs; ) + xp_assert (xp_strcmp(pair->key, afn->name) == 0); + xp_printf (XP_T("function %s ("), afn->name); + for (i = 0; i < afn->nargs; ) { xp_printf (XP_T("__arg%lu"), (unsigned long)i++); - if (i >= func->nargs) break; + if (i >= afn->nargs) break; xp_printf (XP_T(", ")); } xp_printf (XP_T(")\n")); - xp_awk_prnpt (func->body); + xp_awk_prnpt (afn->body); xp_printf (XP_T("\n")); return 0; @@ -315,7 +315,7 @@ static void __dump (xp_awk_t* awk) xp_printf (XP_T("__global%lu;\n\n"), (unsigned long)i); } - xp_awk_map_walk (&awk->tree.funcs, __dump_func, XP_NULL); + xp_awk_map_walk (&awk->tree.afns, __dump_func, XP_NULL); if (awk->tree.begin != XP_NULL) { @@ -480,7 +480,7 @@ static xp_awk_nde_t* __parse_function (xp_awk_t* awk) xp_char_t* name; xp_char_t* name_dup; xp_awk_nde_t* body; - xp_awk_func_t* func; + xp_awk_afn_t* afn; xp_size_t nargs; xp_awk_pair_t* pair; int n; @@ -496,7 +496,7 @@ static xp_awk_nde_t* __parse_function (xp_awk_t* awk) } name = XP_STR_BUF(&awk->token.name); - if (xp_awk_map_get(&awk->tree.funcs, name) != XP_NULL) + if (xp_awk_map_get(&awk->tree.afns, name) != XP_NULL) { /* the function is defined previously */ PANIC (awk, XP_AWK_EDUPFUNC); @@ -569,7 +569,7 @@ static xp_awk_nde_t* __parse_function (xp_awk_t* awk) { /* check if a parameter conflicts with a function */ if (xp_strcmp(name_dup, param) == 0 || - xp_awk_map_get(&awk->tree.funcs, param) != XP_NULL) + xp_awk_map_get(&awk->tree.afns, param) != XP_NULL) { xp_free (name_dup); xp_awk_tab_clear (&awk->parse.params); @@ -659,31 +659,31 @@ static xp_awk_nde_t* __parse_function (xp_awk_t* awk) /* parameter names are not required anymore. clear them */ xp_awk_tab_clear (&awk->parse.params); - func = (xp_awk_func_t*) xp_malloc (xp_sizeof(xp_awk_func_t)); - if (func == XP_NULL) + afn = (xp_awk_afn_t*) xp_malloc (xp_sizeof(xp_awk_afn_t)); + if (afn == XP_NULL) { xp_free (name_dup); xp_awk_clrpt (body); return XP_NULL; } - func->name = XP_NULL; /* function name set below */ - func->nargs = nargs; - func->body = body; + afn->name = XP_NULL; /* function name set below */ + afn->nargs = nargs; + afn->body = body; - n = xp_awk_map_putx (&awk->tree.funcs, name_dup, func, &pair); + n = xp_awk_map_putx (&awk->tree.afns, name_dup, afn, &pair); if (n < 0) { xp_free (name_dup); xp_awk_clrpt (body); - xp_free (func); + xp_free (afn); PANIC (awk, XP_AWK_ENOMEM); } /* duplicate functions should have been detected previously */ xp_assert (n != 0); - func->name = pair->key; /* do some trick to save a string. */ + afn->name = pair->key; /* do some trick to save a string. */ xp_free (name_dup); return body; @@ -896,7 +896,7 @@ static xp_awk_t* __collect_globals (xp_awk_t* awk) if (awk->opt.parse & XP_AWK_UNIQUE) { /* check if it conflict with a function name */ - if (xp_awk_map_get(&awk->tree.funcs, global) != XP_NULL) + if (xp_awk_map_get(&awk->tree.afns, global) != XP_NULL) { PANIC (awk, XP_AWK_EDUPNAME); } @@ -949,7 +949,7 @@ static xp_awk_t* __collect_locals (xp_awk_t* awk, xp_size_t nlocals) if (awk->opt.parse & XP_AWK_UNIQUE) { /* check if it conflict with a function name */ - if (xp_awk_map_get(&awk->tree.funcs, local) != XP_NULL) + if (xp_awk_map_get(&awk->tree.afns, local) != XP_NULL) { PANIC (awk, XP_AWK_EDUPNAME); } diff --git a/ase/awk/run.c b/ase/awk/run.c index 4e480653..d00ed454 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.100 2006-06-19 15:43:27 bacon Exp $ + * $Id: run.c,v 1.101 2006-06-20 15:27:50 bacon Exp $ */ #include @@ -15,7 +15,7 @@ #define STACK_INCREMENT 512 -#define STACK_AT(run,n) ((run)->stack[run->stack_base+(n)]) +#define STACK_AT(run,n) ((run)->stack[(run)->stack_base+(n)]) #define STACK_NARGS(run) (STACK_AT(run,3)) #define STACK_ARG(run,n) STACK_AT(run,3+1+(n)) #define STACK_LOCAL(run,n) STACK_AT(run,3+(xp_size_t)STACK_NARGS(run)+1+(n)) @@ -120,8 +120,12 @@ static xp_awk_val_t* __eval_unary (xp_awk_run_t* run, xp_awk_nde_t* nde); static xp_awk_val_t* __eval_incpre (xp_awk_run_t* run, xp_awk_nde_t* nde); static xp_awk_val_t* __eval_incpst (xp_awk_run_t* run, xp_awk_nde_t* nde); static xp_awk_val_t* __eval_cnd (xp_awk_run_t* run, xp_awk_nde_t* nde); + static xp_awk_val_t* __eval_bfn (xp_awk_run_t* run, xp_awk_nde_t* nde); -static xp_awk_val_t* __eval_ufn (xp_awk_run_t* run, xp_awk_nde_t* nde); +static xp_awk_val_t* __eval_afn (xp_awk_run_t* run, xp_awk_nde_t* nde); +static xp_awk_val_t* __eval_call ( + xp_awk_run_t* run, xp_awk_nde_t* nde, xp_awk_afn_t* afn); + static xp_awk_val_t* __eval_int (xp_awk_run_t* run, xp_awk_nde_t* nde); static xp_awk_val_t* __eval_real (xp_awk_run_t* run, xp_awk_nde_t* nde); static xp_awk_val_t* __eval_str (xp_awk_run_t* run, xp_awk_nde_t* nde); @@ -159,6 +163,25 @@ static int __printval (xp_awk_pair_t* pair, void* arg) return 0; } +xp_size_t xp_awk_getnargs (void* run) +{ + return (xp_size_t) STACK_NARGS ((xp_awk_run_t*)run); +} + +xp_awk_val_t* xp_awk_getarg (void* run, xp_size_t idx) +{ + return STACK_ARG ((xp_awk_run_t*)run, idx); +} + +void xp_awk_setretval (void* run, xp_awk_val_t* val) +{ + xp_awk_run_t* r = (xp_awk_run_t*)run; + xp_awk_refdownval (r, STACK_RETVAL(r)); + STACK_RETVAL(r) = val; + /* should use the same trick as __run_return_statement */ + xp_awk_refupval (val); +} + int xp_awk_run (xp_awk_t* awk, xp_awk_io_t txtio, void* txtio_arg) { xp_awk_run_t* run; @@ -324,7 +347,7 @@ static int __run_main (xp_awk_run_t* run) run->exit_level = EXIT_NONE; - v = __eval_ufn (run, (xp_awk_nde_t*)&nde); + v = __eval_afn (run, (xp_awk_nde_t*)&nde); if (v == XP_NULL) n = -1; else { @@ -1000,8 +1023,7 @@ static int __run_return_statement (xp_awk_run_t* run, xp_awk_nde_return_t* nde) xp_awk_refdownval (run, STACK_RETVAL(run)); STACK_RETVAL(run) = val; - - xp_awk_refupval (val); /* see __eval_ufn for the trick */ + xp_awk_refupval (val); /* see __eval_call for the trick */ /*xp_printf (XP_T("set return value....\n"));*/ } @@ -1067,7 +1089,7 @@ static xp_awk_val_t* __eval_expression (xp_awk_run_t* run, xp_awk_nde_t* nde) __eval_incpst, __eval_cnd, __eval_bfn, - __eval_ufn, + __eval_afn, __eval_int, __eval_real, __eval_str, @@ -2532,34 +2554,40 @@ static xp_awk_val_t* __eval_cnd (xp_awk_run_t* run, xp_awk_nde_t* nde) static xp_awk_val_t* __eval_bfn (xp_awk_run_t* run, xp_awk_nde_t* nde) { - xp_printf (XP_T("__eval_bfn not implemented properly....\n")); - PANIC (run, XP_AWK_EINTERNAL); + return __eval_call (run, nde, XP_NULL); } -static xp_awk_val_t* __eval_ufn (xp_awk_run_t* run, xp_awk_nde_t* nde) +static xp_awk_val_t* __eval_afn (xp_awk_run_t* run, xp_awk_nde_t* nde) { - xp_awk_func_t* func; - xp_awk_pair_t* pair; - xp_awk_nde_t* p; - xp_size_t nargs, i; - xp_awk_val_t* v; - xp_size_t saved_stack_top; xp_awk_nde_call_t* call = (xp_awk_nde_call_t*)nde; - int n; + xp_awk_afn_t* afn; + xp_awk_pair_t* pair; -/*xp_printf (XP_T(".....__eval_call\n"));*/ - pair = xp_awk_map_get (&run->awk->tree.funcs, call->what.name); + pair = xp_awk_map_get (&run->awk->tree.afns, call->what.name); if (pair == XP_NULL) PANIC (run, XP_AWK_ENOSUCHFUNC); - func = (xp_awk_func_t*)pair->val; - xp_assert (func != XP_NULL); + afn = (xp_awk_afn_t*)pair->val; + xp_assert (afn != XP_NULL); - if (call->nargs > func->nargs) + if (call->nargs > afn->nargs) { /* TODO: is this correct? what if i want to allow arbitarary numbers of arguments? */ PANIC (run, XP_AWK_ETOOMANYARGS); } + return __eval_call (run, nde, afn); +} + +static xp_awk_val_t* __eval_call ( + xp_awk_run_t* run, xp_awk_nde_t* nde, xp_awk_afn_t* afn) +{ + xp_awk_nde_call_t* call = (xp_awk_nde_call_t*)nde; + xp_size_t saved_stack_top; + xp_size_t nargs, i; + xp_awk_nde_t* p; + xp_awk_val_t* v; + int n; + /* * --------------------- * localn <- stack top @@ -2684,26 +2712,31 @@ static xp_awk_val_t* __eval_ufn (xp_awk_run_t* run, xp_awk_nde_t* nde) xp_assert (nargs == call->nargs); - while (nargs < func->nargs) + if (afn != XP_NULL) { - /* push as many nils as the number of missing actual arguments */ - if (__raw_push(run,xp_awk_val_nil) == -1) + /* normal awk function */ + + while (nargs < afn->nargs) { - while (nargs > 0) + /* push as many nils as the number of missing actual arguments */ + if (__raw_push(run,xp_awk_val_nil) == -1) { -/* TODO: test this portion. */ - --nargs; - xp_awk_refdownval (run, STACK_ARG(run,nargs)); + while (nargs > 0) + { + /* TODO: test this portion. */ + --nargs; + xp_awk_refdownval (run, STACK_ARG(run,nargs)); + __raw_pop (run); + } + __raw_pop (run); - } + __raw_pop (run); + __raw_pop (run); + PANIC (run, XP_AWK_ENOMEM); + } - __raw_pop (run); - __raw_pop (run); - __raw_pop (run); - PANIC (run, XP_AWK_ENOMEM); + nargs++; } - - nargs++; } run->stack_base = saved_stack_top; @@ -2711,8 +2744,22 @@ static xp_awk_val_t* __eval_ufn (xp_awk_run_t* run, xp_awk_nde_t* nde) /*xp_printf (XP_T("running function body\n")); */ - xp_assert (func->body->type == XP_AWK_NDE_BLK); - n = __run_block(run,(xp_awk_nde_blk_t*)func->body); + if (afn != XP_NULL) + { + /* normal awk function */ + xp_assert (afn->body->type == XP_AWK_NDE_BLK); + n = __run_block(run,(xp_awk_nde_blk_t*)afn->body); + } + else + { + n = 0; + + /* built-in function */ + if (call->what.bfn->handler != XP_NULL) + { + n = call->what.bfn->handler (run); + } + } /*xp_printf (XP_T("block run complete\n")); */ @@ -2727,9 +2774,9 @@ static xp_awk_val_t* __eval_ufn (xp_awk_run_t* run, xp_awk_nde_t* nde) /* this is the trick mentioned in __run_return_statement. * adjust the reference count of the return value. - * the value must not be freeed event if the reference count - * is decremented to zero because its reference is increased in - * __run_return_statement regardless of its reference count. */ + * the value must not be freed even if the reference count + * is decremented to zero because its reference has been incremented + * in __run_return_statement regardless of its reference count. */ v = STACK_RETVAL(run); xp_awk_refdownval_nofree (run, v); diff --git a/ase/awk/tree.h b/ase/awk/tree.h index ea4e9ad0..e9b0337d 100644 --- a/ase/awk/tree.h +++ b/ase/awk/tree.h @@ -1,5 +1,5 @@ /* - * $Id: tree.h,v 1.46 2006-06-19 15:43:27 bacon Exp $ + * $Id: tree.h,v 1.47 2006-06-20 15:27:50 bacon Exp $ */ #ifndef _XP_AWK_TREE_H_ @@ -72,7 +72,7 @@ enum XP_AWK_PRINT_FILE }; -typedef struct xp_awk_func_t xp_awk_func_t; +typedef struct xp_awk_afn_t xp_awk_afn_t; typedef struct xp_awk_nde_t xp_awk_nde_t; @@ -102,7 +102,7 @@ typedef struct xp_awk_nde_exit_t xp_awk_nde_exit_t; typedef struct xp_awk_nde_next_t xp_awk_nde_next_t; typedef struct xp_awk_nde_nextfile_t xp_awk_nde_nextfile_t; -struct xp_awk_func_t +struct xp_awk_afn_t { xp_char_t* name; xp_size_t nargs; diff --git a/ase/awk/val.h b/ase/awk/val.h index e3c3f0cf..17b2eeb1 100644 --- a/ase/awk/val.h +++ b/ase/awk/val.h @@ -1,5 +1,5 @@ /* - * $Id: val.h,v 1.22 2006-04-30 18:05:07 bacon Exp $ + * $Id: val.h,v 1.23 2006-06-20 15:27:50 bacon Exp $ */ #ifndef _XP_AWK_VAL_H_ @@ -19,7 +19,6 @@ enum XP_AWK_VAL_MAP = 5 }; -typedef struct xp_awk_val_t xp_awk_val_t; typedef struct xp_awk_val_nil_t xp_awk_val_nil_t; typedef struct xp_awk_val_int_t xp_awk_val_int_t; typedef struct xp_awk_val_real_t xp_awk_val_real_t;