From 86a65e2e670f8a6ce1b520788f143e83eeac1222 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Fri, 7 Apr 2006 16:52:42 +0000 Subject: [PATCH] *** empty log message *** --- ase/awk/awk.h | 5 +- ase/awk/err.c | 6 +- ase/awk/parse.c | 4 +- ase/awk/run.c | 385 ++++++++++++++++++++++++++++++++++-------------- ase/awk/tree.h | 47 +++--- 5 files changed, 307 insertions(+), 140 deletions(-) diff --git a/ase/awk/awk.h b/ase/awk/awk.h index 10859729..f2991566 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.44 2006-04-07 04:23:11 bacon Exp $ + * $Id: awk.h,v 1.45 2006-04-07 16:52:42 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -69,7 +69,8 @@ enum /* run time error */ XP_AWK_EDIVBYZERO, /* divide by zero */ - XP_AWK_EOPERAND /* invalid operand */ + XP_AWK_EOPERAND, /* invalid operand */ + XP_AWK_EINTERNAL /* internal error */ }; #ifdef __cplusplus diff --git a/ase/awk/err.c b/ase/awk/err.c index f43b3128..2c3bc02b 100644 --- a/ase/awk/err.c +++ b/ase/awk/err.c @@ -1,5 +1,5 @@ /* - * $Id: err.c,v 1.6 2006-04-07 04:23:11 bacon Exp $ + * $Id: err.c,v 1.7 2006-04-07 16:52:42 bacon Exp $ */ #include @@ -43,7 +43,9 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk) XP_TEXT("l-value required"), XP_TEXT("divide by zero"), - XP_TEXT("invalid operand") + XP_TEXT("invalid operand"), + + XP_TEXT("internal error that should never have happened") }; if (awk->errnum >= 0 && awk->errnum < xp_countof(__errstr)) { diff --git a/ase/awk/parse.c b/ase/awk/parse.c index 06632d1b..3f44098b 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.73 2006-04-07 04:23:11 bacon Exp $ + * $Id: parse.c,v 1.74 2006-04-07 16:52:42 bacon Exp $ */ #include @@ -2194,7 +2194,7 @@ static int __get_token (xp_awk_t* awk) } while (xp_isalpha(c) || c == XP_CHAR('_') || xp_isdigit(c)); - SET_TOKEN_TYPE (awk, __classify_ident(awk, XP_STR_BUF(&awk->token.name))); + SET_TOKEN_TYPE (awk, __classify_ident(awk,XP_STR_BUF(&awk->token.name))); } else if (c == XP_CHAR('\"')) { diff --git a/ase/awk/run.c b/ase/awk/run.c index a0037f14..8d1a3b30 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.37 2006-04-07 04:23:11 bacon Exp $ + * $Id: run.c,v 1.38 2006-04-07 16:52:42 bacon Exp $ */ #include @@ -40,11 +40,11 @@ static int __run_return_statement (xp_awk_t* awk, xp_awk_nde_return_t* nde); static int __run_exit_statement (xp_awk_t* awk, xp_awk_nde_exit_t* nde); static xp_awk_val_t* __eval_expression (xp_awk_t* awk, xp_awk_nde_t* nde); -static xp_awk_val_t* __eval_assignment (xp_awk_t* awk, xp_awk_nde_ass_t* nde); +static xp_awk_val_t* __eval_assignment (xp_awk_t* awk, xp_awk_nde_t* nde); static xp_awk_val_t* __do_assignment ( xp_awk_t* awk, xp_awk_nde_var_t* var, xp_awk_val_t* val); -static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_exp_t* nde); +static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_t* nde); static xp_awk_val_t* __eval_binop_lor ( xp_awk_t* awk, xp_awk_val_t* left, xp_awk_val_t* right); static xp_awk_val_t* __eval_binop_land ( @@ -82,16 +82,29 @@ static xp_awk_val_t* __eval_binop_div ( static xp_awk_val_t* __eval_binop_mod ( xp_awk_t* awk, xp_awk_val_t* left, xp_awk_val_t* right); -static xp_awk_val_t* __eval_unary (xp_awk_t* awk, xp_awk_nde_exp_t* nde); -static xp_awk_val_t* __eval_incpre (xp_awk_t* awk, xp_awk_nde_exp_t* nde); -static xp_awk_val_t* __eval_incpst (xp_awk_t* awk, xp_awk_nde_exp_t* nde); -static xp_awk_val_t* __eval_funccall (xp_awk_t* awk, xp_awk_nde_call_t* nde); +static xp_awk_val_t* __eval_unary (xp_awk_t* awk, xp_awk_nde_t* nde); +static xp_awk_val_t* __eval_incpre (xp_awk_t* awk, xp_awk_nde_t* nde); +static xp_awk_val_t* __eval_incpst (xp_awk_t* awk, xp_awk_nde_t* nde); +static xp_awk_val_t* __eval_call (xp_awk_t* awk, xp_awk_nde_t* nde); +static xp_awk_val_t* __eval_int (xp_awk_t* awk, xp_awk_nde_t* nde); +static xp_awk_val_t* __eval_real (xp_awk_t* awk, xp_awk_nde_t* nde); +static xp_awk_val_t* __eval_str (xp_awk_t* awk, xp_awk_nde_t* nde); +static xp_awk_val_t* __eval_named (xp_awk_t* awk, xp_awk_nde_t* nde); +static xp_awk_val_t* __eval_global (xp_awk_t* awk, xp_awk_nde_t* nde); +static xp_awk_val_t* __eval_local (xp_awk_t* awk, xp_awk_nde_t* nde); +static xp_awk_val_t* __eval_arg (xp_awk_t* awk, xp_awk_nde_t* nde); +static xp_awk_val_t* __eval_namedidx (xp_awk_t* awk, xp_awk_nde_t* nde); +static xp_awk_val_t* __eval_globalidx (xp_awk_t* awk, xp_awk_nde_t* nde); +static xp_awk_val_t* __eval_localidx (xp_awk_t* awk, xp_awk_nde_t* nde); +static xp_awk_val_t* __eval_argidx (xp_awk_t* awk, xp_awk_nde_t* nde); +static xp_awk_val_t* __eval_pos (xp_awk_t* awk, xp_awk_nde_t* nde); static int __raw_push (xp_awk_t* awk, void* val); static void __raw_pop (xp_awk_t* awk); typedef xp_awk_val_t* (*binop_func_t) ( xp_awk_t* awk, xp_awk_val_t* left, xp_awk_val_t* right); +typedef xp_awk_val_t* (*eval_expr_t) (xp_awk_t* awk, xp_awk_nde_t* nde); int __printval (xp_awk_pair_t* pair) { @@ -485,44 +498,81 @@ static int __run_exit_statement (xp_awk_t* awk, xp_awk_nde_exit_t* nde) static xp_awk_val_t* __eval_expression (xp_awk_t* awk, xp_awk_nde_t* nde) { + static eval_expr_t __eval_func[] = + { + /* the order of functions here should match the order + * of node types declared in tree.h */ + __eval_assignment, + __eval_binary, + __eval_unary, + __eval_incpre, + __eval_incpst, + __eval_call, + __eval_int, + __eval_real, + __eval_str, + __eval_named, + __eval_global, + __eval_local, + __eval_arg, + __eval_namedidx, + __eval_globalidx, + __eval_localidx, + __eval_argidx, + __eval_pos + }; + + xp_assert (nde->type >= XP_AWK_NDE_ASS && + (nde->type - XP_AWK_NDE_ASS) < xp_countof(__eval_func)); + return __eval_func[nde->type-XP_AWK_NDE_ASS] (awk, nde); + +#if 0 xp_awk_val_t* val; switch (nde->type) { case XP_AWK_NDE_ASS: val = __eval_assignment (awk, (xp_awk_nde_ass_t*)nde); + if (val == XP_NULL) return XP_NULL; break; case XP_AWK_NDE_EXP_BIN: val = __eval_binary (awk, (xp_awk_nde_exp_t*)nde); + if (val == XP_NULL) return XP_NULL; break; case XP_AWK_NDE_EXP_UNR: val = __eval_unary (awk, (xp_awk_nde_exp_t*)nde); + if (val == XP_NULL) return XP_NULL; break; case XP_AWK_NDE_EXP_INCPRE: val = __eval_incpre (awk, (xp_awk_nde_exp_t*)nde); + if (val == XP_NULL) return XP_NULL; break; case XP_AWK_NDE_EXP_INCPST: val = __eval_incpst (awk, (xp_awk_nde_exp_t*)nde); + if (val == XP_NULL) return XP_NULL; + break; + + case XP_AWK_NDE_INT: + val = xp_awk_makeintval ( + awk, ((xp_awk_nde_int_t*)nde)->val); + if (val == XP_NULL) PANIC (awk, XP_ENOMEM); + break; + + case XP_AWK_NDE_REAL: + val = xp_awk_makerealval ( + awk, ((xp_awk_nde_real_t*)nde)->val); + if (val == XP_NULL) PANIC (awk, XP_ENOMEM); break; case XP_AWK_NDE_STR: val = xp_awk_makestrval ( ((xp_awk_nde_str_t*)nde)->buf, ((xp_awk_nde_str_t*)nde)->len); - break; - - case XP_AWK_NDE_INT: - val = xp_awk_makeintval ( - awk, ((xp_awk_nde_int_t*)nde)->val); - break; - - case XP_AWK_NDE_REAL: - val = xp_awk_makerealval ( - awk, ((xp_awk_nde_real_t*)nde)->val); + if (val == XP_NULL) PANIC (awk, XP_ENOMEM); break; case XP_AWK_NDE_NAMED: @@ -557,42 +607,48 @@ static xp_awk_val_t* __eval_expression (xp_awk_t* awk, xp_awk_nde_t* nde) break; case XP_AWK_NDE_NAMEDIDX: + // TODO: break; case XP_AWK_NDE_GLOBALIDX: + // TODO: break; case XP_AWK_NDE_LOCALIDX: + // TODO: break; case XP_AWK_NDE_ARGIDX: + // TODO: break; case XP_AWK_NDE_POS: + // TODO: break; case XP_AWK_NDE_CALL: - val = __eval_funccall(awk, (xp_awk_nde_call_t*)nde); + val = __eval_call (awk, (xp_awk_nde_call_t*)nde); if (val == XP_NULL) return XP_NULL; break; default: - /* somthing wrong. internal error */ - /* TODO: set the error code instead of assertion below */ - xp_assert (!"should never happen"); - return XP_NULL; + xp_assert (!"should never happen - invalid node type"); + PANIC (awk, XP_AWK_EINTERNAL); } + return val; +#endif } -static xp_awk_val_t* __eval_assignment (xp_awk_t* awk, xp_awk_nde_ass_t* nde) +static xp_awk_val_t* __eval_assignment (xp_awk_t* awk, xp_awk_nde_t* nde) { xp_awk_val_t* val; + xp_awk_nde_ass_t* ass = (xp_awk_nde_ass_t*)nde; - xp_assert (nde->left != XP_NULL && nde->right != XP_NULL); + xp_assert (ass->left != XP_NULL && ass->right != XP_NULL); - val = __eval_expression(awk, nde->right); + val = __eval_expression(awk, ass->right); if (val == XP_NULL) return XP_NULL; - return __do_assignment (awk, (xp_awk_nde_var_t*)nde->left, val); + return __do_assignment (awk, (xp_awk_nde_var_t*)ass->left, val); } static xp_awk_val_t* __do_assignment ( @@ -649,29 +705,31 @@ static xp_awk_val_t* __do_assignment ( } else if (var->type == XP_AWK_NDE_NAMEDIDX) { + // TODO: } else if (var->type == XP_AWK_NDE_GLOBALIDX) { + // TODO: } else if (var->type == XP_AWK_NDE_LOCALIDX) { + // TODO: } else if (var->type == XP_AWK_NDE_ARGIDX) { + // TODO: } else { - /* this should never be reached. something wrong */ - // TODO: set errnum .... error handling - return XP_NULL; + xp_assert (!"should never happen - invalid variable type"); + PANIC (awk, XP_AWK_EINTERNAL); } return val; } -static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_exp_t* nde) +static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_t* nde) { - xp_awk_val_t* left, * right, * res; static binop_func_t __binop_func[] = { __eval_binop_lor, @@ -696,15 +754,17 @@ static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_exp_t* nde) __eval_binop_div, __eval_binop_mod }; + xp_awk_nde_exp_t* exp = (xp_awk_nde_exp_t*)nde; + xp_awk_val_t* left, * right, * res; - xp_assert (nde->type == XP_AWK_NDE_EXP_BIN); + xp_assert (exp->type == XP_AWK_NDE_EXP_BIN); - left = __eval_expression (awk, nde->left); + left = __eval_expression (awk, exp->left); if (left == XP_NULL) return XP_NULL; xp_awk_refupval (left); - right = __eval_expression (awk, nde->right); + right = __eval_expression (awk, exp->right); if (right == XP_NULL) { xp_awk_refdownval (awk, left); @@ -713,11 +773,10 @@ static xp_awk_val_t* __eval_binary (xp_awk_t* awk, xp_awk_nde_exp_t* nde) xp_awk_refupval (right); - xp_assert (nde->opcode >= 0 && - nde->opcode < xp_countof(__binop_func)); + xp_assert (exp->opcode >= 0 && + exp->opcode < xp_countof(__binop_func)); - res = __binop_func[nde->opcode] (awk, left, right); - // TODO: do i need to handle error here or in binop_func??? + res = __binop_func[exp->opcode] (awk, left, right); xp_awk_refdownval (awk, left); xp_awk_refdownval (awk, right); @@ -1382,20 +1441,21 @@ static xp_awk_val_t* __eval_binop_mod ( return res; } -static xp_awk_val_t* __eval_unary (xp_awk_t* awk, xp_awk_nde_exp_t* nde) +static xp_awk_val_t* __eval_unary (xp_awk_t* awk, xp_awk_nde_t* nde) { xp_awk_val_t* left, * res; + xp_awk_nde_exp_t* exp = (xp_awk_nde_exp_t*)nde; - xp_assert (nde->type == XP_AWK_NDE_EXP_UNR); - xp_assert (nde->left != XP_NULL && nde->right == XP_NULL); + xp_assert (exp->type == XP_AWK_NDE_EXP_UNR); + xp_assert (exp->left != XP_NULL && exp->right == XP_NULL); - left = __eval_expression (awk, nde->left); + left = __eval_expression (awk, exp->left); if (left == XP_NULL) return XP_NULL; xp_awk_refupval (left); // TODO: a lot of things to do.... - if (nde->opcode == XP_AWK_UNROP_PLUS) + if (exp->opcode == XP_AWK_UNROP_PLUS) { if (left->type == XP_AWK_VAL_INT) { @@ -1416,7 +1476,7 @@ static xp_awk_val_t* __eval_unary (xp_awk_t* awk, xp_awk_nde_exp_t* nde) return XP_NULL; } } - else if (nde->opcode == XP_AWK_UNROP_MINUS) + else if (exp->opcode == XP_AWK_UNROP_MINUS) { if (left->type == XP_AWK_VAL_INT) { @@ -1437,7 +1497,7 @@ static xp_awk_val_t* __eval_unary (xp_awk_t* awk, xp_awk_nde_exp_t* nde) return XP_NULL; } } - else if (nde->opcode == XP_AWK_UNROP_NOT) + else if (exp->opcode == XP_AWK_UNROP_NOT) { if (left->type == XP_AWK_VAL_INT) { @@ -1458,7 +1518,7 @@ static xp_awk_val_t* __eval_unary (xp_awk_t* awk, xp_awk_nde_exp_t* nde) return XP_NULL; } } - else if (nde->opcode == XP_AWK_UNROP_BNOT) + else if (exp->opcode == XP_AWK_UNROP_BNOT) { if (left->type == XP_AWK_VAL_INT) { @@ -1478,184 +1538,203 @@ static xp_awk_val_t* __eval_unary (xp_awk_t* awk, xp_awk_nde_exp_t* nde) return res; } -static xp_awk_val_t* __eval_incpre (xp_awk_t* awk, xp_awk_nde_exp_t* nde) +static xp_awk_val_t* __eval_incpre (xp_awk_t* awk, xp_awk_nde_t* nde) { xp_awk_val_t* left, * res; + xp_awk_nde_exp_t* exp = (xp_awk_nde_exp_t*)nde; - xp_assert (nde->type == XP_AWK_NDE_EXP_INCPRE); - xp_assert (nde->left != XP_NULL && nde->right == XP_NULL); + xp_assert (exp->type == XP_AWK_NDE_EXP_INCPRE); + xp_assert (exp->left != XP_NULL && exp->right == XP_NULL); /* ugly. but let's keep going this way for the time being */ - if (nde->left->type != XP_AWK_NDE_ARG && - nde->left->type != XP_AWK_NDE_ARGIDX && - nde->left->type != XP_AWK_NDE_NAMED && - nde->left->type != XP_AWK_NDE_NAMEDIDX && - nde->left->type != XP_AWK_NDE_GLOBAL && - nde->left->type != XP_AWK_NDE_GLOBALIDX && - nde->left->type != XP_AWK_NDE_LOCAL && - nde->left->type != XP_AWK_NDE_LOCALIDX) + if (exp->left->type != XP_AWK_NDE_ARG && + exp->left->type != XP_AWK_NDE_ARGIDX && + exp->left->type != XP_AWK_NDE_NAMED && + exp->left->type != XP_AWK_NDE_NAMEDIDX && + exp->left->type != XP_AWK_NDE_GLOBAL && + exp->left->type != XP_AWK_NDE_GLOBALIDX && + exp->left->type != XP_AWK_NDE_LOCAL && + exp->left->type != XP_AWK_NDE_LOCALIDX) { - // TOOD: error handling.. - return XP_NULL; + PANIC (awk, XP_AWK_EOPERAND); } - left = __eval_expression (awk, nde->left); // TODO: do it differently + left = __eval_expression (awk, exp->left); // TODO: do it differently if (left == XP_NULL) return XP_NULL; xp_awk_refupval (left); - if (nde->opcode == XP_AWK_UNROP_PLUS) + if (exp->opcode == XP_AWK_INCOP_PLUS) { if (left->type == XP_AWK_VAL_INT) { xp_long_t r = ((xp_awk_val_int_t*)left)->val; res = xp_awk_makeintval (awk, r + 1); - // TODO: error handling + if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); } else if (left->type == XP_AWK_VAL_REAL) { xp_real_t r = ((xp_awk_val_real_t*)left)->val; res = xp_awk_makerealval (awk, r + 1.0); - // TODO: error handling + if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); } else { - // TOOD: error handling.. xp_awk_refdownval (awk, left); - return XP_NULL; + PANIC (awk, XP_AWK_EOPERAND); } } - else if (nde->opcode == XP_AWK_UNROP_MINUS) + else if (exp->opcode == XP_AWK_INCOP_MINUS) { if (left->type == XP_AWK_VAL_INT) { xp_long_t r = ((xp_awk_val_int_t*)left)->val; res = xp_awk_makeintval (awk, r - 1); - // TODO: error handling + if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); } else if (left->type == XP_AWK_VAL_REAL) { xp_real_t r = ((xp_awk_val_real_t*)left)->val; res = xp_awk_makerealval (awk, r - 1.0); - // TODO: error handling + if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); } else { - // TOOD: error handling.. xp_awk_refdownval (awk, left); - return XP_NULL; + PANIC (awk, XP_AWK_EOPERAND); } } + else + { + xp_assert (!"should never happen - invalid opcode"); + xp_awk_refdownval (awk, left); + PANIC (awk, XP_AWK_EINTERNAL); + } if (__do_assignment (awk, - (xp_awk_nde_var_t*)nde->left, res) == XP_NULL) + (xp_awk_nde_var_t*)exp->left, res) == XP_NULL) { - // TODO: error handling xp_awk_refdownval (awk, left); return XP_NULL; } xp_awk_refdownval (awk, left); - return res; } -static xp_awk_val_t* __eval_incpst (xp_awk_t* awk, xp_awk_nde_exp_t* nde) +static xp_awk_val_t* __eval_incpst (xp_awk_t* awk, xp_awk_nde_t* nde) { xp_awk_val_t* left, * res, * res2; + xp_awk_nde_exp_t* exp = (xp_awk_nde_exp_t*)nde; - xp_assert (nde->type == XP_AWK_NDE_EXP_INCPST); - xp_assert (nde->left != XP_NULL && nde->right == XP_NULL); + xp_assert (exp->type == XP_AWK_NDE_EXP_INCPST); + xp_assert (exp->left != XP_NULL && exp->right == XP_NULL); /* ugly. but let's keep going this way for the time being */ - if (nde->left->type != XP_AWK_NDE_ARG && - nde->left->type != XP_AWK_NDE_ARGIDX && - nde->left->type != XP_AWK_NDE_NAMED && - nde->left->type != XP_AWK_NDE_NAMEDIDX && - nde->left->type != XP_AWK_NDE_GLOBAL && - nde->left->type != XP_AWK_NDE_GLOBALIDX && - nde->left->type != XP_AWK_NDE_LOCAL && - nde->left->type != XP_AWK_NDE_LOCALIDX) // TODO: what about NDE_POS? + if (exp->left->type != XP_AWK_NDE_ARG && + exp->left->type != XP_AWK_NDE_ARGIDX && + exp->left->type != XP_AWK_NDE_NAMED && + exp->left->type != XP_AWK_NDE_NAMEDIDX && + exp->left->type != XP_AWK_NDE_GLOBAL && + exp->left->type != XP_AWK_NDE_GLOBALIDX && + exp->left->type != XP_AWK_NDE_LOCAL && + exp->left->type != XP_AWK_NDE_LOCALIDX) { - // TOOD: error handling.. - return XP_NULL; + PANIC (awk, XP_AWK_EOPERAND); } - left = __eval_expression (awk, nde->left); // TODO: do it differently + left = __eval_expression (awk, exp->left); // TODO: do it differently if (left == XP_NULL) return XP_NULL; xp_awk_refupval (left); - left = __eval_expression (awk, nde->left); // TODO: get the actual target... - if (left == XP_NULL) return XP_NULL; - - xp_awk_refupval (left); - - if (nde->opcode == XP_AWK_UNROP_PLUS) + if (exp->opcode == XP_AWK_INCOP_PLUS) { if (left->type == XP_AWK_VAL_INT) { xp_long_t r = ((xp_awk_val_int_t*)left)->val; res = xp_awk_makeintval (awk, r); - // TODO: error handling + if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); res2 = xp_awk_makeintval (awk, r + 1); - // TODO: error handling + if (res2 == XP_NULL) + { + xp_awk_freeval (awk, res); + PANIC (awk, XP_AWK_ENOMEM); + } } else if (left->type == XP_AWK_VAL_REAL) { xp_real_t r = ((xp_awk_val_real_t*)left)->val; res = xp_awk_makerealval (awk, r); - // TODO: error handling + if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); res2 = xp_awk_makerealval (awk, r + 1.0); - // TODO: error handling + if (res2 == XP_NULL) + { + xp_awk_freeval (awk, res); + PANIC (awk, XP_AWK_ENOMEM); + } } else { xp_awk_refdownval (awk, left); - return XP_NULL; + PANIC (awk, XP_AWK_EOPERAND); } } - else if (nde->opcode == XP_AWK_UNROP_MINUS) + else if (exp->opcode == XP_AWK_INCOP_MINUS) { if (left->type == XP_AWK_VAL_INT) { xp_long_t r = ((xp_awk_val_int_t*)left)->val; res = xp_awk_makeintval (awk, r); - // TODO: error handling + if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); + res2 = xp_awk_makeintval (awk, r - 1); - // TODO: error handling + if (res2 == XP_NULL) + { + xp_awk_freeval (awk, res); + PANIC (awk, XP_AWK_ENOMEM); + } } else if (left->type == XP_AWK_VAL_REAL) { xp_real_t r = ((xp_awk_val_real_t*)left)->val; res = xp_awk_makerealval (awk, r); - // TODO: error handling + if (res == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); + res2 = xp_awk_makerealval (awk, r - 1.0); - // TODO: error handling + if (res2 == XP_NULL) + { + xp_awk_freeval (awk, res); + PANIC (awk, XP_AWK_ENOMEM); + } } else { xp_awk_refdownval (awk, left); - return XP_NULL; + PANIC (awk, XP_AWK_EOPERAND); } } + else + { + xp_assert (!"should never happen - invalid opcode"); + xp_awk_refdownval (awk, left); + PANIC (awk, XP_AWK_EINTERNAL); + } if (__do_assignment (awk, - (xp_awk_nde_var_t*)nde->left, res2) == XP_NULL) + (xp_awk_nde_var_t*)exp->left, res2) == XP_NULL) { - // TODO: error handling xp_awk_refdownval (awk, left); return XP_NULL; } xp_awk_refdownval (awk, left); - return res; } -static xp_awk_val_t* __eval_funccall (xp_awk_t* awk, xp_awk_nde_call_t* nde) +static xp_awk_val_t* __eval_call (xp_awk_t* awk, xp_awk_nde_t* nde) { xp_awk_func_t* func; xp_awk_pair_t* pair; @@ -1663,8 +1742,9 @@ static xp_awk_val_t* __eval_funccall (xp_awk_t* awk, xp_awk_nde_call_t* nde) xp_size_t nargs, i; xp_awk_val_t* v; xp_size_t saved_stack_top; + xp_awk_nde_call_t* call = (xp_awk_nde_call_t*)nde; - pair = xp_awk_map_get (&awk->tree.funcs, nde->name); + pair = xp_awk_map_get (&awk->tree.funcs, call->name); if (pair == XP_NULL) return XP_NULL; /* no such function */ /* @@ -1721,7 +1801,7 @@ static xp_awk_val_t* __eval_funccall (xp_awk_t* awk, xp_awk_nde_call_t* nde) } nargs = 0; - p = nde->args; + p = call->args; while (p != XP_NULL) { v = __eval_expression(awk,p); @@ -1788,6 +1868,91 @@ static xp_awk_val_t* __eval_funccall (xp_awk_t* awk, xp_awk_nde_call_t* nde) return v; } +static xp_awk_val_t* __eval_int (xp_awk_t* awk, xp_awk_nde_t* nde) +{ + xp_awk_val_t* val; + val = xp_awk_makeintval ( + awk, ((xp_awk_nde_int_t*)nde)->val); + if (val == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); + return val; +} + +static xp_awk_val_t* __eval_real (xp_awk_t* awk, xp_awk_nde_t* nde) +{ + xp_awk_val_t* val; + val = xp_awk_makerealval ( + awk, ((xp_awk_nde_real_t*)nde)->val); + if (val == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); + return val; +} + +static xp_awk_val_t* __eval_str (xp_awk_t* awk, xp_awk_nde_t* nde) +{ + xp_awk_val_t* val; + val = xp_awk_makestrval ( + ((xp_awk_nde_str_t*)nde)->buf, + ((xp_awk_nde_str_t*)nde)->len); + if (val == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); + return val; +} + +static xp_awk_val_t* __eval_named (xp_awk_t* awk, xp_awk_nde_t* nde) +{ + xp_awk_pair_t* pair; + xp_awk_nde_var_t* tgt = (xp_awk_nde_var_t*)nde; + + pair = xp_awk_map_get(&awk->run.named,tgt->id.name); + return (pair == XP_NULL)? xp_awk_val_nil: pair->val; +} + +static xp_awk_val_t* __eval_global (xp_awk_t* awk, xp_awk_nde_t* nde) +{ + xp_awk_nde_var_t* tgt = (xp_awk_nde_var_t*)nde; + return STACK_GLOBAL(awk,tgt->id.idxa); +} + +static xp_awk_val_t* __eval_local (xp_awk_t* awk, xp_awk_nde_t* nde) +{ + xp_awk_nde_var_t* tgt = (xp_awk_nde_var_t*)nde; + return STACK_LOCAL(awk,tgt->id.idxa); +} + +static xp_awk_val_t* __eval_arg (xp_awk_t* awk, xp_awk_nde_t* nde) +{ + xp_awk_nde_var_t* tgt = (xp_awk_nde_var_t*)nde; + return STACK_ARG(awk,tgt->id.idxa); +} + +static xp_awk_val_t* __eval_namedidx (xp_awk_t* awk, xp_awk_nde_t* nde) +{ + // TODO: + return XP_NULL; +} + +static xp_awk_val_t* __eval_globalidx (xp_awk_t* awk, xp_awk_nde_t* nde) +{ + // TODO: + return XP_NULL; +} + +static xp_awk_val_t* __eval_localidx (xp_awk_t* awk, xp_awk_nde_t* nde) +{ + // TODO: + return XP_NULL; +} + +static xp_awk_val_t* __eval_argidx (xp_awk_t* awk, xp_awk_nde_t* nde) +{ + // TODO: + return XP_NULL; +} + +static xp_awk_val_t* __eval_pos (xp_awk_t* awk, xp_awk_nde_t* nde) +{ + // TODO: + return XP_NULL; +} + static int __raw_push (xp_awk_t* awk, void* val) { if (awk->run.stack_top >= awk->run.stack_limit) diff --git a/ase/awk/tree.h b/ase/awk/tree.h index 52c37e86..9ece6935 100644 --- a/ase/awk/tree.h +++ b/ase/awk/tree.h @@ -1,5 +1,5 @@ /* - * $Id: tree.h,v 1.29 2006-04-02 12:41:14 bacon Exp $ + * $Id: tree.h,v 1.30 2006-04-07 16:52:42 bacon Exp $ */ #ifndef _XP_AWK_TREE_H_ @@ -13,28 +13,8 @@ enum { XP_AWK_NDE_NULL, + /* statement */ XP_AWK_NDE_BLK, - XP_AWK_NDE_ASS, - - XP_AWK_NDE_EXP_BIN, - XP_AWK_NDE_EXP_UNR, - XP_AWK_NDE_EXP_INCPRE, - XP_AWK_NDE_EXP_INCPST, - - XP_AWK_NDE_INT, - XP_AWK_NDE_REAL, - XP_AWK_NDE_STR, - XP_AWK_NDE_NAMED, - XP_AWK_NDE_NAMEDIDX, - XP_AWK_NDE_GLOBAL, - XP_AWK_NDE_GLOBALIDX, - XP_AWK_NDE_LOCAL, - XP_AWK_NDE_LOCALIDX, - XP_AWK_NDE_ARG, - XP_AWK_NDE_ARGIDX, - XP_AWK_NDE_POS, - XP_AWK_NDE_CALL, - XP_AWK_NDE_IF, XP_AWK_NDE_WHILE, XP_AWK_NDE_DOWHILE, @@ -43,9 +23,28 @@ enum XP_AWK_NDE_CONTINUE, XP_AWK_NDE_RETURN, XP_AWK_NDE_EXIT, - XP_AWK_NDE_NEXT, - XP_AWK_NDE_NEXTFILE + XP_AWK_NDE_NEXTFILE, + + /* expression */ + XP_AWK_NDE_ASS, + XP_AWK_NDE_EXP_BIN, + XP_AWK_NDE_EXP_UNR, + XP_AWK_NDE_EXP_INCPRE, + XP_AWK_NDE_EXP_INCPST, + XP_AWK_NDE_CALL, + XP_AWK_NDE_INT, + XP_AWK_NDE_REAL, + XP_AWK_NDE_STR, + XP_AWK_NDE_NAMED, + XP_AWK_NDE_GLOBAL, + XP_AWK_NDE_LOCAL, + XP_AWK_NDE_ARG, + XP_AWK_NDE_NAMEDIDX, + XP_AWK_NDE_GLOBALIDX, + XP_AWK_NDE_LOCALIDX, + XP_AWK_NDE_ARGIDX, + XP_AWK_NDE_POS }; typedef struct xp_awk_func_t xp_awk_func_t;