diff --git a/qse/lib/awk/misc.c b/qse/lib/awk/misc.c index 52ccfd5e..e9f8f095 100644 --- a/qse/lib/awk/misc.c +++ b/qse/lib/awk/misc.c @@ -1,5 +1,5 @@ /* - * $Id: misc.c 510 2011-07-20 16:17:16Z hyunghwan.chung $ + * $Id: misc.c 514 2011-07-22 15:37:46Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -1108,3 +1108,36 @@ void qse_awk_rtx_freemem (qse_awk_rtx_t* rtx, void* ptr) qse_awk_freemem (rtx->awk, ptr); } +int qse_awk_sprintlong ( + qse_awk_t* awk, qse_char_t* buf, qse_size_t len, qse_long_t num) +{ + return awk->prm.sprintf ( + awk, buf, len, + #if QSE_SIZEOF_LONG_LONG > 0 + QSE_T("%lld"), (long long)num + #elif QSE_SIZEOF___INT64 > 0 + QSE_T("%I64d"), (__int64)num + #elif QSE_SIZEOF_LONG > 0 + QSE_T("%ld"), (long)num + #elif QSE_SIZEOF_INT > 0 + QSE_T("%d"), (int)num + #else + #error unsupported size + #endif + ); +} + +int qse_awk_sprintreal ( + qse_awk_t* awk, qse_char_t* buf, qse_size_t len, qse_real_t num) +{ + return awk->prm.sprintf ( + awk, buf, len, + #if QSE_SIZEOF_LONG_DOUBLE > 0 + QSE_T("%Lf"), (long long)num + #elif QSE_SIZEOF_DOUBLE > 0 + QSE_T("%f"), (double)num + #else + #error unsupported size + #endif + ); +} diff --git a/qse/lib/awk/misc.h b/qse/lib/awk/misc.h index 998aa594..633346f5 100644 --- a/qse/lib/awk/misc.h +++ b/qse/lib/awk/misc.h @@ -1,5 +1,5 @@ /* - * $Id: misc.h 462 2011-05-18 14:36:40Z hyunghwan.chung $ + * $Id: misc.h 514 2011-07-22 15:37:46Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -76,6 +76,22 @@ int qse_awk_matchrex ( qse_cstr_t* match, qse_awk_errnum_t* errnum ); +int qse_awk_sprintlong ( + qse_awk_t* awk, + qse_char_t* buf, + qse_size_t len, + qse_long_t num +); + + +int qse_awk_sprintreal ( + qse_awk_t* awk, + qse_char_t* buf, + qse_size_t len, + qse_real_t num +); + + #ifdef __cplusplus } #endif diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index 6a87c0d7..df09e616 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c 486 2011-05-29 15:22:08Z hyunghwan.chung $ + * $Id: parse.c 514 2011-07-22 15:37:46Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -3351,6 +3351,8 @@ static qse_awk_nde_t* parse_binary ( qse_awk_loc_t rloc; const binmap_t* p = binmap; qse_bool_t matched = QSE_FALSE; + int fold; + qse_long_t folded_l; while (p->token != TOK_EOF) { @@ -3382,24 +3384,70 @@ static qse_awk_nde_t* parse_binary ( return QSE_NULL; } - nde = (qse_awk_nde_exp_t*) QSE_AWK_ALLOC ( - awk, QSE_SIZEOF(qse_awk_nde_exp_t)); - if (nde == QSE_NULL) + fold = 0; + if (left->type == QSE_AWK_NDE_INT && + right->type == QSE_AWK_NDE_INT) { - qse_awk_clrpt (awk, right); - qse_awk_clrpt (awk, left); - SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc); - return QSE_NULL; + fold = 1; + switch (opcode) + { + case QSE_AWK_BINOP_PLUS: + folded_l = ((qse_awk_nde_int_t*)left)->val + ((qse_awk_nde_int_t*)right)->val; + break; + + case QSE_AWK_BINOP_MINUS: + folded_l = ((qse_awk_nde_int_t*)left)->val - ((qse_awk_nde_int_t*)right)->val; + break; + + case QSE_AWK_BINOP_MUL: + folded_l = ((qse_awk_nde_int_t*)left)->val * ((qse_awk_nde_int_t*)right)->val; + break; + + case QSE_AWK_BINOP_IDIV: + folded_l = ((qse_awk_nde_int_t*)left)->val / ((qse_awk_nde_int_t*)right)->val; + break; + + case QSE_AWK_BINOP_MOD: + folded_l = ((qse_awk_nde_int_t*)left)->val % ((qse_awk_nde_int_t*)right)->val; + break; + + default: + fold = 0; + } } - nde->type = QSE_AWK_NDE_EXP_BIN; - nde->loc = *xloc; - nde->next = QSE_NULL; - nde->opcode = opcode; - nde->left = left; - nde->right = right; + if (fold) + { + qse_awk_clrpt (awk, right); + ((qse_awk_nde_int_t*)left)->val = folded_l; + if (((qse_awk_nde_int_t*)left)->str) + { + QSE_AWK_FREE (awk, ((qse_awk_nde_int_t*)left)->str); + ((qse_awk_nde_int_t*)left)->str = QSE_NULL; + ((qse_awk_nde_int_t*)left)->len = 0; + } + } + else + { + nde = (qse_awk_nde_exp_t*) QSE_AWK_ALLOC ( + awk, QSE_SIZEOF(qse_awk_nde_exp_t)); + if (nde == QSE_NULL) + { + qse_awk_clrpt (awk, right); + qse_awk_clrpt (awk, left); + SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc); + return QSE_NULL; + } - left = (qse_awk_nde_t*)nde; + nde->type = QSE_AWK_NDE_EXP_BIN; + nde->loc = *xloc; + nde->next = QSE_NULL; + nde->opcode = opcode; + nde->left = left; + nde->right = right; + + left = (qse_awk_nde_t*)nde; + } } return left; @@ -3612,13 +3660,13 @@ static qse_awk_nde_t* parse_concat ( } } else if (MATCH(awk,TOK_LPAREN) || - MATCH(awk,TOK_DOLLAR) || - MATCH(awk,TOK_PLUS) || - MATCH(awk,TOK_MINUS) || - MATCH(awk,TOK_PLUSPLUS) || - MATCH(awk,TOK_MINUSMINUS) || - MATCH(awk,TOK_LNOT) || - awk->tok.type >= TOK_GETLINE) + MATCH(awk,TOK_DOLLAR) || + MATCH(awk,TOK_PLUS) || + MATCH(awk,TOK_MINUS) || + MATCH(awk,TOK_PLUSPLUS) || + MATCH(awk,TOK_MINUSMINUS) || + MATCH(awk,TOK_LNOT) || + awk->tok.type >= TOK_GETLINE) { /* TODO: is the check above sufficient? */ if (!(awk->option & QSE_AWK_IMPLICIT)) break; @@ -3692,6 +3740,8 @@ static qse_awk_nde_t* parse_unary ( qse_awk_nde_t* left; qse_awk_loc_t uloc; int opcode; + int fold; + qse_long_t folded_l; opcode = (MATCH(awk,TOK_PLUS))? QSE_AWK_UNROP_PLUS: (MATCH(awk,TOK_MINUS))? QSE_AWK_UNROP_MINUS: @@ -3717,23 +3767,68 @@ static qse_awk_nde_t* parse_unary ( awk->parse.depth.cur.expr--; if (left == QSE_NULL) return QSE_NULL; - nde = (qse_awk_nde_exp_t*) - QSE_AWK_ALLOC (awk, QSE_SIZEOF(qse_awk_nde_exp_t)); - if (nde == QSE_NULL) + fold = 0; + if (left->type == QSE_AWK_NDE_INT) { - qse_awk_clrpt (awk, left); - SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc); - return QSE_NULL; + fold = 1; + + switch (opcode) + { + case QSE_AWK_UNROP_PLUS: + folded_l = ((qse_awk_nde_int_t*)left)->val; + break; + + case QSE_AWK_UNROP_MINUS: + folded_l = -((qse_awk_nde_int_t*)left)->val; + break; + + case QSE_AWK_UNROP_LNOT: + folded_l = !((qse_awk_nde_int_t*)left)->val; + break; + + case QSE_AWK_UNROP_BNOT: + folded_l = ~((qse_awk_nde_int_t*)left)->val; + break; + + default: + fold = 0; + break; + } } - nde->type = QSE_AWK_NDE_EXP_UNR; - nde->loc = *xloc; - nde->next = QSE_NULL; - nde->opcode = opcode; - nde->left = left; - nde->right = QSE_NULL; + if (fold) + { + ((qse_awk_nde_int_t*)left)->val = folded_l; + if (((qse_awk_nde_int_t*)left)->str) + { + QSE_AWK_FREE (awk, ((qse_awk_nde_int_t*)left)->str); + ((qse_awk_nde_int_t*)left)->str = QSE_NULL; + ((qse_awk_nde_int_t*)left)->len = 0; + } + + return left; + } + else + { + nde = (qse_awk_nde_exp_t*) + QSE_AWK_ALLOC (awk, QSE_SIZEOF(qse_awk_nde_exp_t)); + if (nde == QSE_NULL) + { + qse_awk_clrpt (awk, left); + SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc); + return QSE_NULL; + } + + nde->type = QSE_AWK_NDE_EXP_UNR; + nde->loc = *xloc; + nde->next = QSE_NULL; + nde->opcode = opcode; + nde->left = left; + nde->right = QSE_NULL; + + return (qse_awk_nde_t*)nde; + } - return (qse_awk_nde_t*)nde; } static qse_awk_nde_t* parse_exponent ( diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index 12bf2cc2..3780c541 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c 485 2011-05-29 15:15:52Z hyunghwan.chung $ + * $Id: run.c 514 2011-07-22 15:37:46Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -6822,22 +6822,12 @@ qse_char_t* qse_awk_rtx_format ( do { - n = rtx->awk->prm.sprintf ( + n = qse_awk_sprintlong ( rtx->awk, rtx->format.tmp.ptr, rtx->format.tmp.len, - #if QSE_SIZEOF_LONG_LONG > 0 - QSE_T("%lld"), (long long)width - #elif QSE_SIZEOF___INT64 > 0 - QSE_T("%I64d"), (__int64)width - #elif QSE_SIZEOF_LONG > 0 - QSE_T("%ld"), (long)width - #elif QSE_SIZEOF_INT > 0 - QSE_T("%d"), (int)width - #else - #error unsupported size - #endif - ); + width + ); if (n == -1) { GROW (&rtx->format.tmp); diff --git a/qse/lib/awk/tree.c b/qse/lib/awk/tree.c index bf77691e..afba4d96 100644 --- a/qse/lib/awk/tree.c +++ b/qse/lib/awk/tree.c @@ -1,5 +1,5 @@ /* - * $Id: tree.c 485 2011-05-29 15:15:52Z hyunghwan.chung $ + * $Id: tree.c 514 2011-07-22 15:37:46Z hyunghwan.chung $ * Copyright 2006-2011 Chung, Hyung-Hwan. This file is part of QSE. @@ -260,19 +260,39 @@ static int print_expr (qse_awk_t* awk, qse_awk_nde_t* nde) case QSE_AWK_NDE_INT: { - QSE_ASSERT (((qse_awk_nde_int_t*)nde)->str != QSE_NULL); - PUT_SRCSTRX (awk, - ((qse_awk_nde_int_t*)nde)->str, - ((qse_awk_nde_int_t*)nde)->len); + if (((qse_awk_nde_int_t*)nde)->str) + { + PUT_SRCSTRX (awk, + ((qse_awk_nde_int_t*)nde)->str, + ((qse_awk_nde_int_t*)nde)->len); + } + else + { + qse_char_t buf[64]; + qse_awk_sprintlong ( + awk, buf, QSE_COUNTOF(buf), + ((qse_awk_nde_int_t*)nde)->val); + PUT_SRCSTR (awk, buf); + } break; } case QSE_AWK_NDE_REAL: { - QSE_ASSERT (((qse_awk_nde_real_t*)nde)->str != QSE_NULL); - PUT_SRCSTRX (awk, - ((qse_awk_nde_real_t*)nde)->str, - ((qse_awk_nde_real_t*)nde)->len); + if (((qse_awk_nde_real_t*)nde)->str) + { + PUT_SRCSTRX (awk, + ((qse_awk_nde_real_t*)nde)->str, + ((qse_awk_nde_real_t*)nde)->len); + } + else + { + qse_char_t buf[64]; + qse_awk_sprintreal ( + awk, buf, QSE_COUNTOF(buf), + ((qse_awk_nde_real_t*)nde)->val); + PUT_SRCSTR (awk, buf); + } break; } @@ -1211,7 +1231,7 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree) case QSE_AWK_NDE_INT: { - if (((qse_awk_nde_int_t*)p)->str != QSE_NULL) + if (((qse_awk_nde_int_t*)p)->str) QSE_AWK_FREE (awk, ((qse_awk_nde_int_t*)p)->str); QSE_AWK_FREE (awk, p); break; @@ -1219,7 +1239,7 @@ void qse_awk_clrpt (qse_awk_t* awk, qse_awk_nde_t* tree) case QSE_AWK_NDE_REAL: { - if (((qse_awk_nde_real_t*)p)->str != QSE_NULL) + if (((qse_awk_nde_real_t*)p)->str) QSE_AWK_FREE (awk, ((qse_awk_nde_real_t*)p)->str); QSE_AWK_FREE (awk, p); break;