From c4a635d425277177bb77480f3497c25129e02337 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Mon, 30 Jan 2006 14:34:47 +0000 Subject: [PATCH] *** empty log message *** --- ase/awk/awk.c | 28 ++++++++++++++++--- ase/awk/awk.h | 7 ++--- ase/awk/hash.c | 67 ++++++++++++++++++++++++++++++++++++++++------ ase/awk/hash.h | 17 +++++++----- ase/awk/parse.c | 55 ++++++++++++++++++++++++++----------- ase/awk/tree.h | 5 ++-- ase/test/awk/awk.c | 10 ------- 7 files changed, 141 insertions(+), 48 deletions(-) diff --git a/ase/awk/awk.c b/ase/awk/awk.c index 39250f6b..d9798a7d 100644 --- a/ase/awk/awk.c +++ b/ase/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c,v 1.12 2006-01-29 18:28:14 bacon Exp $ + * $Id: awk.c,v 1.13 2006-01-30 14:34:47 bacon Exp $ */ #include @@ -9,6 +9,8 @@ #include #endif +static void __free_func (void* func); + xp_awk_t* xp_awk_open (xp_awk_t* awk) { if (awk == XP_NULL) { @@ -23,12 +25,19 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk) return XP_NULL; } - if (xp_awk_tab_open(&awk->parse.func) == XP_NULL) { + if (xp_awk_hash_open(&awk->tree.funcs, 256, __free_func) == XP_NULL) { xp_str_close (&awk->token.name); if (awk->__dynamic) xp_free (awk); return XP_NULL; } + if (xp_awk_tab_open(&awk->parse.funcs) == XP_NULL) { + xp_str_close (&awk->token.name); + xp_awk_hash_close (&awk->tree.funcs); + if (awk->__dynamic) xp_free (awk); + return XP_NULL; + } + awk->opt = 0; awk->errnum = XP_AWK_ENOERR; @@ -57,7 +66,8 @@ int xp_awk_close (xp_awk_t* awk) xp_awk_clear (awk); if (xp_awk_detsrc(awk) == -1) return -1; - xp_awk_tab_close(&awk->parse.func); + xp_awk_hash_close (&awk->tree.funcs); + xp_awk_tab_close (&awk->parse.funcs); xp_str_close (&awk->token.name); if (awk->__dynamic) xp_free (awk); @@ -71,6 +81,8 @@ int xp_awk_close (xp_awk_t* awk) void xp_awk_clear (xp_awk_t* awk) { /* clear parse trees */ + xp_awk_hash_clear (&awk->tree.funcs); + if (awk->tree.begin != XP_NULL) { xp_assert (awk->tree.begin->next == XP_NULL); xp_awk_clrpt (awk->tree.begin); @@ -128,3 +140,13 @@ int xp_awk_detsrc (xp_awk_t* awk) return 0; } +static void __free_func (void* func) +{ + xp_awk_func_t* f = (xp_awk_func_t*) func; + + /* f->name doesn't have to be freed */ + /*xp_free (f->name);*/ + + xp_awk_clrpt (f->body); + xp_free (f); +} diff --git a/ase/awk/awk.h b/ase/awk/awk.h index b0f8c766..0106d4c9 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.21 2006-01-29 18:28:14 bacon Exp $ + * $Id: awk.h,v 1.22 2006-01-30 14:34:47 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -15,6 +15,7 @@ #include #include +#include enum { @@ -87,7 +88,7 @@ struct xp_awk_t /* parse tree */ struct { - //xp_awk_hash_t* funcs; + xp_awk_hash_t funcs; xp_awk_node_t* begin; xp_awk_node_t* end; xp_awk_node_t* unnamed; @@ -96,7 +97,7 @@ struct xp_awk_t /* temporary information that the parser needs */ struct { - xp_awk_tab_t func; + xp_awk_tab_t funcs; // TODO: locals, globals??? xp_char_t* vars; /* global and local variable names... */ xp_char_t* args; /* function arguments */ diff --git a/ase/awk/hash.c b/ase/awk/hash.c index 2ae56303..7425191b 100644 --- a/ase/awk/hash.c +++ b/ase/awk/hash.c @@ -1,5 +1,5 @@ /* - * $Id: hash.c,v 1.2 2006-01-30 13:25:26 bacon Exp $ + * $Id: hash.c,v 1.3 2006-01-30 14:34:47 bacon Exp $ */ #include @@ -9,7 +9,16 @@ static xp_size_t __hash (const xp_char_t* key); -xp_awk_hash_t* xp_awk_hash_open (xp_awk_hash_t* hash, xp_size_t capa) +#define FREE_PAIR(hash,pair) \ + do { \ + xp_free ((pair)->key); \ + if ((hash)->free_value != XP_NULL) \ + (hash)->free_value ((pair)->value); \ + xp_free (pair); \ + } while (0) + +xp_awk_hash_t* xp_awk_hash_open ( + xp_awk_hash_t* hash, xp_size_t capa, void (*free_value) (void*)) { if (hash == XP_NULL) { hash = (xp_awk_hash_t*) xp_malloc (xp_sizeof(xp_awk_hash_t)); @@ -26,6 +35,7 @@ xp_awk_hash_t* xp_awk_hash_open (xp_awk_hash_t* hash, xp_size_t capa) hash->capa = capa; hash->size = 0; + hash->free_value = free_value; while (capa > 0) hash->buck[--capa] = XP_NULL; return hash; @@ -48,16 +58,20 @@ void xp_awk_hash_clear (xp_awk_hash_t* hash) while (pair != XP_NULL) { next = pair->next; - xp_free (pair); + + FREE_PAIR (hash, pair); hash->size--; + pair = next; } hash->buck[i] = XP_NULL; } + + xp_assert (hash->size == 0); } -xp_awk_pair_t* xp_awk_hash_get (xp_awk_hash_t* hash, const xp_char_t* key) +xp_awk_pair_t* xp_awk_hash_get (xp_awk_hash_t* hash, xp_char_t* key) { xp_awk_pair_t* pair; xp_size_t hc; @@ -73,7 +87,7 @@ xp_awk_pair_t* xp_awk_hash_get (xp_awk_hash_t* hash, const xp_char_t* key) return XP_NULL; } -xp_awk_pair_t* xp_awk_hash_put (xp_awk_hash_t* hash, const xp_char_t* key, void* value) +xp_awk_pair_t* xp_awk_hash_put (xp_awk_hash_t* hash, xp_char_t* key, void* value) { xp_awk_pair_t* pair; xp_size_t hc; @@ -83,7 +97,16 @@ xp_awk_pair_t* xp_awk_hash_put (xp_awk_hash_t* hash, const xp_char_t* key, void* while (pair != XP_NULL) { if (xp_strcmp(pair->key,key) == 0) { + + if (pair->key != key) { + xp_free (pair->key); + pair->key = key; + } + if (hash->free_value != XP_NULL) { + hash->free_value (pair->value); + } pair->value = value; + return pair; } pair = pair->next; @@ -101,7 +124,7 @@ xp_awk_pair_t* xp_awk_hash_put (xp_awk_hash_t* hash, const xp_char_t* key, void* return pair; } -xp_awk_pair_t* xp_awk_hash_set (xp_awk_hash_t* hash, const xp_char_t* key, void* value) +xp_awk_pair_t* xp_awk_hash_set (xp_awk_hash_t* hash, xp_char_t* key, void* value) { xp_awk_pair_t* pair; xp_size_t hc; @@ -111,7 +134,16 @@ xp_awk_pair_t* xp_awk_hash_set (xp_awk_hash_t* hash, const xp_char_t* key, void* while (pair != XP_NULL) { if (xp_strcmp(pair->key,key) == 0) { + if (pair->key != key) { + xp_free (pair->key); + pair->key = key; + } + + if (hash->free_value != XP_NULL) { + hash->free_value (pair->value); + } pair->value = value; + return pair; } pair = pair->next; @@ -120,7 +152,7 @@ xp_awk_pair_t* xp_awk_hash_set (xp_awk_hash_t* hash, const xp_char_t* key, void* return XP_NULL; } -int xp_awk_hash_remove (xp_awk_hash_t* hash, const xp_char_t* key) +int xp_awk_hash_remove (xp_awk_hash_t* hash, xp_char_t* key) { xp_awk_pair_t* pair, * prev; xp_size_t hc; @@ -135,8 +167,9 @@ int xp_awk_hash_remove (xp_awk_hash_t* hash, const xp_char_t* key) hash->buck[hc] = pair->next; else prev->next = pair->next; - xp_free (pair); + FREE_PAIR (hash, pair); hash->size--; + return 0; } @@ -147,6 +180,24 @@ int xp_awk_hash_remove (xp_awk_hash_t* hash, const xp_char_t* key) return -1; } +int xp_awk_hash_walk (xp_awk_hash_t* hash, int (*walker) (xp_awk_pair_t*)) +{ + xp_size_t i; + xp_awk_pair_t* pair, * next; + + for (i = 0; i < hash->capa; i++) { + pair = hash->buck[i]; + + while (pair != XP_NULL) { + next = pair->next; + if (walker(pair) == -1) return -1; + pair = next; + } + } + + return 0; +} + static xp_size_t __hash (const xp_char_t* key) { xp_size_t n = 0, i; diff --git a/ase/awk/hash.h b/ase/awk/hash.h index 5c60d29d..e798bb35 100644 --- a/ase/awk/hash.h +++ b/ase/awk/hash.h @@ -1,5 +1,5 @@ /* - * $Id: hash.h,v 1.3 2006-01-30 13:25:26 bacon Exp $ + * $Id: hash.h,v 1.4 2006-01-30 14:34:47 bacon Exp $ */ #ifndef _XP_AWK_HASH_H_ @@ -17,7 +17,7 @@ typedef struct xp_awk_pair_t xp_awk_pair_t; struct xp_awk_pair_t { - const xp_char_t* key; + xp_char_t* key; void* value; xp_awk_pair_t* next; }; @@ -27,6 +27,7 @@ struct xp_awk_hash_t xp_size_t size; xp_size_t capa; xp_awk_pair_t** buck; + void (*free_value) (void*); xp_bool_t __dynamic; }; @@ -34,16 +35,18 @@ struct xp_awk_hash_t extern "C" { #endif -xp_awk_hash_t* xp_awk_hash_open (xp_awk_hash_t* hash, xp_size_t capa); +xp_awk_hash_t* xp_awk_hash_open ( + xp_awk_hash_t* hash, xp_size_t capa, void (*free_value) (void*)); void xp_awk_hash_close (xp_awk_hash_t* hash); void xp_awk_hash_clear (xp_awk_hash_t* hash); -xp_awk_pair_t* xp_awk_hash_get (xp_awk_hash_t* hash, const xp_char_t* key); -xp_awk_pair_t* xp_awk_hash_put (xp_awk_hash_t* hash, const xp_char_t* key, void* value); -xp_awk_pair_t* xp_awk_hash_set (xp_awk_hash_t* hash, const xp_char_t* key, void* value); +xp_awk_pair_t* xp_awk_hash_get (xp_awk_hash_t* hash, xp_char_t* key); +xp_awk_pair_t* xp_awk_hash_put (xp_awk_hash_t* hash, xp_char_t* key, void* value); +xp_awk_pair_t* xp_awk_hash_set (xp_awk_hash_t* hash, xp_char_t* key, void* value); -int xp_awk_hash_remove (xp_awk_hash_t* hash, const xp_char_t* key); +int xp_awk_hash_remove (xp_awk_hash_t* hash, xp_char_t* key); +int xp_awk_hash_walk (xp_awk_hash_t* hash, int (*walker) (xp_awk_pair_t*)); #ifdef __cplusplus } diff --git a/ase/awk/parse.c b/ase/awk/parse.c index b92edbbe..6c0ee66d 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.38 2006-01-30 13:25:26 bacon Exp $ + * $Id: parse.c,v 1.39 2006-01-30 14:34:47 bacon Exp $ */ #include @@ -188,6 +188,34 @@ static struct __kwent __kwtab[] = #define PANIC(awk,code) do { (awk)->errnum = (code); return XP_NULL; } while (0); +static int __dump_func (xp_awk_pair_t* pair) +{ + xp_awk_func_t* func = (xp_awk_func_t*)pair->value; + + xp_assert (xp_strcmp(pair->key, func->name) == 0); + xp_printf (XP_TEXT("function %s (nargs=>%u)\n"), func->name, func->nargs); + xp_awk_prnpt (func->body); + xp_printf (XP_TEXT("\n")); + + return 0; +} + +static void __dump (xp_awk_t* awk) +{ + xp_awk_hash_walk (&awk->tree.funcs, __dump_func); + + if (awk->tree.begin != NULL) { + xp_printf (XP_TEXT("BEGIN ")); + xp_awk_prnpt (awk->tree.begin); + xp_printf (XP_TEXT("\n")); + } + + if (awk->tree.end != NULL) { + xp_printf (XP_TEXT("END ")); + xp_awk_prnpt (awk->tree.end); + } +} + int xp_awk_parse (xp_awk_t* awk) { /* if you want to parse anew, call xp_awk_clear first. @@ -197,23 +225,20 @@ int xp_awk_parse (xp_awk_t* awk) GET_TOKEN (awk); while (1) { - xp_awk_node_t* unit; - if (MATCH(awk,TOKEN_EOF)) break; - unit = __parse_progunit(awk); - if (unit == XP_NULL) { + if (__parse_progunit(awk) == XP_NULL) { // TODO: cleanup the parse tree created so far.... // function tables also etc... xp_printf (XP_TEXT("error - %d\n"), awk->errnum); return -1; } - -xp_awk_prnpt(unit); - } +xp_printf (XP_TEXT("-----------------------------\n")); xp_printf (XP_TEXT("sucessful end - %d\n"), awk->errnum); +__dump (awk); + return 0; } @@ -263,6 +288,7 @@ static xp_awk_node_t* __parse_function (xp_awk_t* awk) xp_char_t* name; xp_char_t* name_dup; xp_awk_node_t* body; + xp_awk_func_t* func; xp_size_t fnpos; xp_size_t nargs = 0; @@ -386,10 +412,10 @@ static xp_awk_node_t* __parse_function (xp_awk_t* awk) return XP_NULL; } -/* func = (xp_awk_func_t*) xp_malloc (xp_sizeof(xp_awk_func_t)); if (func == XP_NULL) { __remove_func_name (awk, fnpos); +// TODO: cleanup parameter name list xp_free (name_dup); xp_awk_clrpt (body); return XP_NULL; @@ -399,15 +425,14 @@ static xp_awk_node_t* __parse_function (xp_awk_t* awk) func->nargs = nargs; func->body = body; - xp_assert (xp_awk_hash_get(&awk->tree.func, name_dup) == XP_NULL); - if (xp_awk_hash_put(&awk->tree.func, name_dup, func) == XP_NULL) { + xp_assert (xp_awk_hash_get(&awk->tree.funcs, name_dup) == XP_NULL); + if (xp_awk_hash_put(&awk->tree.funcs, name_dup, func) == XP_NULL) { __remove_func_name (awk, fnpos); xp_free (name_dup); xp_awk_clrpt (body); xp_free (func); PANIC (awk, XP_AWK_ENOMEM); } -*/ return body; } @@ -1744,17 +1769,17 @@ static INLINE xp_size_t __add_func_name (xp_awk_t* awk, const xp_char_t* name) { xp_assert (__find_func_name(awk,name) == (xp_size_t)-1); - return xp_awk_tab_adddatum(&awk->parse.func, name); + return xp_awk_tab_adddatum(&awk->parse.funcs, name); } static INLINE int __remove_func_name (xp_awk_t* awk, xp_size_t index) { - return xp_awk_tab_remrange (&awk->parse.func, index, 1); + return xp_awk_tab_remrange (&awk->parse.funcs, index, 1); } static INLINE xp_size_t __find_func_name (xp_awk_t* awk, const xp_char_t* name) { - return xp_awk_tab_find(&awk->parse.func, name, 0); + return xp_awk_tab_find(&awk->parse.funcs, name, 0); } static INLINE xp_size_t __find_func_arg (xp_awk_t* awk, const xp_char_t* name) diff --git a/ase/awk/tree.h b/ase/awk/tree.h index 0ac515b5..07eebadb 100644 --- a/ase/awk/tree.h +++ b/ase/awk/tree.h @@ -1,5 +1,5 @@ /* - * $Id: tree.h,v 1.18 2006-01-25 16:11:43 bacon Exp $ + * $Id: tree.h,v 1.19 2006-01-30 14:34:47 bacon Exp $ */ #ifndef _XP_AWK_TREE_H_ @@ -32,6 +32,8 @@ enum XP_AWK_NODE_FOR }; +typedef struct xp_awk_func_t xp_awk_func_t; + typedef struct xp_awk_node_t xp_awk_node_t; typedef struct xp_awk_node_sgv_t xp_awk_node_sgv_t; typedef struct xp_awk_node_block_t xp_awk_node_block_t; @@ -46,7 +48,6 @@ typedef struct xp_awk_node_if_t xp_awk_node_if_t; typedef struct xp_awk_node_while_t xp_awk_node_while_t; typedef struct xp_awk_node_for_t xp_awk_node_for_t; - struct xp_awk_func_t { xp_char_t* name; diff --git a/ase/test/awk/awk.c b/ase/test/awk/awk.c index 287585f6..c18f133c 100644 --- a/ase/test/awk/awk.c +++ b/ase/test/awk/awk.c @@ -76,16 +76,6 @@ int xp_main (int argc, xp_char_t* argv[]) return -1; } - xp_printf (XP_TEXT("-----------------------------------------------\n")); - if (awk.tree.begin != XP_NULL) { - xp_printf (XP_TEXT("BEGIN ")); - xp_awk_prnpt (awk.tree.begin); - } - if (awk.tree.end != XP_NULL) { - xp_printf (XP_TEXT("END ")); - xp_awk_prnpt (awk.tree.end); - } - xp_awk_close (&awk); return 0; }