diff --git a/qse/cmd/awk/awk.c b/qse/cmd/awk/awk.c index f6aa7017..b0efe937 100644 --- a/qse/cmd/awk/awk.c +++ b/qse/cmd/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c 338 2010-07-30 13:24:19Z hyunghwan.chung $ + * $Id: awk.c 343 2010-08-05 07:31:17Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -34,6 +34,7 @@ #include #include +#define ENABLE_CALLBACK #define ABORT(label) goto label #if defined(_WIN32) @@ -265,11 +266,11 @@ static void dprint_return (qse_awk_rtx_t* rtx, qse_awk_val_t* ret) dprint (QSE_T("[END NAMED VARIABLES]\n")); } -#if 0 +#ifdef ENABLE_CALLBACK static void on_statement ( - qse_awk_rtx_t* run, qse_size_t line, void* data) + qse_awk_rtx_t* rtx, qse_awk_nde_t* nde, void* data) { - /*dprint (L"running %d\n", (int)line);*/ + dprint (L"running %d at line %d\n", (int)nde->type, (int)nde->loc.lin); } #endif @@ -710,7 +711,7 @@ static int awk_main (int argc, qse_char_t* argv[]) qse_awk_t* awk = QSE_NULL; qse_awk_rtx_t* rtx = QSE_NULL; qse_awk_val_t* retv; -#if 0 +#ifdef ENABLE_CALLBACK qse_awk_rcb_t rcb; #endif int i; @@ -795,8 +796,8 @@ static int awk_main (int argc, qse_char_t* argv[]) goto oops; } -#if 0 - rcb.on_statement = on_statement; +#ifdef ENABLE_CALLBACK + rcb.stm = on_statement; rcb.udd = &arg; #endif @@ -816,7 +817,7 @@ static int awk_main (int argc, qse_char_t* argv[]) } app_rtx = rtx; -#if 0 +#ifdef ENABLE_CALLBACK qse_awk_rtx_setrcb (rtx, &rcb); #endif diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index 93a042e0..5be0e58f 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h 328 2010-07-08 06:58:44Z hyunghwan.chung $ + * $Id: awk.h 343 2010-08-05 07:31:17Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -114,6 +114,17 @@ typedef struct qse_awk_t qse_awk_t; */ typedef struct qse_awk_rtx_t qse_awk_rtx_t; +/** + * The qse_awk_loc_t type defines a structure to hold location. + */ +struct qse_awk_loc_t +{ + const qse_char_t* fil; /**< file */ + qse_size_t lin; /**< line */ + qse_size_t col; /**< column */ +}; +typedef struct qse_awk_loc_t qse_awk_loc_t; + /** * The QSE_AWK_VAL_HDR defines the common header for a value. * Three common fields are: @@ -231,7 +242,7 @@ struct qse_awk_val_ref_t enum { /* keep these items in the same order as corresponding items - * in tree.h */ + * in qse_awk_nde_type_t. */ QSE_AWK_VAL_REF_NAMED, /**< plain named variable */ QSE_AWK_VAL_REF_GBL, /**< plain global variable */ QSE_AWK_VAL_REF_LCL, /**< plain local variable */ @@ -250,6 +261,81 @@ struct qse_awk_val_ref_t }; typedef struct qse_awk_val_ref_t qse_awk_val_ref_t; +/** + * The qse_awk_nde_type_t defines the node types. + */ +enum qse_awk_nde_type_t +{ + QSE_AWK_NDE_NULL, + + /* statement */ + QSE_AWK_NDE_BLK, + QSE_AWK_NDE_IF, + QSE_AWK_NDE_WHILE, + QSE_AWK_NDE_DOWHILE, + QSE_AWK_NDE_FOR, + QSE_AWK_NDE_FOREACH, + QSE_AWK_NDE_BREAK, + QSE_AWK_NDE_CONTINUE, + QSE_AWK_NDE_RETURN, + QSE_AWK_NDE_EXIT, + QSE_AWK_NDE_NEXT, + QSE_AWK_NDE_NEXTFILE, + QSE_AWK_NDE_DELETE, + QSE_AWK_NDE_RESET, + QSE_AWK_NDE_PRINT, + QSE_AWK_NDE_PRINTF, + + /* expression */ + /* if you change the following values including their order, + * you should change __eval_func of __eval_expression + * in run.c accordingly */ + QSE_AWK_NDE_GRP, + QSE_AWK_NDE_ASS, + QSE_AWK_NDE_EXP_BIN, + QSE_AWK_NDE_EXP_UNR, + QSE_AWK_NDE_EXP_INCPRE, + QSE_AWK_NDE_EXP_INCPST, + QSE_AWK_NDE_CND, + QSE_AWK_NDE_FNC, + QSE_AWK_NDE_FUN, + QSE_AWK_NDE_INT, + QSE_AWK_NDE_REAL, + QSE_AWK_NDE_STR, + QSE_AWK_NDE_REX, + + /* keep this order for the following items otherwise, you may have + * to change eval_incpre and eval_incpst in run.c as well as + * QSE_AWK_VAL_REF_XXX in qse_awk_val_ref_t */ + QSE_AWK_NDE_NAMED, + QSE_AWK_NDE_GBL, + QSE_AWK_NDE_LCL, + QSE_AWK_NDE_ARG, + QSE_AWK_NDE_NAMEDIDX, + QSE_AWK_NDE_GBLIDX, + QSE_AWK_NDE_LCLIDX, + QSE_AWK_NDE_ARGIDX, + QSE_AWK_NDE_POS, + /* ---------------------------------- */ + + QSE_AWK_NDE_GETLINE +}; +typedef enum qse_awk_nde_type_t qse_awk_nde_type_t; + +#define QSE_AWK_NDE_HDR \ + qse_awk_nde_type_t type; \ + qse_awk_loc_t loc; \ + qse_awk_nde_t* next + +/** @struct qse_awk_nde_t + * The qse_awk_nde_t type defines a common part of a node. + */ +typedef struct qse_awk_nde_t qse_awk_nde_t; +struct qse_awk_nde_t +{ + QSE_AWK_NDE_HDR; +}; + typedef qse_real_t (*qse_awk_pow_t) ( qse_awk_t* awk, qse_real_t x, @@ -465,17 +551,6 @@ struct qse_awk_prm_t }; typedef struct qse_awk_prm_t qse_awk_prm_t; -/** - * The qse_awk_loc_t type defines a structure to hold location. - */ -struct qse_awk_loc_t -{ - const qse_char_t* fil; /**< file */ - qse_size_t lin; /**< line */ - qse_size_t col; /**< column */ -}; -typedef struct qse_awk_loc_t qse_awk_loc_t; - /** * The qse_awk_sio_t type defines a script stream handler set. * The qse_awk_parse() function calls the input and output handler to parse @@ -536,8 +611,19 @@ struct qse_awk_rio_t typedef struct qse_awk_rio_t qse_awk_rio_t; /** - * The qse_awk_rcb_t type defines runtime callbacks. You may set callbacks - * with qse_awk_rtx_setrcb() to be informed of important events during runtime. + * The qse_awk_rcb_stm_t type defines the callback function for each + * statement. + */ +typedef void (*qse_awk_rcb_stm_t) ( + qse_awk_rtx_t* rtx, /**< runtime context */ + const qse_awk_nde_t* nde, /**< node */ + void* udd /**< user-defined data */ +); + +/** + * The qse_awk_rcb_t type defines runtime callbacks. You can specify callback + * functions with qse_awk_rtx_setrcb() to be informed of important events + * during runtime. */ struct qse_awk_rcb_t { @@ -545,13 +631,13 @@ struct qse_awk_rcb_t * called by qse_awk_rtx_loop() and qse_awk_rtx_call() for * each statement executed. */ - void (*on_statement) ( - qse_awk_rtx_t* rtx, const qse_awk_loc_t* loc, void* udd); + qse_awk_rcb_stm_t stm; /** - * A caller may store a custom data pointer into this field. + * A caller may store a user-defined data pointer into this field. This + * is passed to the actual callback. */ - void* udd; + void* udd; }; typedef struct qse_awk_rcb_t qse_awk_rcb_t; diff --git a/qse/include/qse/cmn/xma.h b/qse/include/qse/cmn/xma.h index 7e1ae889..307a2cfa 100644 --- a/qse/include/qse/cmn/xma.h +++ b/qse/include/qse/cmn/xma.h @@ -49,6 +49,8 @@ * * qse_xma_dump (xma, qse_printf); // dump memory blocks * + * // the following two lines are not actually needed as the allocator + * // is closed after them. * qse_xma_free (xma, ptr2); // dispose of the 1K block * qse_xma_free (xma, ptr1); // dispose of the 6K block * diff --git a/qse/lib/awk/awk.h b/qse/lib/awk/awk.h index 9385a242..3bd14a88 100644 --- a/qse/lib/awk/awk.h +++ b/qse/lib/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h 328 2010-07-08 06:58:44Z hyunghwan.chung $ + * $Id: awk.h 343 2010-08-05 07:31:17Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -137,7 +137,7 @@ struct qse_awk_t { int block; int loop; - int stmnt; /* statement */ + int stmt; /* statement */ } id; struct diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index 09053cd8..0614d5d9 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c 328 2010-07-08 06:58:44Z hyunghwan.chung $ + * $Id: parse.c 343 2010-08-05 07:31:17Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -165,7 +165,7 @@ static qse_awk_chain_t* parse_action_block ( static qse_awk_nde_t* parse_block_dc ( qse_awk_t* awk, const qse_awk_loc_t* xloc, qse_bool_t istop); -static qse_awk_nde_t* parse_stmt ( +static qse_awk_nde_t* parse_statement ( qse_awk_t* awk, const qse_awk_loc_t* xloc); static qse_awk_nde_t* parse_expr_dc ( @@ -1516,7 +1516,7 @@ static qse_awk_nde_t* parse_block ( /* parse an actual statement in a block */ { qse_awk_loc_t sloc = awk->tok.loc; - nde = parse_stmt (awk, &sloc); + nde = parse_statement (awk, &sloc); } if (nde == QSE_NULL) @@ -2128,7 +2128,7 @@ static qse_awk_nde_t* parse_if (qse_awk_t* awk, const qse_awk_loc_t* xloc) } tloc = awk->tok.loc; - then_part = parse_stmt (awk, &tloc); + then_part = parse_statement (awk, &tloc); if (then_part == QSE_NULL) { qse_awk_clrpt (awk, test); @@ -2157,7 +2157,7 @@ static qse_awk_nde_t* parse_if (qse_awk_t* awk, const qse_awk_loc_t* xloc) { qse_awk_loc_t eloc = awk->tok.loc; - else_part = parse_stmt (awk, &eloc); + else_part = parse_statement (awk, &eloc); } if (else_part == QSE_NULL) { @@ -2222,7 +2222,7 @@ static qse_awk_nde_t* parse_while (qse_awk_t* awk, const qse_awk_loc_t* xloc) { qse_awk_loc_t wloc = awk->tok.loc; - body = parse_stmt (awk, &wloc); + body = parse_statement (awk, &wloc); } if (body == QSE_NULL) { @@ -2297,7 +2297,7 @@ static qse_awk_nde_t* parse_for (qse_awk_t* awk, const qse_awk_loc_t* xloc) { qse_awk_loc_t floc = awk->tok.loc; - body = parse_stmt (awk, &floc); + body = parse_statement (awk, &floc); } if (body == QSE_NULL) { @@ -2415,7 +2415,7 @@ static qse_awk_nde_t* parse_for (qse_awk_t* awk, const qse_awk_loc_t* xloc) { qse_awk_loc_t floc = awk->tok.loc; - body = parse_stmt (awk, &floc); + body = parse_statement (awk, &floc); } if (body == QSE_NULL) { @@ -2457,7 +2457,7 @@ static qse_awk_nde_t* parse_dowhile (qse_awk_t* awk, const qse_awk_loc_t* xloc) { qse_awk_loc_t dwloc = awk->tok.loc; - body = parse_stmt (awk, &dwloc); + body = parse_statement (awk, &dwloc); } if (body == QSE_NULL) return QSE_NULL; @@ -2998,11 +2998,10 @@ static qse_awk_nde_t* parse_print ( return (qse_awk_nde_t*)nde; } -static qse_awk_nde_t* parse_stmt_nb ( +static qse_awk_nde_t* parse_statement_nb ( qse_awk_t* awk, const qse_awk_loc_t* xloc) { /* parse a non-block statement */ - qse_awk_nde_t* nde; /* keywords that don't require any terminating semicolon */ @@ -3032,6 +3031,7 @@ static qse_awk_nde_t* parse_stmt_nb ( return nde; } + /* keywords that require a terminating semicolon */ if (MATCH(awk,TOK_DO)) { @@ -3129,7 +3129,7 @@ static qse_awk_nde_t* parse_stmt_nb ( return nde; } -static qse_awk_nde_t* parse_stmt ( +static qse_awk_nde_t* parse_statement ( qse_awk_t* awk, const qse_awk_loc_t* xloc) { qse_awk_nde_t* nde; @@ -3164,28 +3164,29 @@ static qse_awk_nde_t* parse_stmt ( else if (MATCH(awk,TOK_LBRACE)) { /* a block statemnt { ... } */ - qse_awk_loc_t xloc = awk->ptok.loc; + qse_awk_loc_t tloc = awk->ptok.loc; if (get_token(awk) <= -1) return QSE_NULL; - nde = parse_block_dc (awk, &xloc, QSE_FALSE); + nde = parse_block_dc (awk, &tloc, QSE_FALSE); } else { - /* the statement id held in awk->parse.id.stmnt denotes + /* the statement id held in awk->parse.id.stmt denotes * the token id of the statement currently being parsed. * the current statement id is saved here because the - * statement id can be changed in parse_stmt_nb. - * it will, in turn, call parse_stmt which will + * statement id can be changed in parse_statement_nb. + * it will, in turn, call parse_statement which will * eventually change the statement id. */ - int old_id = awk->parse.id.stmnt; + int old_id = awk->parse.id.stmt; + qse_awk_loc_t tloc = awk->tok.loc; /* set the current statement id */ - awk->parse.id.stmnt = awk->tok.type; + awk->parse.id.stmt = awk->tok.type; /* proceed parsing the statement */ - nde = parse_stmt_nb (awk, xloc); + nde = parse_statement_nb (awk, &tloc); /* restore the statement id saved previously */ - awk->parse.id.stmnt = old_id; + awk->parse.id.stmt = old_id; } return nde; @@ -4215,8 +4216,8 @@ static qse_awk_nde_t* parse_primary_nogetline ( qse_awk_nde_grp_t* tmp; - if ((awk->parse.id.stmnt != TOK_PRINT && - awk->parse.id.stmnt != TOK_PRINTF) || + if ((awk->parse.id.stmt != TOK_PRINT && + awk->parse.id.stmt != TOK_PRINTF) || awk->parse.depth.cur.expr != 1) { if (!MATCH(awk,TOK_IN)) diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index d7a23378..b9ca49dc 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c 328 2010-07-08 06:58:44Z hyunghwan.chung $ + * $Id: run.c 343 2010-08-05 07:31:17Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -1870,11 +1870,7 @@ static int run_block0 (qse_awk_rtx_t* rtx, qse_awk_nde_blk_t* nde) #define ON_STATEMENT(rtx,nde) \ if ((rtx)->awk->stopall) (rtx)->exit_level = EXIT_ABORT; \ - if ((rtx)->rcb.on_statement != QSE_NULL) \ - { \ - (rtx)->rcb.on_statement ( \ - rtx, &(nde)->loc, (rtx)->rcb.udd); \ - } + if ((rtx)->rcb.stm) (rtx)->rcb.stm (rtx, nde, (rtx)->rcb.udd); static int run_statement (qse_awk_rtx_t* rtx, qse_awk_nde_t* nde) { @@ -3167,7 +3163,7 @@ static qse_awk_val_t* eval_expression0 (qse_awk_rtx_t* run, qse_awk_nde_t* nde) static eval_expr_t __evaluator[] = { /* the order of functions here should match the order - * of node types declared in tree.h */ + * of node types(qse_awk_nde_type_t) declared in qse/awk/awk.h */ eval_group, eval_assignment, eval_binary, @@ -4995,7 +4991,7 @@ static qse_awk_val_t* eval_incpre (qse_awk_rtx_t* run, qse_awk_nde_t* nde) QSE_ASSERT (exp->left != QSE_NULL && exp->right == QSE_NULL); /* this way of checking if the l-value is assignable is - * ugly as it is dependent of the values defined in tree.h. + * ugly as it is dependent on the node types defined in qse/awk/awk.h * but let's keep going this way for the time being. */ if (exp->left->type < QSE_AWK_NDE_NAMED || /*exp->left->type > QSE_AWK_NDE_ARGIDX) XXX */ @@ -5150,7 +5146,7 @@ static qse_awk_val_t* eval_incpst (qse_awk_rtx_t* run, qse_awk_nde_t* nde) QSE_ASSERT (exp->left != QSE_NULL && exp->right == QSE_NULL); /* this way of checking if the l-value is assignable is - * ugly as it is dependent of the values defined in tree.h. + * ugly as it is dependent on the node types defined in qse/awk/awk.h. * but let's keep going this way for the time being. */ if (exp->left->type < QSE_AWK_NDE_NAMED || /*exp->left->type > QSE_AWK_NDE_ARGIDX) XXX */ diff --git a/qse/lib/awk/tree.h b/qse/lib/awk/tree.h index 7175e25f..e2a89604 100644 --- a/qse/lib/awk/tree.h +++ b/qse/lib/awk/tree.h @@ -1,5 +1,5 @@ /* - * $Id: tree.h 287 2009-09-15 10:01:02Z hyunghwan.chung $ + * $Id: tree.h 343 2010-08-05 07:31:17Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. This file is part of QSE. @@ -21,65 +21,6 @@ #ifndef _QSE_LIB_AWK_TREE_H_ #define _QSE_LIB_AWK_TREE_H_ -enum qse_awk_nde_type_t -{ - QSE_AWK_NDE_NULL, - - /* statement */ - QSE_AWK_NDE_BLK, - QSE_AWK_NDE_IF, - QSE_AWK_NDE_WHILE, - QSE_AWK_NDE_DOWHILE, - QSE_AWK_NDE_FOR, - QSE_AWK_NDE_FOREACH, - QSE_AWK_NDE_BREAK, - QSE_AWK_NDE_CONTINUE, - QSE_AWK_NDE_RETURN, - QSE_AWK_NDE_EXIT, - QSE_AWK_NDE_NEXT, - QSE_AWK_NDE_NEXTFILE, - QSE_AWK_NDE_DELETE, - QSE_AWK_NDE_RESET, - QSE_AWK_NDE_PRINT, - QSE_AWK_NDE_PRINTF, - - /* expression */ - /* if you change the following values including their order, - * you should change __eval_func of __eval_expression - * in run.c accordingly */ - QSE_AWK_NDE_GRP, - QSE_AWK_NDE_ASS, - QSE_AWK_NDE_EXP_BIN, - QSE_AWK_NDE_EXP_UNR, - QSE_AWK_NDE_EXP_INCPRE, - QSE_AWK_NDE_EXP_INCPST, - QSE_AWK_NDE_CND, - QSE_AWK_NDE_FNC, - QSE_AWK_NDE_FUN, - QSE_AWK_NDE_INT, - QSE_AWK_NDE_REAL, - QSE_AWK_NDE_STR, - QSE_AWK_NDE_REX, - - /* keep this order for the following items otherwise, you may have - * to change eval_incpre and eval_incpst in run.c as well as - * QSE_AWK_VAL_REF_XXX in awk.h */ - QSE_AWK_NDE_NAMED, - QSE_AWK_NDE_GBL, - QSE_AWK_NDE_LCL, - QSE_AWK_NDE_ARG, - QSE_AWK_NDE_NAMEDIDX, - QSE_AWK_NDE_GBLIDX, - QSE_AWK_NDE_LCLIDX, - QSE_AWK_NDE_ARGIDX, - QSE_AWK_NDE_POS, - /* ---------------------------------- */ - - QSE_AWK_NDE_GETLINE -}; - -typedef enum qse_awk_nde_type_t qse_awk_nde_type_t; - enum qse_awk_in_type_t { /* the order of these values match @@ -107,7 +48,6 @@ enum qse_awk_out_type_t * note it is different from qse_awk_fnc_t */ typedef struct qse_awk_fun_t qse_awk_fun_t; -typedef struct qse_awk_nde_t qse_awk_nde_t; typedef struct qse_awk_nde_blk_t qse_awk_nde_blk_t; typedef struct qse_awk_nde_grp_t qse_awk_nde_grp_t; typedef struct qse_awk_nde_ass_t qse_awk_nde_ass_t; @@ -152,16 +92,6 @@ struct qse_awk_fun_t qse_awk_nde_t* body; }; -#define QSE_AWK_NDE_HDR \ - qse_awk_nde_type_t type; \ - qse_awk_loc_t loc; \ - qse_awk_nde_t* next - -struct qse_awk_nde_t -{ - QSE_AWK_NDE_HDR; -}; - /* QSE_AWK_NDE_BLK - block statement including top-level blocks */ struct qse_awk_nde_blk_t {