From abc5ea4502d0591f82af27584847605622db4f33 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Wed, 5 Apr 2006 15:56:20 +0000 Subject: [PATCH] *** empty log message *** --- ase/awk/awk.h | 7 ++++-- ase/awk/err.c | 6 +++-- ase/awk/parse.c | 46 ++++++++++++++++++++++------------ ase/awk/run.c | 65 +++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 97 insertions(+), 27 deletions(-) diff --git a/ase/awk/awk.h b/ase/awk/awk.h index 73069181..0cdd5b1f 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.41 2006-04-04 16:03:14 bacon Exp $ + * $Id: awk.h,v 1.42 2006-04-05 15:56:20 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -63,7 +63,10 @@ enum XP_AWK_EDUPVAR, /* duplicate variable name */ XP_AWK_EDUPNAME, /* duplicate name - function, variable, etc */ XP_AWK_EUNDEF, /* undefined identifier */ - XP_AWK_ELVALUE /* l-value required */ + XP_AWK_ELVALUE, /* l-value required */ + + /* run time error */ + XP_AWK_EDIVBYZERO /* divide by zero */ }; #ifdef __cplusplus diff --git a/ase/awk/err.c b/ase/awk/err.c index e5edc97e..8768226b 100644 --- a/ase/awk/err.c +++ b/ase/awk/err.c @@ -1,5 +1,5 @@ /* - * $Id: err.c,v 1.3 2006-04-02 12:41:14 bacon Exp $ + * $Id: err.c,v 1.4 2006-04-05 15:56:20 bacon Exp $ */ #include @@ -38,7 +38,9 @@ const xp_char_t* xp_awk_geterrstr (xp_awk_t* awk) XP_TEXT("duplicate variable name"), XP_TEXT("duplicate name"), XP_TEXT("undefined identifier"), - XP_TEXT("l-value required") + XP_TEXT("l-value required"), + + XP_TEXT("divide by zero") }; if (awk->errnum >= 0 && awk->errnum < xp_countof(__errstr)) { diff --git a/ase/awk/parse.c b/ase/awk/parse.c index c0216368..40af3404 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.71 2006-04-04 16:22:01 bacon Exp $ + * $Id: parse.c,v 1.72 2006-04-05 15:56:20 bacon Exp $ */ #include @@ -738,7 +738,7 @@ static xp_awk_nde_t* __parse_block (xp_awk_t* awk, xp_bool_t is_top) block->next = XP_NULL; block->body = head; -/* TODO: not only local variables but also etsted blocks, +/* TODO: not only local variables but also nested blocks, unless it is part of other constructs such as if, can be promoted and merged to top-level block */ @@ -840,7 +840,8 @@ static xp_awk_t* __collect_locals (xp_awk_t* awk, xp_size_t nlocals) /* check if it conflicts with other local variable names */ if (xp_awk_tab_find(&awk->parse.locals, local, - ((awk->opt.parse & XP_AWK_SHADING)? nlocals: 0)) != (xp_size_t)-1) { + ((awk->opt.parse & XP_AWK_SHADING)? nlocals: 0)) != (xp_size_t)-1) + { PANIC (awk, XP_AWK_EDUPVAR); } @@ -1103,24 +1104,34 @@ static xp_awk_nde_t* __parse_binary_expr ( if (opcode == XP_AWK_BINOP_PLUS) l += r; else if (opcode == XP_AWK_BINOP_MINUS) l -= r; else if (opcode == XP_AWK_BINOP_MUL) l *= r; - else if (opcode == XP_AWK_BINOP_DIV) l /= r; - else if (opcode == XP_AWK_BINOP_MOD) l %= r; + else if (opcode == XP_AWK_BINOP_DIV && r != 0) l /= r; + else if (opcode == XP_AWK_BINOP_MOD && r != 0) l %= r; else goto skip_constant_folding; xp_awk_clrpt (right); ((xp_awk_nde_int_t*)left)->val = l; continue; } - /* TODO: else if (left->type == XP_AWK_NDE_REAL && right->type == XP_AWK_NDE_REAL) { + xp_real_t l, r; + + l = ((xp_awk_nde_real_t*)left)->val; + r = ((xp_awk_nde_real_t*)right)->val; + + /* TODO: more operators */ + if (opcode == XP_AWK_BINOP_PLUS) l += r; + else if (opcode == XP_AWK_BINOP_MINUS) l -= r; + else if (opcode == XP_AWK_BINOP_MUL) l *= r; + else if (opcode == XP_AWK_BINOP_DIV) l /= r; + else goto skip_constant_folding; + + xp_awk_clrpt (right); + ((xp_awk_nde_real_t*)left)->val = l; + continue; } - else if (left->type == XP_AWK_NDE_STR && - right->type == XP_AWK_NDE_STR) - { - // TODO: string concatenation operator.... - } */ + // TODO: enhance constant folding more... skip_constant_folding: nde = (xp_awk_nde_exp_t*)xp_malloc(xp_sizeof(xp_awk_nde_exp_t)); @@ -1362,7 +1373,8 @@ static xp_awk_nde_t* __parse_increment (xp_awk_t* awk) static xp_awk_nde_t* __parse_primary (xp_awk_t* awk) { - if (MATCH(awk,TOKEN_IDENT)) { + if (MATCH(awk,TOKEN_IDENT)) + { xp_char_t* name_dup; name_dup = (xp_char_t*)xp_strdup(XP_STR_BUF(&awk->token.name)); @@ -1480,7 +1492,8 @@ static xp_awk_nde_t* __parse_primary (xp_awk_t* awk) return (xp_awk_nde_t*)nde; } - else if (MATCH(awk,TOKEN_REAL)) { + else if (MATCH(awk,TOKEN_REAL)) + { xp_awk_nde_real_t* nde; nde = (xp_awk_nde_real_t*) @@ -1503,7 +1516,8 @@ static xp_awk_nde_t* __parse_primary (xp_awk_t* awk) return (xp_awk_nde_t*)nde; } - else if (MATCH(awk,TOKEN_STRING)) { + else if (MATCH(awk,TOKEN_STRING)) + { xp_awk_nde_str_t* nde; nde = (xp_awk_nde_str_t*)xp_malloc(xp_sizeof(xp_awk_nde_str_t)); @@ -2476,11 +2490,11 @@ static int __get_number (xp_awk_t* awk) else if (c != '.') { /* octal number */ - do + while (c >= XP_CHAR('0') && c <= XP_CHAR('7')) { ADD_TOKEN_CHAR (awk, c); GET_CHAR_TO (awk, c); - } while (c >= XP_CHAR('0') && c <= XP_CHAR('7')); + } return 0; } diff --git a/ase/awk/run.c b/ase/awk/run.c index 80c24013..2f82d632 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.34 2006-04-04 06:26:56 bacon Exp $ + * $Id: run.c,v 1.35 2006-04-05 15:56:20 bacon Exp $ */ #include @@ -26,6 +26,9 @@ #define EXIT_FUNCTION 3 #define EXIT_GLOBAL 4 +#define PANIC(awk,code) \ + do { (awk)->errnum = (code); return XP_NULL; } while (0) + static int __run_block (xp_awk_t* awk, xp_awk_nde_blk_t* nde); static int __run_statement (xp_awk_t* awk, xp_awk_nde_t* nde); static int __run_if_statement (xp_awk_t* awk, xp_awk_nde_if_t* nde); @@ -1067,12 +1070,50 @@ static xp_awk_val_t* __eval_binop_div ( if (left->type == XP_AWK_VAL_INT && right->type == XP_AWK_VAL_INT) { - xp_long_t r = - ((xp_awk_val_int_t*)left)->val / - ((xp_awk_val_int_t*)right)->val; + xp_long_t r; + + if (((xp_awk_val_int_t*)right)->val == 0) + { + PANIC (awk, XP_AWK_EDIVBYZERO); + } + + r = ((xp_awk_val_int_t*)left)->val / + ((xp_awk_val_int_t*)right)->val; res = xp_awk_makeintval (awk, r); // TOOD: error handling } + else if (left->type == XP_AWK_VAL_REAL && + right->type == XP_AWK_VAL_REAL) + { + xp_real_t r; + + r = ((xp_awk_val_real_t*)left)->val / + ((xp_awk_val_real_t*)right)->val; + res = xp_awk_makerealval (awk, r); + // TOOD: error handling + } + else if (left->type == XP_AWK_VAL_INT && + right->type == XP_AWK_VAL_REAL) + { + xp_real_t r; + + r = ((xp_awk_val_int_t*)left)->val / + ((xp_awk_val_real_t*)right)->val; + res = xp_awk_makerealval (awk, r); + } + else if (left->type == XP_AWK_VAL_REAL && + right->type == XP_AWK_VAL_INT) + { + xp_real_t r; + + r = ((xp_awk_val_real_t*)left)->val / + ((xp_awk_val_int_t*)right)->val; + res = xp_awk_makerealval (awk, r); + } + else + { + // TODO: invalid operands for div + } return res; } @@ -1085,12 +1126,22 @@ static xp_awk_val_t* __eval_binop_mod ( if (left->type == XP_AWK_VAL_INT && right->type == XP_AWK_VAL_INT) { - xp_long_t r = - ((xp_awk_val_int_t*)left)->val % - ((xp_awk_val_int_t*)right)->val; + xp_long_t r; + + if (((xp_awk_val_int_t*)right)->val == 0) + { + PANIC (awk, XP_AWK_EDIVBYZERO); + } + + r = ((xp_awk_val_int_t*)left)->val % + ((xp_awk_val_int_t*)right)->val; res = xp_awk_makeintval (awk, r); // TOOD: error handling } + else + { + // TODO: mod is only for integers + } return res; }