diff --git a/ase/awk/awk.h b/ase/awk/awk.h index 4635cefa..a3f4d627 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.18 2006-01-24 16:14:28 bacon Exp $ + * $Id: awk.h,v 1.19 2006-01-25 16:11:43 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -91,6 +91,14 @@ struct xp_awk_t xp_awk_node_t* unnamed; } tree; + /* temporary information that the parser needs */ + struct + { + // TODO: locals, globals??? + xp_char_t* vars; /* global and local variable names... */ + xp_char_t* args; /* function arguments */ + } parse; + /* source buffer management */ struct { diff --git a/ase/awk/parse.c b/ase/awk/parse.c index 49c307f5..259ee2ee 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.33 2006-01-25 14:50:57 bacon Exp $ + * $Id: parse.c,v 1.34 2006-01-25 16:11:43 bacon Exp $ */ #include @@ -61,6 +61,9 @@ enum TOKEN_NEXT, TOKEN_NEXTFILE, + TOKEN_LOCAL, + TOKEN_GLOBAL, + __TOKEN_COUNT__ }; @@ -132,6 +135,11 @@ static struct __kwent __kwtab[] = { XP_TEXT("delete"), TOKEN_DELETE }, { XP_TEXT("next"), TOKEN_NEXT }, { XP_TEXT("nextfile"), TOKEN_NEXTFILE }, + +// TODO: don't return TOKEN_LOCAL & TOKEN_GLOBAL when explicit variable declaration is disabled. + { XP_TEXT("local"), TOKEN_LOCAL }, + { XP_TEXT("global"), TOKEN_GLOBAL }, + { XP_NULL, 0 }, }; @@ -398,36 +406,68 @@ static xp_awk_node_t* __parse_block (xp_awk_t* awk) { xp_awk_node_t* head, * curr, * node; xp_awk_node_block_t* block; + xp_size_t lvc = 0; + /* local variable declaration */ + //TODO: if (awk->opt & XP_AWK_VARDECL) { + while (1) { + if (MATCH(awk,TOKEN_EOF)) { + // cleanup the variable name list... + PANIC (awk, XP_AWK_EENDSRC); + } + + if (MATCH(awk,TOKEN_RBRACE)) { + if (__get_token(awk) == -1) { + // TODO: cleanup the variable name list... + return XP_NULL; + } + goto skip_block_body; + } + + if (!MATCH(awk,TOKEN_LOCAL)) break; + + if (__get_token(awk) == -1) { + // TODO: cleanup the variable name list... + return XP_NULL; + } +// TODO: collect variables... +// TODO: check duplicates with locals and globals, and maybe with the function names also depending on the awk options.... + } + // TODO: } + + /* block body */ head = XP_NULL; curr = XP_NULL; while (1) { if (MATCH(awk,TOKEN_EOF)) { + // TODO: cleanup the variable name list... if (head != XP_NULL) xp_awk_clrpt (head); PANIC (awk, XP_AWK_EENDSRC); } if (MATCH(awk,TOKEN_RBRACE)) { if (__get_token(awk) == -1) { + // TODO: cleanup the variable name list... if (head != XP_NULL) xp_awk_clrpt (head); return XP_NULL; } break; } -/* if you want to remove top-level null statement... get it here... */ +/* TODO: if you want to remove top-level null statement... get it here... */ /* if (MATCH(awk,TOKEN_SEMICOLON)) { if (__get_token(awk) == -1) { + // TODO: cleanup the variable name list... if (head != XP_NULL) xp_awk_clrpt (head); return XP_NULL; } continue; } */ - node = __parse_statement (awk); if (node == XP_NULL) { + // TODO: cleanup the variable name list... if (head != XP_NULL) xp_awk_clrpt (head); return XP_NULL; } @@ -437,16 +477,23 @@ static xp_awk_node_t* __parse_block (xp_awk_t* awk) curr = node; } +skip_block_body: + block = (xp_awk_node_block_t*) xp_malloc (xp_sizeof(xp_awk_node_block_t)); if (block == XP_NULL) { + // TODO: cleanup the variable name list... xp_awk_clrpt (head); PANIC (awk, XP_AWK_ENOMEM); } +// TODO: remove empty block such as { } { ;;;; }, or { local a, b, c; ;;; }. etc block->type = XP_AWK_NODE_BLOCK; block->next = XP_NULL; + block->lvc = lvc; block->body = head; + // TODO: cleanup the variable name list... + return (xp_awk_node_t*)block; } @@ -850,7 +897,7 @@ static xp_awk_node_t* __parse_primary (xp_awk_t* awk) return (xp_awk_node_t*)node; } else if (MATCH(awk,TOKEN_DOLLAR)) { - xp_awk_node_pos_t* node; + xp_awk_node_sgv_t* node; xp_awk_node_t* prim; if (__get_token(awk)) return XP_NULL; @@ -858,7 +905,7 @@ static xp_awk_node_t* __parse_primary (xp_awk_t* awk) prim = __parse_primary (awk); if (prim == XP_NULL) return XP_NULL; - node = (xp_awk_node_pos_t*) xp_malloc (xp_sizeof(xp_awk_node_pos_t)); + node = (xp_awk_node_sgv_t*) xp_malloc (xp_sizeof(xp_awk_node_sgv_t)); if (node == XP_NULL) { xp_awk_clrpt (prim); PANIC (awk, XP_AWK_ENOMEM); @@ -866,7 +913,7 @@ static xp_awk_node_t* __parse_primary (xp_awk_t* awk) node->type = XP_AWK_NODE_POS; node->next = XP_NULL; - node->pos = prim; + node->value = prim; return (xp_awk_node_t*)node; } @@ -1281,10 +1328,10 @@ static xp_awk_node_t* __parse_continue (xp_awk_t* awk) static xp_awk_node_t* __parse_return (xp_awk_t* awk) { - xp_awk_node_block_t* node; + xp_awk_node_sgv_t* node; xp_awk_node_t* val; - node = (xp_awk_node_block_t*) xp_malloc (xp_sizeof(xp_awk_node_block_t)); + node = (xp_awk_node_sgv_t*) xp_malloc (xp_sizeof(xp_awk_node_sgv_t)); if (node == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); node->type = XP_AWK_NODE_RETURN; node->next = XP_NULL; @@ -1295,16 +1342,16 @@ static xp_awk_node_t* __parse_return (xp_awk_t* awk) return XP_NULL; } - node->body = val; + node->value = val; return (xp_awk_node_t*)node; } static xp_awk_node_t* __parse_exit (xp_awk_t* awk) { - xp_awk_node_block_t* node; + xp_awk_node_sgv_t* node; xp_awk_node_t* val; - node = (xp_awk_node_block_t*) xp_malloc (xp_sizeof(xp_awk_node_block_t)); + node = (xp_awk_node_sgv_t*) xp_malloc (xp_sizeof(xp_awk_node_sgv_t)); if (node == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); node->type = XP_AWK_NODE_EXIT; node->next = XP_NULL; @@ -1315,7 +1362,7 @@ static xp_awk_node_t* __parse_exit (xp_awk_t* awk) return XP_NULL; } - node->body = val; + node->value = val; return (xp_awk_node_t*)node; } diff --git a/ase/awk/tree.c b/ase/awk/tree.c index 1bdf8d26..561b9447 100644 --- a/ase/awk/tree.c +++ b/ase/awk/tree.c @@ -1,5 +1,5 @@ /* - * $Id: tree.c,v 1.11 2006-01-25 14:50:57 bacon Exp $ + * $Id: tree.c,v 1.12 2006-01-25 16:11:43 bacon Exp $ */ #include @@ -77,7 +77,7 @@ static int __print_expr_node (xp_awk_node_t* node) case XP_AWK_NODE_POS: xp_printf (XP_TEXT("$")); - __print_expr_node (((xp_awk_node_pos_t*)node)->pos); + __print_expr_node (((xp_awk_node_sgv_t*)node)->value); break; case XP_AWK_NODE_CALL: @@ -212,12 +212,12 @@ static void __print_statements (xp_awk_node_t* tree, int depth) case XP_AWK_NODE_RETURN: __print_tabs (depth); xp_printf (XP_TEXT("return ")); - xp_assert (((xp_awk_node_block_t*)p)->body->next == XP_NULL); - if (__print_expr_node(((xp_awk_node_block_t*)p)->body) == 0) { + xp_assert (((xp_awk_node_sgv_t*)p)->value->next == XP_NULL); + if (__print_expr_node(((xp_awk_node_sgv_t*)p)->value) == 0) { xp_printf (XP_TEXT(";\n")); } else { - xp_awk_node_block_t* x = (xp_awk_node_block_t*)p; + xp_awk_node_sgv_t* x = (xp_awk_node_sgv_t*)p; xp_printf (XP_TEXT("***INTERNAL ERROR: unknown node type - %d\n"), x->type); } break; @@ -225,12 +225,12 @@ static void __print_statements (xp_awk_node_t* tree, int depth) case XP_AWK_NODE_EXIT: __print_tabs (depth); xp_printf (XP_TEXT("exit ")); - xp_assert (((xp_awk_node_block_t*)p)->body->next == XP_NULL); - if (__print_expr_node(((xp_awk_node_block_t*)p)->body) == 0) { + xp_assert (((xp_awk_node_sgv_t*)p)->value->next == XP_NULL); + if (__print_expr_node(((xp_awk_node_sgv_t*)p)->value) == 0) { xp_printf (XP_TEXT(";\n")); } else { - xp_awk_node_block_t* x = (xp_awk_node_block_t*)p; + xp_awk_node_sgv_t* x = (xp_awk_node_sgv_t*)p; xp_printf (XP_TEXT("***INTERNAL ERROR: unknown node type - %d\n"), x->type); } break; @@ -318,7 +318,7 @@ void xp_awk_clrpt (xp_awk_node_t* tree) case XP_AWK_NODE_RETURN: case XP_AWK_NODE_EXIT: - xp_awk_clrpt (((xp_awk_node_block_t*)p)->body); + xp_awk_clrpt (((xp_awk_node_sgv_t*)p)->value); xp_free (p); break; @@ -360,7 +360,7 @@ void xp_awk_clrpt (xp_awk_node_t* tree) break; case XP_AWK_NODE_POS: - xp_awk_clrpt (((xp_awk_node_pos_t*)p)->pos); + xp_awk_clrpt (((xp_awk_node_sgv_t*)p)->value); xp_free (p); break; diff --git a/ase/awk/tree.h b/ase/awk/tree.h index 79bf914b..0ac515b5 100644 --- a/ase/awk/tree.h +++ b/ase/awk/tree.h @@ -1,5 +1,5 @@ /* - * $Id: tree.h,v 1.17 2006-01-25 14:50:57 bacon Exp $ + * $Id: tree.h,v 1.18 2006-01-25 16:11:43 bacon Exp $ */ #ifndef _XP_AWK_TREE_H_ @@ -33,6 +33,7 @@ enum }; 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; typedef struct xp_awk_node_assign_t xp_awk_node_assign_t; typedef struct xp_awk_node_expr_t xp_awk_node_expr_t; @@ -62,9 +63,17 @@ struct xp_awk_node_t XP_AWK_NODE_HDR; }; +/* XP_AWK_NODE_RETURN, XP_AWK_NODE_EXIT, XP_AWK_NODE_POS */ +struct xp_awk_node_sgv_t +{ + XP_AWK_NODE_HDR; + xp_awk_node_t* value; +}; + struct xp_awk_node_block_t { XP_AWK_NODE_HDR; + xp_size_t lvc; /* local variable count */ xp_awk_node_t* body; }; @@ -110,12 +119,6 @@ struct xp_awk_node_idx_t xp_awk_node_t* idx; }; -/* positional variable - $1, $(a + 1), $$xx, etc */ -struct xp_awk_node_pos_t -{ - XP_AWK_NODE_HDR; - xp_awk_node_t* pos; -}; struct xp_awk_node_call_t {