diff --git a/ase/awk/awk.c b/ase/awk/awk.c index f3eda1fc..b194f44e 100644 --- a/ase/awk/awk.c +++ b/ase/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c,v 1.8 2006-01-18 15:16:01 bacon Exp $ + * $Id: awk.c,v 1.9 2006-01-19 16:28:21 bacon Exp $ */ #include @@ -23,16 +23,17 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk) return XP_NULL; } + awk->opt = 0; awk->tree = XP_NULL; awk->errnum = XP_AWK_ENOERR; awk->src_func = XP_NULL; - awk->inp_func = XP_NULL; - awk->outp_func = XP_NULL; + awk->in_func = XP_NULL; + awk->out_func = XP_NULL; awk->src_arg = XP_NULL; - awk->inp_arg = XP_NULL; - awk->outp_arg = XP_NULL; + awk->in_arg = XP_NULL; + awk->out_arg = XP_NULL; awk->lex.curc = XP_CHAR_EOF; awk->lex.ungotc_count = 0; diff --git a/ase/awk/awk.h b/ase/awk/awk.h index 0366dc3e..0bc9c915 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.14 2006-01-19 10:56:34 bacon Exp $ + * $Id: awk.h,v 1.15 2006-01-19 16:28:21 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -30,11 +30,13 @@ enum XP_AWK_ELBRACE, /* left brace expected */ XP_AWK_ELPAREN, /* left parenthesis expected */ XP_AWK_ERPAREN, /* right parenthesis expected */ + XP_AWK_ERBRACK, /* right bracket expected */ XP_AWK_ECOMMA, /* comma expected */ XP_AWK_ESEMICOLON, /* semicolon expected */ XP_AWK_EEXPR, /* expression expected */ - XP_AWK_EWHILE /* keyword 'while' is expected */ + XP_AWK_EWHILE, /* keyword 'while' is expected */ + XP_AWK_EASSIGN /* assignment statement expected */ }; /* @@ -48,6 +50,7 @@ typedef struct xp_awk_t xp_awk_t; typedef xp_ssize_t (*xp_awk_io_t) ( int cmd, void* arg, xp_char_t* data, xp_size_t count); +/* io function commands */ enum { XP_AWK_IO_OPEN, @@ -55,19 +58,28 @@ enum XP_AWK_IO_DATA }; +/* options */ +enum +{ + XP_AWK_ASSIGN_ONLY /* a non-assignment expression cannot be used as a statement */ +}; + struct xp_awk_t { + /* options */ + int opt; + /* parse tree */ xp_awk_node_t* tree; /* io functions */ xp_awk_io_t src_func; - xp_awk_io_t inp_func; - xp_awk_io_t outp_func; + xp_awk_io_t in_func; + xp_awk_io_t out_func; void* src_arg; - void* inp_arg; - void* outp_arg; + void* in_arg; + void* out_arg; /* source buffer management */ struct { @@ -111,11 +123,11 @@ int xp_awk_attsrc (xp_awk_t* awk, xp_awk_io_t src, void* arg); */ int xp_awk_detsrc (xp_awk_t* awk); -int xp_awk_attinp (xp_awk_t* awk, xp_awk_io_t inp, void* arg); -int xp_awk_detinp (xp_awk_t* awk); +int xp_awk_attin (xp_awk_t* awk, xp_awk_io_t in, void* arg); +int xp_awk_detin (xp_awk_t* awk); -int xp_awk_attoutp (xp_awk_t* awk, xp_awk_io_t outp, void* arg); -int xp_awk_detoutp (xp_awk_t* awk); +int xp_awk_attout (xp_awk_t* awk, xp_awk_io_t out, void* arg); +int xp_awk_detout (xp_awk_t* awk); int xp_awk_parse (xp_awk_t* awk); diff --git a/ase/awk/parse.c b/ase/awk/parse.c index f08d43dd..bf187aeb 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.25 2006-01-19 13:28:29 bacon Exp $ + * $Id: parse.c,v 1.26 2006-01-19 16:28:21 bacon Exp $ */ #include @@ -33,8 +33,8 @@ enum TOKEN_RPAREN, TOKEN_LBRACE, TOKEN_RBRACE, - TOKEN_LBRACKET, - TOKEN_RBRACKET, + TOKEN_LBRACK, + TOKEN_RBRACK, TOKEN_COMMA, TOKEN_SEMICOLON, @@ -84,6 +84,7 @@ static xp_awk_node_t* __parse_additive (xp_awk_t* awk, xp_char_t* ident); static xp_awk_node_t* __parse_multiplicative (xp_awk_t* awk, xp_char_t* ident); static xp_awk_node_t* __parse_unary (xp_awk_t* awk, xp_char_t* ident); static xp_awk_node_t* __parse_primary (xp_awk_t* awk, xp_char_t* ident); +static xp_awk_node_t* __parse_hashidx (xp_awk_t* awk, xp_char_t* name); static xp_awk_node_t* __parse_funcall (xp_awk_t* awk, xp_char_t* name); static xp_awk_node_t* __parse_if (xp_awk_t* awk); static xp_awk_node_t* __parse_while (xp_awk_t* awk); @@ -422,6 +423,17 @@ static xp_awk_node_t* __parse_expression (xp_awk_t* awk) xp_free (ident); return XP_NULL; } + +/* + if (MATCH(awk,TOKEN_LBRACK)) { +// TODO: hashidx.... + xp_awk_node_t* node; + node = __parse_hashidx (awk, name); + if (node == XP_NULL) xp_free (name); + return (xp_awk_node_t*)node; + } +*/ + if (MATCH(awk,TOKEN_ASSIGN)) { if (__get_token(awk) == -1) { xp_free (ident); @@ -429,14 +441,24 @@ static xp_awk_node_t* __parse_expression (xp_awk_t* awk) } x = __parse_assignment (awk, ident); } - else x = __parse_basic_expr (awk, ident); + else { + if (awk->opt & XP_AWK_ASSIGN_ONLY) { + xp_free (ident); + PANIC (awk, XP_AWK_EASSIGN); + } + + x = __parse_basic_expr (awk, ident); + } xp_free (ident); } else { /* the expression starts with a non-identifier */ -// TODO: maybe this should be an error ->>> just an expression without assignment */ + if (awk->opt & XP_AWK_ASSIGN_ONLY) { + PANIC (awk, XP_AWK_EASSIGN); + } + x = __parse_basic_expr (awk, XP_NULL); } @@ -603,7 +625,13 @@ static xp_awk_node_t* __parse_primary (xp_awk_t* awk, xp_char_t* ident) } } - if (MATCH(awk,TOKEN_LPAREN)) { + if (MATCH(awk,TOKEN_LBRACK)) { + xp_awk_node_t* node; + node = __parse_hashidx (awk, name); + if (node == XP_NULL) xp_free (name); + return (xp_awk_node_t*)node; + } + else if (MATCH(awk,TOKEN_LPAREN)) { /* function call */ xp_awk_node_t* node; node = __parse_funcall (awk, name); @@ -699,6 +727,46 @@ static xp_awk_node_t* __parse_primary (xp_awk_t* awk, xp_char_t* ident) PANIC (awk, XP_AWK_EEXPR); } +static xp_awk_node_t* __parse_hashidx (xp_awk_t* awk, xp_char_t* name) +{ + xp_awk_node_t* idx; + xp_awk_node_idx_t* node; + + if (__get_token(awk) == -1) return XP_NULL; + +xp_printf (XP_TEXT("----------------\n")); + idx = __parse_expression (awk); + if (idx == XP_NULL) return XP_NULL; +xp_printf (XP_TEXT("+++++++++++++++++++\n")); + + if (!MATCH(awk,TOKEN_RBRACK)) { + xp_awk_clrpt (idx); + PANIC (awk, XP_AWK_ERBRACK); + } + +xp_printf (XP_TEXT("$$$$$$$$$$$$$$$$$$$$$$\n")); + if (__get_token(awk) == -1) { + xp_awk_clrpt (idx); + return XP_NULL; + } + +xp_printf (XP_TEXT("#######################\n")); + node = (xp_awk_node_idx_t*) xp_malloc (xp_sizeof(xp_awk_node_idx_t)); + if (node == XP_NULL) { + xp_awk_clrpt (idx); + PANIC (awk, XP_AWK_ENOMEM); + } + +xp_printf (XP_TEXT("~~~~~~~~~~~~~~~~~~~~~~~~~`\n")); + node->type = XP_AWK_NODE_IDX; + node->next = XP_NULL; + node->name = name; + node->idx = idx; + +xp_printf (XP_TEXT("%%%%%%%%%%%%%%%%%%%%%%%%%[%s]\n"), XP_STR_BUF(&awk->token.name)); + return (xp_awk_node_t*)node; +} + static xp_awk_node_t* __parse_funcall (xp_awk_t* awk, xp_char_t* name) { xp_awk_node_t* head, * curr, * node; @@ -1232,12 +1300,12 @@ static int __get_token (xp_awk_t* awk) GET_CHAR_TO (awk, c); } else if (c == XP_CHAR('[')) { - SET_TOKEN_TYPE (awk, TOKEN_LBRACKET); + SET_TOKEN_TYPE (awk, TOKEN_LBRACK); ADD_TOKEN_CHAR (awk, c); GET_CHAR_TO (awk, c); } else if (c == XP_CHAR(']')) { - SET_TOKEN_TYPE (awk, TOKEN_RBRACKET); + SET_TOKEN_TYPE (awk, TOKEN_RBRACK); ADD_TOKEN_CHAR (awk, c); GET_CHAR_TO (awk, c); } diff --git a/ase/awk/tree.c b/ase/awk/tree.c index 8db66cd8..405bc584 100644 --- a/ase/awk/tree.c +++ b/ase/awk/tree.c @@ -1,5 +1,5 @@ /* - * $Id: tree.c,v 1.7 2006-01-19 13:28:29 bacon Exp $ + * $Id: tree.c,v 1.8 2006-01-19 16:28:21 bacon Exp $ */ #include @@ -66,6 +66,12 @@ static int __print_expr_node (xp_awk_node_t* node) xp_printf (XP_TEXT("%s"), ((xp_awk_node_term_t*)node)->value); break; + case XP_AWK_NODE_IDX: + xp_printf (XP_TEXT("%s["), ((xp_awk_node_idx_t*)node)->name); + __print_expr_node (((xp_awk_node_idx_t*)node)->idx); + xp_printf (XP_TEXT("]")); + break; + case XP_AWK_NODE_CALL: xp_printf (XP_TEXT("%s ("), ((xp_awk_node_call_t*)node)->name); if (__print_expr_node_list (((xp_awk_node_call_t*)node)->args) == -1) return -1; @@ -323,6 +329,12 @@ void xp_awk_clrpt (xp_awk_node_t* tree) xp_free (p); break; + case XP_AWK_NODE_IDX: + xp_awk_clrpt (((xp_awk_node_idx_t*)p)->idx); + xp_free (((xp_awk_node_idx_t*)p)->name); + xp_free (p); + break; + case XP_AWK_NODE_CALL: xp_free (((xp_awk_node_call_t*)p)->name); xp_awk_clrpt (((xp_awk_node_call_t*)p)->args); diff --git a/ase/awk/tree.h b/ase/awk/tree.h index 0f50a7c0..4f3ba72c 100644 --- a/ase/awk/tree.h +++ b/ase/awk/tree.h @@ -1,5 +1,5 @@ /* - * $Id: tree.h,v 1.12 2006-01-19 13:28:29 bacon Exp $ + * $Id: tree.h,v 1.13 2006-01-19 16:28:21 bacon Exp $ */ #ifndef _XP_AWK_TREE_H_ @@ -19,6 +19,7 @@ enum XP_AWK_NODE_STR, XP_AWK_NODE_NUM, XP_AWK_NODE_VAR, + XP_AWK_NODE_IDX, XP_AWK_NODE_CALL, XP_AWK_NODE_IF, XP_AWK_NODE_WHILE, @@ -31,6 +32,7 @@ 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; typedef struct xp_awk_node_term_t xp_awk_node_term_t; +typedef struct xp_awk_node_idx_t xp_awk_node_idx_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; @@ -72,34 +74,41 @@ struct xp_awk_node_term_t xp_char_t* value; }; -struct xp_awk_node_call_t +struct xp_awk_node_idx_t { XP_AWK_NODE_HDR; xp_char_t* name; + xp_awk_node_t* idx; +}; + +struct xp_awk_node_call_t +{ + XP_AWK_NODE_HDR; /* XP_AWK_NODE_CALL */ + xp_char_t* name; xp_awk_node_t* args; }; struct xp_awk_node_if_t { - XP_AWK_NODE_HDR; + XP_AWK_NODE_HDR; /* XP_AWK_NODE_IF */ xp_awk_node_t* test; xp_awk_node_t* then_part; - xp_awk_node_t* else_part; + xp_awk_node_t* else_part; /* optional */ }; struct xp_awk_node_while_t { - XP_AWK_NODE_HDR; + XP_AWK_NODE_HDR; /* XP_AWK_NODE_WHILE, XP_AWK_NODE_DOWHILE */ xp_awk_node_t* test; 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_HDR; /* XP_AWK_NODE_FOR */ + xp_awk_node_t* init; /* optional */ + xp_awk_node_t* test; /* optional */ + xp_awk_node_t* incr; /* optional */ xp_awk_node_t* body; };