diff --git a/ase/awk/parse.c b/ase/awk/parse.c index 268072c0..f08d43dd 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.24 2006-01-19 10:56:35 bacon Exp $ + * $Id: parse.c,v 1.25 2006-01-19 13:28:29 bacon Exp $ */ #include @@ -865,7 +865,98 @@ static xp_awk_node_t* __parse_while (xp_awk_t* awk) static xp_awk_node_t* __parse_for (xp_awk_t* awk) { - return XP_NULL; + xp_awk_node_t* init, * test, * incr, * body; + xp_awk_node_for_t* node; + + if (!MATCH(awk,TOKEN_LPAREN)) PANIC (awk, XP_AWK_ELPAREN); + if (__get_token(awk) == -1) return XP_NULL; + + if (MATCH(awk,TOKEN_SEMICOLON)) init = XP_NULL; + else { + init = __parse_expression (awk); + if (init == XP_NULL) return XP_NULL; + + if (!MATCH(awk,TOKEN_SEMICOLON)) { + xp_awk_clrpt (init); + PANIC (awk, XP_AWK_ESEMICOLON); + } + } + + if (__get_token(awk) == -1) { + xp_awk_clrpt (init); + return XP_NULL; + } + + if (MATCH(awk,TOKEN_SEMICOLON)) test = XP_NULL; + else { + test = __parse_expression (awk); + if (test == XP_NULL) { + xp_awk_clrpt (init); + return XP_NULL; + } + + if (!MATCH(awk,TOKEN_SEMICOLON)) { + xp_awk_clrpt (init); + xp_awk_clrpt (test); + PANIC (awk, XP_AWK_ESEMICOLON); + } + } + + if (__get_token(awk) == -1) { + xp_awk_clrpt (init); + xp_awk_clrpt (test); + return XP_NULL; + } + + if (MATCH(awk,TOKEN_RPAREN)) incr = XP_NULL; + else { + incr = __parse_expression (awk); + if (incr == XP_NULL) { + xp_awk_clrpt (init); + xp_awk_clrpt (test); + return XP_NULL; + } + + if (!MATCH(awk,TOKEN_RPAREN)) { + xp_awk_clrpt (init); + xp_awk_clrpt (test); + xp_awk_clrpt (incr); + PANIC (awk, XP_AWK_ERPAREN); + } + } + + if (__get_token(awk) == -1) { + xp_awk_clrpt (init); + xp_awk_clrpt (test); + xp_awk_clrpt (incr); + return XP_NULL; + } + + body = __parse_statement (awk); + if (body == XP_NULL) { + xp_awk_clrpt (init); + xp_awk_clrpt (test); + xp_awk_clrpt (incr); + return XP_NULL; + } + + node = (xp_awk_node_for_t*) xp_malloc (xp_sizeof(xp_awk_node_for_t)); + if (node == XP_NULL) { + xp_awk_clrpt (init); + xp_awk_clrpt (test); + xp_awk_clrpt (incr); + xp_awk_clrpt (body); + PANIC (awk, XP_AWK_ENOMEM); + } + + node->type = XP_AWK_NODE_FOR; + node->next = XP_NULL; + node->init = init; + node->test = test; + node->incr = incr; + node->body = body; + + return (xp_awk_node_t*)node; } static xp_awk_node_t* __parse_dowhile (xp_awk_t* awk) diff --git a/ase/awk/tree.c b/ase/awk/tree.c index 74b219f8..8db66cd8 100644 --- a/ase/awk/tree.c +++ b/ase/awk/tree.c @@ -1,5 +1,5 @@ /* - * $Id: tree.c,v 1.6 2006-01-19 10:56:35 bacon Exp $ + * $Id: tree.c,v 1.7 2006-01-19 13:28:29 bacon Exp $ */ #include @@ -162,6 +162,29 @@ static void __print_statements (xp_awk_node_t* tree, int depth) xp_printf (XP_TEXT(");\n")); break; + case XP_AWK_NODE_FOR: + __print_tabs (depth); + xp_printf (XP_TEXT("for (")); + if (((xp_awk_node_for_t*)p)->init != XP_NULL) { + __print_expr_node (((xp_awk_node_for_t*)p)->init); + } + xp_printf (XP_TEXT("; ")); + if (((xp_awk_node_for_t*)p)->test != XP_NULL) { + __print_expr_node (((xp_awk_node_for_t*)p)->test); + } + xp_printf (XP_TEXT("; ")); + if (((xp_awk_node_for_t*)p)->incr != XP_NULL) { + __print_expr_node (((xp_awk_node_for_t*)p)->incr); + } + xp_printf (XP_TEXT(")\n")); + + if (((xp_awk_node_for_t*)p)->body->type == XP_AWK_NODE_BLOCK) { + __print_statements (((xp_awk_node_for_t*)p)->body, depth); + } + else { + __print_statements (((xp_awk_node_for_t*)p)->body, depth + 1); + } + case XP_AWK_NODE_BREAK: __print_tabs (depth); xp_printf (XP_TEXT("break;\n")); @@ -237,8 +260,8 @@ void xp_awk_clrpt (xp_awk_node_t* tree) case XP_AWK_NODE_IF: xp_awk_clrpt (((xp_awk_node_if_t*)p)->test); - if (((xp_awk_node_if_t*)p)->then_part != XP_NULL) - xp_awk_clrpt (((xp_awk_node_if_t*)p)->then_part); + xp_awk_clrpt (((xp_awk_node_if_t*)p)->then_part); + if (((xp_awk_node_if_t*)p)->else_part != XP_NULL) xp_awk_clrpt (((xp_awk_node_if_t*)p)->else_part); xp_free (p); @@ -247,8 +270,18 @@ void xp_awk_clrpt (xp_awk_node_t* tree) case XP_AWK_NODE_WHILE: case XP_AWK_NODE_DOWHILE: xp_awk_clrpt (((xp_awk_node_while_t*)p)->test); - if (((xp_awk_node_while_t*)p)->body != XP_NULL) - xp_awk_clrpt (((xp_awk_node_while_t*)p)->body); + xp_awk_clrpt (((xp_awk_node_while_t*)p)->body); + xp_free (p); + break; + + case XP_AWK_NODE_FOR: + if (((xp_awk_node_for_t*)p)->init != XP_NULL) + xp_awk_clrpt (((xp_awk_node_for_t*)p)->init); + if (((xp_awk_node_for_t*)p)->test != XP_NULL) + xp_awk_clrpt (((xp_awk_node_for_t*)p)->test); + if (((xp_awk_node_for_t*)p)->incr != XP_NULL) + xp_awk_clrpt (((xp_awk_node_for_t*)p)->incr); + xp_awk_clrpt (((xp_awk_node_for_t*)p)->body); xp_free (p); break; diff --git a/ase/awk/tree.h b/ase/awk/tree.h index dbd33a42..0f50a7c0 100644 --- a/ase/awk/tree.h +++ b/ase/awk/tree.h @@ -1,5 +1,5 @@ /* - * $Id: tree.h,v 1.11 2006-01-19 10:56:35 bacon Exp $ + * $Id: tree.h,v 1.12 2006-01-19 13:28:29 bacon Exp $ */ #ifndef _XP_AWK_TREE_H_ @@ -22,7 +22,8 @@ enum XP_AWK_NODE_CALL, XP_AWK_NODE_IF, XP_AWK_NODE_WHILE, - XP_AWK_NODE_DOWHILE + XP_AWK_NODE_DOWHILE, + XP_AWK_NODE_FOR }; typedef struct xp_awk_node_t xp_awk_node_t; @@ -33,6 +34,7 @@ typedef struct xp_awk_node_term_t xp_awk_node_term_t; typedef struct xp_awk_node_call_t xp_awk_node_call_t; 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; #define XP_AWK_NODE_HDR \ int type; \ @@ -92,6 +94,15 @@ struct xp_awk_node_while_t xp_awk_node_t* body; }; +struct xp_awk_node_for_t +{ + XP_AWK_NODE_HDR; + xp_awk_node_t* init; + xp_awk_node_t* test; + xp_awk_node_t* incr; + xp_awk_node_t* body; +}; + #ifdef __cplusplus extern "C" { #endif