From 4df4cec9da082fd8b58652c00f7e30544cfdecff Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 5 Feb 2006 16:00:33 +0000 Subject: [PATCH] *** empty log message *** --- ase/awk/awk.c | 4 +- ase/awk/awk.h | 3 +- ase/awk/parse.c | 132 ++++++++++++++++++++++++++++++++++++++------- ase/awk/tree.c | 61 +++++++++++++++------ ase/awk/tree.h | 10 ++-- ase/test/awk/awk.c | 2 +- 6 files changed, 170 insertions(+), 42 deletions(-) diff --git a/ase/awk/awk.c b/ase/awk/awk.c index d6511a0a..5e69a6d6 100644 --- a/ase/awk/awk.c +++ b/ase/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c,v 1.18 2006-02-05 13:45:59 bacon Exp $ + * $Id: awk.c,v 1.19 2006-02-05 16:00:33 bacon Exp $ */ #include @@ -69,6 +69,7 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk) awk->parse.nlocals_max = 0; + awk->tree.nglobals = 0; awk->tree.begin = XP_NULL; awk->tree.end = XP_NULL; awk->tree.unnamed = XP_NULL; @@ -153,6 +154,7 @@ void xp_awk_clear (xp_awk_t* awk) awk->parse.nlocals_max = 0; /* clear parse trees */ + awk->tree.nglobals = 0; xp_awk_hash_clear (&awk->tree.funcs); if (awk->tree.begin != XP_NULL) { diff --git a/ase/awk/awk.h b/ase/awk/awk.h index c197a88d..174694fa 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.25 2006-02-05 13:45:59 bacon Exp $ + * $Id: awk.h,v 1.26 2006-02-05 16:00:33 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -99,6 +99,7 @@ struct xp_awk_t /* parse tree */ struct { + xp_size_t nglobals; xp_awk_hash_t funcs; xp_awk_node_t* begin; xp_awk_node_t* end; diff --git a/ase/awk/parse.c b/ase/awk/parse.c index 32bac584..2f6177c9 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.47 2006-02-05 14:21:18 bacon Exp $ + * $Id: parse.c,v 1.48 2006-02-05 16:00:33 bacon Exp $ */ #include @@ -82,12 +82,13 @@ enum { #endif -static xp_awk_node_t* __parse_progunit (xp_awk_t* awk); +static xp_awk_t* __parse_progunit (xp_awk_t* awk); static xp_awk_node_t* __parse_function (xp_awk_t* awk); static xp_awk_node_t* __parse_begin (xp_awk_t* awk); static xp_awk_node_t* __parse_end (xp_awk_t* awk); static xp_awk_node_t* __parse_action (xp_awk_t* awk); static xp_awk_node_t* __parse_block (xp_awk_t* awk, xp_bool_t is_top); +static xp_awk_t* __collect_globals (xp_awk_t* awk); static xp_awk_t* __collect_locals (xp_awk_t* awk, xp_size_t nlocals); static xp_awk_node_t* __parse_statement (xp_awk_t* awk); static xp_awk_node_t* __parse_statement_nb (xp_awk_t* awk); @@ -206,6 +207,16 @@ static int __dump_func (xp_awk_pair_t* pair) static void __dump (xp_awk_t* awk) { + if (awk->tree.nglobals > 0) { + xp_size_t i; + + xp_printf (XP_TEXT("global ")); + for (i = 0; i < awk->tree.nglobals - 1; i++) { + xp_printf (XP_TEXT("__global%lu, "), (unsigned long)i); + } + xp_printf (XP_TEXT("__global%lu;\n"), (unsigned long)i); + } + xp_awk_hash_walk (&awk->tree.funcs, __dump_func); if (awk->tree.begin != NULL) { @@ -240,6 +251,7 @@ int xp_awk_parse (xp_awk_t* awk) } } + awk->tree.nglobals = xp_awk_tab_getsize (&awk->parse.globals); xp_printf (XP_TEXT("-----------------------------\n")); xp_printf (XP_TEXT("sucessful end - %d\n"), awk->errnum); __dump (awk); @@ -247,25 +259,34 @@ __dump (awk); return 0; } -static xp_awk_node_t* __parse_progunit (xp_awk_t* awk) +static xp_awk_t* __parse_progunit (xp_awk_t* awk) { /* pattern { action } function name (parameter-list) { statement } */ - xp_awk_node_t* node; - if (MATCH(awk,TOKEN_FUNCTION)) { - node = __parse_function(awk); - if (node == XP_NULL) return XP_NULL; + if ((awk->opt.parse & XP_AWK_EXPLICIT) && MATCH(awk,TOKEN_GLOBAL)) { + xp_size_t nglobals; + + if (__get_token(awk) == -1) return XP_NULL; + + nglobals = xp_awk_tab_getsize(&awk->parse.globals); + if (__collect_globals(awk) == XP_NULL) { + xp_awk_tab_remrange ( + &awk->parse.globals, nglobals, + xp_awk_tab_getsize(&awk->parse.globals) - nglobals); + return XP_NULL; + } + } + else if (MATCH(awk,TOKEN_FUNCTION)) { + if (__parse_function(awk) == XP_NULL) return XP_NULL; } else if (MATCH(awk,TOKEN_BEGIN)) { - node = __parse_begin (awk); - if (node == XP_NULL) return XP_NULL; + if (__parse_begin(awk) == XP_NULL) return XP_NULL; } else if (MATCH(awk, TOKEN_END)) { - node = __parse_end (awk); - if (node == XP_NULL) return XP_NULL; + if (__parse_end(awk) == XP_NULL) return XP_NULL; } /* TODO: process patterns and expressions */ /* @@ -279,13 +300,15 @@ static xp_awk_node_t* __parse_progunit (xp_awk_t* awk) */ else { /* pattern-less actions */ + xp_awk_node_t* node; + node = __parse_action (awk); if (node == XP_NULL) return XP_NULL; // TODO: weave the action block into awk->tree.actions... } - return node; + return awk; } static xp_awk_node_t* __parse_function (xp_awk_t* awk) @@ -611,6 +634,50 @@ static xp_awk_node_t* __parse_block (xp_awk_t* awk, xp_bool_t is_top) return (xp_awk_node_t*)block; } +static xp_awk_t* __collect_globals (xp_awk_t* awk) +{ + xp_char_t* global; + + while (1) { + if (!MATCH(awk,TOKEN_IDENT)) { + PANIC (awk, XP_AWK_EIDENT); + } + + global = XP_STR_BUF(&awk->token.name); + + if (awk->opt.parse & XP_AWK_UNIQUE) { + /* check if it conflict with a function name */ + if (xp_awk_hash_get(&awk->tree.funcs, global) != XP_NULL) { + PANIC (awk, XP_AWK_EDUPNAME); + } + } + + /* check if it conflicts with other global variable names */ + if (xp_awk_tab_find(&awk->parse.globals, global, 0) != (xp_size_t)-1) { + PANIC (awk, XP_AWK_EDUPVAR); + } + + if (xp_awk_tab_adddatum(&awk->parse.globals, global) == (xp_size_t)-1) { + PANIC (awk, XP_AWK_ENOMEM); + } + + if (__get_token(awk) == -1) return XP_NULL; + + if (MATCH(awk,TOKEN_SEMICOLON)) break; + + if (!MATCH(awk,TOKEN_COMMA)) { + PANIC (awk, XP_AWK_ECOMMA); + } + + if (__get_token(awk) == -1) return XP_NULL; + } + + /* skip a semicolon */ + if (__get_token(awk) == -1) return XP_NULL; + + return awk; +} + static xp_awk_t* __collect_locals (xp_awk_t* awk, xp_size_t nlocals) { xp_char_t* local; @@ -787,8 +854,12 @@ static xp_awk_node_t* __parse_expression (xp_awk_t* awk) xp_assert (x->next == XP_NULL); if (x->type != XP_AWK_NODE_ARG && x->type != XP_AWK_NODE_ARGIDX && - x->type != XP_AWK_NODE_VAR && - x->type != XP_AWK_NODE_VARIDX && + x->type != XP_AWK_NODE_NAMED && + x->type != XP_AWK_NODE_NAMEDIDX && + x->type != XP_AWK_NODE_GLOBAL && + x->type != XP_AWK_NODE_GLOBALIDX && + x->type != XP_AWK_NODE_LOCAL && + x->type != XP_AWK_NODE_LOCALIDX && x->type != XP_AWK_NODE_POS) { xp_awk_clrpt (x); PANIC (awk, XP_AWK_EASSIGN); @@ -1019,7 +1090,7 @@ static xp_awk_node_t* __parse_primary (xp_awk_t* awk) /* search the local variable list */ idxa = xp_awk_tab_rrfind(&awk->parse.locals, name_dup, 0); if (idxa != (xp_size_t)-1) { - node->type = XP_AWK_NODE_VAR; + node->type = XP_AWK_NODE_LOCAL; node->next = XP_NULL; //node->id.name = XP_NULL; node->id.name = name_dup; @@ -1028,14 +1099,24 @@ static xp_awk_node_t* __parse_primary (xp_awk_t* awk) return (xp_awk_node_t*)node; } - /* TODO: search the global variable list... */ /* search the global variable list */ + idxa = xp_awk_tab_rrfind(&awk->parse.globals, name_dup, 0); + if (idxa != (xp_size_t)-1) { + node->type = XP_AWK_NODE_GLOBAL; + node->next = XP_NULL; + //node->id.name = XP_NULL; + node->id.name = name_dup; + node->id.idxa = idxa; + + return (xp_awk_node_t*)node; + } if (awk->opt.parse & XP_AWK_IMPLICIT) { - node->type = XP_AWK_NODE_VAR; + node->type = XP_AWK_NODE_NAMED; node->next = XP_NULL; node->id.name = name_dup; node->id.idxa = (xp_size_t)-1; + return (xp_awk_node_t*)node; } @@ -1181,7 +1262,7 @@ static xp_awk_node_t* __parse_hashidx (xp_awk_t* awk, xp_char_t* name) /* search the local variable list */ idxa = xp_awk_tab_rrfind(&awk->parse.locals, name, 0); if (idxa != (xp_size_t)-1) { - node->type = XP_AWK_NODE_VARIDX; + node->type = XP_AWK_NODE_LOCALIDX; node->next = XP_NULL; //node->id.name = XP_NULL; node->id.name = name; @@ -1191,14 +1272,25 @@ static xp_awk_node_t* __parse_hashidx (xp_awk_t* awk, xp_char_t* name) return (xp_awk_node_t*)node; } - /* TODO: search the global variable list... */ /* search the global variable list */ + idxa = xp_awk_tab_rrfind(&awk->parse.globals, name, 0); + if (idxa != (xp_size_t)-1) { + node->type = XP_AWK_NODE_GLOBALIDX; + node->next = XP_NULL; + //node->id.name = XP_NULL; + node->id.name = name; + node->id.idxa = idxa; + + return (xp_awk_node_t*)node; + } if (awk->opt.parse & XP_AWK_IMPLICIT) { - node->type = XP_AWK_NODE_VAR; + node->type = XP_AWK_NODE_NAMEDIDX; node->next = XP_NULL; node->id.name = name; node->id.idxa = (xp_size_t)-1; + node->idx = idx; + return (xp_awk_node_t*)node; } diff --git a/ase/awk/tree.c b/ase/awk/tree.c index b33f6810..f2a5ac81 100644 --- a/ase/awk/tree.c +++ b/ase/awk/tree.c @@ -1,5 +1,5 @@ /* - * $Id: tree.c,v 1.18 2006-02-05 13:45:59 bacon Exp $ + * $Id: tree.c,v 1.19 2006-02-05 16:00:33 bacon Exp $ */ #include @@ -79,7 +79,41 @@ static int __print_expr_node (xp_awk_node_t* node) xp_printf (XP_TEXT("]")); break; - case XP_AWK_NODE_VAR: + case XP_AWK_NODE_NAMED: + xp_assert (((xp_awk_node_var_t*)node)->id.idxa == (xp_size_t)-1); + xp_printf (XP_TEXT("%s"), ((xp_awk_node_var_t*)node)->id.name); + break; + + case XP_AWK_NODE_NAMEDIDX: + xp_assert (((xp_awk_node_idx_t*)node)->id.idxa == (xp_size_t)-1); + xp_printf (XP_TEXT("%s["), ((xp_awk_node_idx_t*)node)->id.name); + __print_expr_node (((xp_awk_node_idx_t*)node)->idx); + xp_printf (XP_TEXT("]")); + break; + + case XP_AWK_NODE_GLOBAL: + if (((xp_awk_node_var_t*)node)->id.idxa != (xp_size_t)-1) { + xp_printf (XP_TEXT("__global%lu"), + (unsigned long)((xp_awk_node_var_t*)node)->id.idxa); + } + else { + xp_printf (XP_TEXT("%s"), ((xp_awk_node_var_t*)node)->id.name); + } + break; + + case XP_AWK_NODE_GLOBALIDX: + if (((xp_awk_node_idx_t*)node)->id.idxa != (xp_size_t)-1) { + xp_printf (XP_TEXT("__global%lu["), + (unsigned long)((xp_awk_node_idx_t*)node)->id.idxa); + } + else { + xp_printf (XP_TEXT("%s["), ((xp_awk_node_idx_t*)node)->id.name); + } + __print_expr_node (((xp_awk_node_idx_t*)node)->idx); + xp_printf (XP_TEXT("]")); + break; + + case XP_AWK_NODE_LOCAL: if (((xp_awk_node_var_t*)node)->id.idxa != (xp_size_t)-1) { xp_printf (XP_TEXT("__local%lu"), (unsigned long)((xp_awk_node_var_t*)node)->id.idxa); @@ -89,7 +123,7 @@ static int __print_expr_node (xp_awk_node_t* node) } break; - case XP_AWK_NODE_VARIDX: + case XP_AWK_NODE_LOCALIDX: if (((xp_awk_node_idx_t*)node)->id.idxa != (xp_size_t)-1) { xp_printf (XP_TEXT("__local%lu["), (unsigned long)((xp_awk_node_idx_t*)node)->id.idxa); @@ -398,12 +432,20 @@ void xp_awk_clrpt (xp_awk_node_t* tree) xp_free (p); break; + case XP_AWK_NODE_NAMED: + xp_assert (((xp_awk_node_idx_t*)p)->id.name != XP_NULL); + case XP_AWK_NODE_GLOBAL: + case XP_AWK_NODE_LOCAL: case XP_AWK_NODE_ARG: if (((xp_awk_node_var_t*)p)->id.name != XP_NULL) xp_free (((xp_awk_node_var_t*)p)->id.name); xp_free (p); break; + case XP_AWK_NODE_NAMEDIDX: + xp_assert (((xp_awk_node_idx_t*)p)->id.name != XP_NULL); + case XP_AWK_NODE_GLOBALIDX: + case XP_AWK_NODE_LOCALIDX: case XP_AWK_NODE_ARGIDX: xp_awk_clrpt (((xp_awk_node_idx_t*)p)->idx); if (((xp_awk_node_idx_t*)p)->id.name != XP_NULL) @@ -411,19 +453,6 @@ void xp_awk_clrpt (xp_awk_node_t* tree) xp_free (p); break; - case XP_AWK_NODE_VAR: - if (((xp_awk_node_var_t*)p)->id.name != XP_NULL) - xp_free (((xp_awk_node_var_t*)p)->id.name); - xp_free (p); - break; - - case XP_AWK_NODE_VARIDX: - xp_awk_clrpt (((xp_awk_node_idx_t*)p)->idx); - if (((xp_awk_node_idx_t*)p)->id.name != XP_NULL) - xp_free (((xp_awk_node_idx_t*)p)->id.name); - xp_free (p); - break; - case XP_AWK_NODE_POS: xp_assert (((xp_awk_node_sgv_t*)p)->value != XP_NULL); xp_awk_clrpt (((xp_awk_node_sgv_t*)p)->value); diff --git a/ase/awk/tree.h b/ase/awk/tree.h index 7aae171c..14b7b167 100644 --- a/ase/awk/tree.h +++ b/ase/awk/tree.h @@ -1,5 +1,5 @@ /* - * $Id: tree.h,v 1.21 2006-02-04 19:31:51 bacon Exp $ + * $Id: tree.h,v 1.22 2006-02-05 16:00:33 bacon Exp $ */ #ifndef _XP_AWK_TREE_H_ @@ -20,8 +20,12 @@ enum XP_AWK_NODE_UNARY, XP_AWK_NODE_STR, XP_AWK_NODE_NUM, - XP_AWK_NODE_VAR, - XP_AWK_NODE_VARIDX, + XP_AWK_NODE_NAMED, + XP_AWK_NODE_NAMEDIDX, + XP_AWK_NODE_GLOBAL, + XP_AWK_NODE_GLOBALIDX, + XP_AWK_NODE_LOCAL, + XP_AWK_NODE_LOCALIDX, XP_AWK_NODE_ARG, XP_AWK_NODE_ARGIDX, XP_AWK_NODE_POS, diff --git a/ase/test/awk/awk.c b/ase/test/awk/awk.c index 8bff2fb0..32635309 100644 --- a/ase/test/awk/awk.c +++ b/ase/test/awk/awk.c @@ -78,7 +78,7 @@ int xp_main (int argc, xp_char_t* argv[]) return -1; } -awk.opt.parse = XP_AWK_EXPLICIT | XP_AWK_UNIQUE; +awk.opt.parse = XP_AWK_EXPLICIT | XP_AWK_UNIQUE | XP_AWK_SHADING | XP_AWK_IMPLICIT; if (xp_awk_parse(&awk) == -1) { xp_printf ( XP_TEXT("error: cannot parse program - [%d] %s\n"),