diff --git a/qse/include/qse/awk/Awk.hpp b/qse/include/qse/awk/Awk.hpp index 868a0473..4ad38226 100644 --- a/qse/include/qse/awk/Awk.hpp +++ b/qse/include/qse/awk/Awk.hpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.hpp 231 2009-07-13 10:03:53Z hyunghwan.chung $ + * $Id: Awk.hpp 232 2009-07-14 08:06:14Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -254,6 +254,8 @@ public: class Value { public: + friend class Awk; + // initialization void* operator new (size_t n, Run* run) throw (); void* operator new[] (size_t n, Run* run) throw (); @@ -556,6 +558,7 @@ public: ERR_NEXTFEND = QSE_AWK_ENEXTFEND, ERR_PRINTFARG = QSE_AWK_EPRINTFARG, ERR_PREPST = QSE_AWK_EPREPST, + ERR_INCDECOPR = QSE_AWK_EINCDECOPR, ERR_DIVBY0 = QSE_AWK_EDIVBY0, ERR_OPERAND = QSE_AWK_EOPERAND, ERR_POSIDX = QSE_AWK_EPOSIDX, @@ -647,25 +650,29 @@ public: }; // end of enum Option + /** + * Defines an identifier of predefined global variables. + * Awk::setGlobal and Awk::getGlobal can take one of these enumeration. + */ enum Global { - GBL_ARGC = QSE_AWK_GBL_ARGC, - GBL_ARGV = QSE_AWK_GBL_ARGV, - GBL_CONVFMT = QSE_AWK_GBL_CONVFMT, - GBL_FILENAME = QSE_AWK_GBL_FILENAME, - GBL_FNR = QSE_AWK_GBL_FNR, - GBL_FS = QSE_AWK_GBL_FS, - GBL_IGNORECASE = QSE_AWK_GBL_IGNORECASE, - GBL_NF = QSE_AWK_GBL_NF, - GBL_NR = QSE_AWK_GBL_NR, - GBL_OFILENAME = QSE_AWK_GBL_OFILENAME, - GBL_OFMT = QSE_AWK_GBL_OFMT, - GBL_OFS = QSE_AWK_GBL_OFS, - GBL_ORS = QSE_AWK_GBL_ORS, - GBL_RLENGTH = QSE_AWK_GBL_RLENGTH, - GBL_RS = QSE_AWK_GBL_RS, - GBL_RSTART = QSE_AWK_GBL_RSTART, - GBL_SUBSEP = QSE_AWK_GBL_SUBSEP + GBL_ARGC = QSE_AWK_GBL_ARGC, /**< ARGC */ + GBL_ARGV = QSE_AWK_GBL_ARGV, /**< ARGV */ + GBL_CONVFMT = QSE_AWK_GBL_CONVFMT, /**< CONVFMT */ + GBL_FILENAME = QSE_AWK_GBL_FILENAME, /**< FILENAME */ + GBL_FNR = QSE_AWK_GBL_FNR, /**< FNR */ + GBL_FS = QSE_AWK_GBL_FS, /**< FS */ + GBL_IGNORECASE = QSE_AWK_GBL_IGNORECASE, /**< IGNORECASE */ + GBL_NF = QSE_AWK_GBL_NF, /**< NF */ + GBL_NR = QSE_AWK_GBL_NR, /**< NR */ + GBL_OFILENAME = QSE_AWK_GBL_OFILENAME, /**< OFILENAME */ + GBL_OFMT = QSE_AWK_GBL_OFMT, /**< OFMT */ + GBL_OFS = QSE_AWK_GBL_OFS, /**< OFS */ + GBL_ORS = QSE_AWK_GBL_ORS, /**< ORS */ + GBL_RLENGTH = QSE_AWK_GBL_RLENGTH, /**< RLENGTH */ + GBL_RS = QSE_AWK_GBL_RS, /**< RS */ + GBL_RSTART = QSE_AWK_GBL_RSTART, /**< RSTART */ + GBL_SUBSEP = QSE_AWK_GBL_SUBSEP /**< SUBSEP */ }; /** Represents the execution context */ @@ -699,94 +706,39 @@ public: ErrorNumber code, size_t line, const char_t* msg); /** - * Sets the value of a global variable. The global variable - * is indicated by the first parameter. - * - * @param id - * The ID to a global variable. This value corresponds - * to the predefined global variable IDs or the value - * returned by Awk::addGlobal. - * @param v - * The value to assign to the global variable. - * - * @return - * On success, 0 is returned. - * On failure, -1 is returned. + * Sets the value of a global variable identified by @a id + * to @a v. + * @return 0 on success, -1 on failure */ int setGlobal (int id, long_t v); /** - * Sets the value of a global variable. The global variable - * is indicated by the first parameter. - * - * @param id - * The ID to a global variable. This value corresponds - * to the predefined global variable IDs or the value - * returned by Awk::addGlobal. - * @param v - * The value to assign to the global variable. - * - * @return - * On success, 0 is returned. - * On failure, -1 is returned. + * Sets the value of a global variable identified by @a id + * to @a v. + * @return 0 on success, -1 on failure */ int setGlobal (int id, real_t v); /** - * Sets the value of a global variable. The global variable - * is indicated by the first parameter. - * - * @param id - * The ID to a global variable. This value corresponds - * to the predefined global variable IDs or the value - * returned by Awk::addGlobal. - * @param ptr The pointer to a character array - * @param len The number of characters in the array - * - * @return - * On success, 0 is returned. - * On failure, -1 is returned. + * Sets the value of a global variable identified by @a id + * to a string as long as @a len characters pointed to by + * @a ptr. + * @return 0 on success, -1 on failure */ int setGlobal (int id, const char_t* ptr, size_t len); - /** - * Sets the value of a global variable. The global variable - * is indicated by the first parameter. - * - * @param id - * The ID to a global variable. This value corresponds - * to the predefined global variable IDs or the value - * returned by Awk::addGlobal. - * @param global - * The reference to the value holder - * - * @return - * On success, 0 is returned. - * On failure, -1 is returned. + * Sets a global variable identified by @a id to a value @a v. + * @return 0 on success, -1 on failure */ - int setGlobal (int id, const Value& global); + int setGlobal (int id, const Value& v); /** - * Gets the value of a global variable. - * - * @param id - * The ID to a global variable. This value corresponds - * to the predefined global variable IDs or the value - * returned by Awk::addGlobal. - * @param global - * The reference to the value holder of a global variable - * indicated by id. The parameter is set if this method - * returns 0. - * - * @return - * On success, 0 is returned. - * On failure, -1 is returned. + * Gets the value of a global variable identified by @a id + * and store it in @a v. + * @return 0 on success, -1 on failure */ - int getGlobal (int id, Value& global) const; - - void* alloc (size_t size); - void free (void* ptr); + int getGlobal (int id, Value& v) const; protected: Awk* awk; @@ -939,6 +891,7 @@ public: /** * Adds a intrinsic global variable. + * @return integer >= 0 on success, -1 on failure. */ virtual int addGlobal (const char_t* name); @@ -947,6 +900,23 @@ public: */ virtual int deleteGlobal (const char_t* name); + /** + * Sets the value of a global variable identified by @a id. + * The @a id is either a value returned by Awk::addGlobal or one of + * Awk::Global enumerations. It is not legal to call this function + * prior to Awk::parse. + * @return 0 on success, -1 on failure + */ + virtual int setGlobal (int id, const Value& v); + /** + * Gets the value of a global riable identified by @a id. + * The @a id is either a value returned by Awk::addGlobal or one of + * Awk::Global enumerations. It is not legal to call this function + * prior to Awk::parse. + * @return 0 on success, -1 on failure + */ + virtual int getGlobal (int id, Value& v); + /** * Represents a user-defined intrinsic function. */ diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index 968b1083..dc5c76be 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h 230 2009-07-13 08:51:23Z hyunghwan.chung $ + * $Id: awk.h 232 2009-07-14 08:06:14Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -291,7 +291,7 @@ enum qse_awk_rio_cmd_t QSE_AWK_RIO_WRITE = 3, /**< write a stream */ QSE_AWK_RIO_FLUSH = 4, /**< write buffered data to a stream */ QSE_AWK_RIO_NEXT = 5 /**< close the current stream and - open the next stream. only for console */ + open the next stream (only for console) */ }; typedef enum qse_awk_rio_cmd_t qse_awk_rio_cmd_t; @@ -682,6 +682,7 @@ enum qse_awk_errnum_t QSE_AWK_ENEXTFEND, /**< 'nextfile' illegal in END block */ QSE_AWK_EPRINTFARG,/**< 'printf' not followed by argument */ QSE_AWK_EPREPST, /**< both prefix and postfix incr/decr operator present */ + QSE_AWK_EINCDECOPR,/**< illegal operand for incr/decr operator */ /* run time error */ QSE_AWK_EDIVBY0, /**< divide by zero */ diff --git a/qse/include/qse/awk/std.h b/qse/include/qse/awk/std.h index 2659a7b9..e678249e 100644 --- a/qse/include/qse/awk/std.h +++ b/qse/include/qse/awk/std.h @@ -1,5 +1,5 @@ /* - * $Id: std.h 212 2009-06-25 07:39:27Z hyunghwan.chung $ + * $Id: std.h 232 2009-07-14 08:06:14Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -32,7 +32,6 @@ * * @todo * - add code to treat a function as a value - * - StdAwk ARGV and console name handling * - add RQ and LQ for more powerful record splitting * - improve performance in qse_awk_rtx_readio() if RS is logner than 2 chars. */ diff --git a/qse/lib/awk/Awk.cpp b/qse/lib/awk/Awk.cpp index fbb421b8..c66a70a2 100644 --- a/qse/lib/awk/Awk.cpp +++ b/qse/lib/awk/Awk.cpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.cpp 231 2009-07-13 10:03:53Z hyunghwan.chung $ + * $Id: Awk.cpp 232 2009-07-14 08:06:14Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -1000,7 +1000,6 @@ int Awk::Run::setGlobal (int id, const char_t* ptr, size_t len) int Awk::Run::setGlobal (int id, const Value& gbl) { QSE_ASSERT (this->rtx != QSE_NULL); - return qse_awk_rtx_setgbl (this->rtx, id, (val_t*)gbl); } @@ -1531,7 +1530,7 @@ int Awk::addGlobal (const char_t* name) QSE_ASSERT (awk != QSE_NULL); int n = qse_awk_addgbl (awk, name, qse_strlen(name)); - if (n == -1) retrieveError (); + if (n <= -1) retrieveError (); return n; } @@ -1539,7 +1538,33 @@ int Awk::deleteGlobal (const char_t* name) { QSE_ASSERT (awk != QSE_NULL); int n = qse_awk_delgbl (awk, name, qse_strlen(name)); - if (n == -1) retrieveError (); + if (n <= -1) retrieveError (); + return n; +} + +int Awk::setGlobal (int id, const Value& v) +{ + QSE_ASSERT (awk != QSE_NULL); + QSE_ASSERT (runctx.rtx != QSE_NULL); + + if (v.run != &runctx) + { + setError (ERR_INVAL); + return -1; + } + + int n = runctx.setGlobal (id, v); + if (n <= -1) retrieveError (); + return n; +} + +int Awk::getGlobal (int id, Value& v) +{ + QSE_ASSERT (awk != QSE_NULL); + QSE_ASSERT (runctx.rtx != QSE_NULL); + + int n = runctx.getGlobal (id, v); + if (n <= -1) retrieveError (); return n; } diff --git a/qse/lib/awk/awk.c b/qse/lib/awk/awk.c index be68f3a5..7bf79585 100644 --- a/qse/lib/awk/awk.c +++ b/qse/lib/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c 212 2009-06-25 07:39:27Z hyunghwan.chung $ + * $Id: awk.c 232 2009-07-14 08:06:14Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -54,6 +54,27 @@ static void free_fnc (qse_map_t* map, void* vptr, qse_size_t vlen) QSE_AWK_FREE (awk, f); } +static int init_token (qse_mmgr_t* mmgr, qse_awk_token_t* token) +{ + token->name = qse_str_open (mmgr, 0, 128); + if (token->name == QSE_NULL) return -1; + + token->type = 0; + token->line = 0; + token->column = 0; + + return 0; +} + +static void fini_token (qse_awk_token_t* token) +{ + if (token->name != QSE_NULL) + { + qse_str_close (token->name); + token->name = QSE_NULL; + } +} + qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm) { qse_awk_t* awk; @@ -91,8 +112,8 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm) } awk->prm = *prm; - awk->token.name = qse_str_open (mmgr, 0, 128); - if (awk->token.name == QSE_NULL) goto oops; + if (init_token (mmgr, &awk->token) == -1) goto oops; + if (init_token (mmgr, &awk->atoken) == -1) goto oops; awk->wtab = qse_map_open (mmgr, QSE_SIZEOF(awk), 512, 70); if (awk->wtab == QSE_NULL) goto oops; @@ -170,12 +191,9 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm) awk->tree.chain_tail = QSE_NULL; awk->tree.chain_size = 0; - awk->token.prev.type = 0; - awk->token.prev.line = 0; - awk->token.prev.column = 0; - awk->token.type = 0; - awk->token.line = 0; - awk->token.column = 0; + awk->ptoken.type = 0; + awk->ptoken.line = 0; + awk->ptoken.column = 0; awk->src.lex.curc = QSE_CHAR_EOF; awk->src.lex.ungotc_count = 0; @@ -218,7 +236,8 @@ oops: if (awk->tree.funs) qse_map_close (awk->tree.funs); if (awk->rwtab) qse_map_close (awk->rwtab); if (awk->wtab) qse_map_close (awk->wtab); - if (awk->token.name) qse_str_close (awk->token.name); + fini_token (&awk->atoken); + fini_token (&awk->token); QSE_AWK_FREE (awk, awk); return QSE_NULL; @@ -240,7 +259,8 @@ int qse_awk_close (qse_awk_t* awk) qse_map_close (awk->rwtab); qse_map_close (awk->wtab); - qse_str_close (awk->token.name); + fini_token (&awk->atoken); + fini_token (&awk->token); /* QSE_AWK_ALLOC, QSE_AWK_FREE, etc can not be used * from the next line onwards */ diff --git a/qse/lib/awk/awk.h b/qse/lib/awk/awk.h index 8416b58b..c2f28faf 100644 --- a/qse/lib/awk/awk.h +++ b/qse/lib/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h 212 2009-06-25 07:39:27Z hyunghwan.chung $ + * $Id: awk.h 232 2009-07-14 08:06:14Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -96,6 +96,15 @@ struct qse_awk_tree_t int ok; }; +typedef struct qse_awk_token_t qse_awk_token_t; +struct qse_awk_token_t +{ + int type; + qse_str_t* name; + qse_size_t line; + qse_size_t column; +}; + struct qse_awk_t { QSE_DEFINE_COMMON_FIELDS (sed) @@ -188,21 +197,17 @@ struct qse_awk_t } shared; } src; - /* token */ - struct + /* previous token info excluding name */ + struct { - struct - { - int type; - qse_size_t line; - qse_size_t column; - } prev; - - int type; - qse_str_t* name; + int type; qse_size_t line; qse_size_t column; - } token; + } ptoken; + + /* current token */ + qse_awk_token_t token; + qse_awk_token_t atoken; /* intrinsic functions */ struct diff --git a/qse/lib/awk/err.c b/qse/lib/awk/err.c index 652f909f..d9dd9f58 100644 --- a/qse/lib/awk/err.c +++ b/qse/lib/awk/err.c @@ -1,5 +1,5 @@ /* - * $Id: err.c 220 2009-07-01 13:14:39Z hyunghwan.chung $ + * $Id: err.c 232 2009-07-14 08:06:14Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -107,6 +107,7 @@ const qse_char_t* qse_awk_dflerrstr (qse_awk_t* awk, qse_awk_errnum_t errnum) QSE_T("'nextfile' illegal in the END block"), QSE_T("'printf' not followed by argument"), QSE_T("both prefix and postfix increment/decrement operator present"), + QSE_T("illegal operand for increment/decrement operator"), QSE_T("divide by zero"), QSE_T("invalid operand"), diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index 666bc34f..0a0193ac 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c 220 2009-07-01 13:14:39Z hyunghwan.chung $ + * $Id: parse.c 232 2009-07-14 08:06:14Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -172,12 +172,10 @@ static qse_awk_nde_t* parse_binary_expr ( qse_awk_nde_t*(*next_level_func)(qse_awk_t*,qse_size_t)); static qse_awk_nde_t* parse_logical_or (qse_awk_t* awk, qse_size_t line); -static qse_awk_nde_t* parse_logical_or_with_io (qse_awk_t* awk, qse_size_t line); static qse_awk_nde_t* parse_logical_and (qse_awk_t* awk, qse_size_t line); static qse_awk_nde_t* parse_in (qse_awk_t* awk, qse_size_t line); static qse_awk_nde_t* parse_regex_match (qse_awk_t* awk, qse_size_t line); static qse_awk_nde_t* parse_bitwise_or (qse_awk_t* awk, qse_size_t line); -static qse_awk_nde_t* parse_bitwise_or_with_io (qse_awk_t* awk, qse_size_t line); static qse_awk_nde_t* parse_bitwise_xor (qse_awk_t* awk, qse_size_t line); static qse_awk_nde_t* parse_bitwise_and (qse_awk_t* awk, qse_size_t line); static qse_awk_nde_t* parse_equality (qse_awk_t* awk, qse_size_t line); @@ -215,12 +213,17 @@ static qse_awk_nde_t* parse_reset (qse_awk_t* awk, qse_size_t line); static qse_awk_nde_t* parse_print (qse_awk_t* awk, qse_size_t line, int type); static int get_token (qse_awk_t* awk); -static int get_number (qse_awk_t* awk); -static int get_charstr (qse_awk_t* awk); -static int get_rexstr (qse_awk_t* awk); +static int preget_token (qse_awk_t* awk); + +static int get_number (qse_awk_t* awk, qse_awk_token_t* token); +static int get_charstr (qse_awk_t* awk, qse_awk_token_t* token); +static int get_rexstr (qse_awk_t* awk, qse_awk_token_t* token); static int get_string ( qse_awk_t* awk, qse_char_t end_char, - qse_char_t esc_char, qse_bool_t keep_esc_char, int preescaped); + qse_char_t esc_char, qse_bool_t keep_esc_char, int preescaped, + qse_awk_token_t* token +); + static int get_char (qse_awk_t* awk); static int unget_char (qse_awk_t* awk, qse_cint_t c); static int skip_spaces (qse_awk_t* awk); @@ -342,22 +345,23 @@ static global_t gtab[] = #define UNGET_CHAR(awk,c) \ do { if (unget_char (awk, c) <= -1) return -1; } while(0) -#define SET_TOKEN_TYPE(awk,code) do { (awk)->token.type = (code); } while (0) +#define SET_TOKEN_TYPE(awk,token,code) \ + do { (token)->type = (code); } while (0) -#define ADD_TOKEN_CHAR(awk,c) \ +#define ADD_TOKEN_CHAR(awk,token,c) \ do { \ - if (qse_str_ccat((awk)->token.name,(c)) == (qse_size_t)-1) \ + if (qse_str_ccat((token)->name,(c)) == (qse_size_t)-1) \ { \ - qse_awk_seterror (awk, QSE_AWK_ENOMEM, (awk)->token.line, QSE_NULL); \ + qse_awk_seterror (awk, QSE_AWK_ENOMEM, (token)->line, QSE_NULL); \ return -1; \ } \ } while (0) -#define ADD_TOKEN_STR(awk,s,l) \ +#define ADD_TOKEN_STR(awk,token,s,l) \ do { \ - if (qse_str_ncat((awk)->token.name,(s),(l)) == (qse_size_t)-1) \ + if (qse_str_ncat((token)->name,(s),(l)) == (qse_size_t)-1) \ { \ - qse_awk_seterror (awk, QSE_AWK_ENOMEM, (awk)->token.line, QSE_NULL); \ + qse_awk_seterror (awk, QSE_AWK_ENOMEM, (token)->line, QSE_NULL); \ return -1; \ } \ } while (0) @@ -374,7 +378,7 @@ static global_t gtab[] = errarg.len = QSE_STR_LEN((awk)->token.name); \ errarg.ptr = QSE_STR_PTR((awk)->token.name); \ if (MATCH(awk,TOKEN_EOF)) \ - qse_awk_seterror (awk, code, (awk)->token.prev.line, &errarg); \ + qse_awk_seterror (awk, code, (awk)->ptoken.line, &errarg); \ else \ qse_awk_seterror (awk, code, (awk)->token.line, &errarg); \ } while (0) @@ -640,7 +644,7 @@ static qse_awk_t* parse_progunit (qse_awk_t* awk) /* if (awk->tree.begin != QSE_NULL) { - SETERRLIN (awk, QSE_AWK_EDUPBEG, awk->token.prev.line); + SETERRLIN (awk, QSE_AWK_EDUPBEG, awk->ptoken.line); return QSE_NULL; } */ @@ -652,7 +656,7 @@ static qse_awk_t* parse_progunit (qse_awk_t* awk) { /* when QSE_AWK_NEWLINE is set, * BEGIN and { should be located on the same line */ - SETERRLIN (awk, QSE_AWK_EBLKBEG, awk->token.prev.line); + SETERRLIN (awk, QSE_AWK_EBLKBEG, awk->ptoken.line); return QSE_NULL; } @@ -676,7 +680,7 @@ static qse_awk_t* parse_progunit (qse_awk_t* awk) /* if (awk->tree.end != QSE_NULL) { - SETERRLIN (awk, QSE_AWK_EDUPEND, awk->token.prev.line); + SETERRLIN (awk, QSE_AWK_EDUPEND, awk->ptoken.line); return QSE_NULL; } */ @@ -688,7 +692,7 @@ static qse_awk_t* parse_progunit (qse_awk_t* awk) { /* when QSE_AWK_NEWLINE is set, * END and { should be located on the same line */ - SETERRLIN (awk, QSE_AWK_EBLKEND, awk->token.prev.line); + SETERRLIN (awk, QSE_AWK_EBLKEND, awk->ptoken.line); return QSE_NULL; } @@ -760,7 +764,7 @@ static qse_awk_t* parse_progunit (qse_awk_t* awk) { /* blockless pattern */ qse_bool_t newline = MATCH(awk,TOKEN_NEWLINE); - qse_size_t tline = awk->token.prev.line; + qse_size_t tline = awk->ptoken.line; awk->parse.id.block = PARSE_ACTION_BLOCK; if (parse_pattern_block(awk,ptn,QSE_TRUE) == QSE_NULL) @@ -1059,7 +1063,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk) awk->tree.cur_fun.len = name_len; /* actual function body */ - body = awk->parse.parse_block (awk, awk->token.prev.line, QSE_TRUE); + body = awk->parse.parse_block (awk, awk->ptoken.line, QSE_TRUE); /* clear the current function name remembered */ awk->tree.cur_fun.ptr = QSE_NULL; @@ -1125,7 +1129,7 @@ static qse_awk_nde_t* parse_begin (qse_awk_t* awk) QSE_ASSERT (MATCH(awk,TOKEN_LBRACE)); if (get_token(awk) <= -1) return QSE_NULL; - nde = awk->parse.parse_block (awk, awk->token.prev.line, QSE_TRUE); + nde = awk->parse.parse_block (awk, awk->ptoken.line, QSE_TRUE); if (nde == QSE_NULL) return QSE_NULL; if (awk->tree.begin == QSE_NULL) @@ -1149,7 +1153,7 @@ static qse_awk_nde_t* parse_end (qse_awk_t* awk) QSE_ASSERT (MATCH(awk,TOKEN_LBRACE)); if (get_token(awk) <= -1) return QSE_NULL; - nde = awk->parse.parse_block (awk, awk->token.prev.line, QSE_TRUE); + nde = awk->parse.parse_block (awk, awk->ptoken.line, QSE_TRUE); if (nde == QSE_NULL) return QSE_NULL; if (awk->tree.end == QSE_NULL) @@ -1271,7 +1275,7 @@ static qse_awk_nde_t* parse_block ( QSE_LDA_SIZE(awk->parse.lcls) - nlcls); if (head != QSE_NULL) qse_awk_clrpt (awk, head); - SETERRLIN (awk, QSE_AWK_EENDSRC, awk->token.prev.line); + SETERRLIN (awk, QSE_AWK_EENDSRC, awk->ptoken.line); return QSE_NULL; } @@ -1375,7 +1379,7 @@ static qse_awk_nde_t* parse_block_dc ( if (awk->parse.depth.cur.block >= awk->parse.depth.max.block) { - SETERRLIN (awk, QSE_AWK_EBLKNST, awk->token.prev.line); + SETERRLIN (awk, QSE_AWK_EBLKNST, awk->ptoken.line); return QSE_NULL; } @@ -1585,8 +1589,7 @@ static int add_global ( return (int)ngbls; } -int qse_awk_addgbl ( - qse_awk_t* awk, const qse_char_t* name, qse_size_t len) +int qse_awk_addgbl (qse_awk_t* awk, const qse_char_t* name, qse_size_t len) { int n; @@ -1887,7 +1890,7 @@ static qse_awk_nde_t* parse_statement (qse_awk_t* awk, qse_size_t line) /* a block statemnt { ... } */ if (get_token(awk) <= -1) return QSE_NULL; nde = awk->parse.parse_block ( - awk, awk->token.prev.line, QSE_FALSE); + awk, awk->ptoken.line, QSE_FALSE); } else { @@ -2034,7 +2037,7 @@ static qse_awk_nde_t* parse_statement_nb (qse_awk_t* awk, qse_size_t line) else { if (nde != QSE_NULL) qse_awk_clrpt (awk, nde); - SETERRLIN (awk, QSE_AWK_ESTMEND, awk->token.prev.line); + SETERRLIN (awk, QSE_AWK_ESTMEND, awk->ptoken.line); return QSE_NULL; } @@ -2251,115 +2254,13 @@ static qse_awk_nde_t* parse_binary_expr ( static qse_awk_nde_t* parse_logical_or (qse_awk_t* awk, qse_size_t line) { - if ((awk->option & QSE_AWK_RIO) && - (awk->option & QSE_AWK_RWPIPE)) + static binmap_t map[] = { - return parse_logical_or_with_io (awk, line); - } - else - { - static binmap_t map[] = - { - { TOKEN_LOR, QSE_AWK_BINOP_LOR }, - { TOKEN_EOF, 0 } - }; + { TOKEN_LOR, QSE_AWK_BINOP_LOR }, + { TOKEN_EOF, 0 } + }; - return parse_binary_expr (awk, line, 1, map, parse_logical_and); - } -} - -static qse_awk_nde_t* parse_logical_or_with_io (qse_awk_t* awk, qse_size_t line) -{ - qse_awk_nde_t* left, * right; - - left = parse_logical_and (awk, line); - if (left == QSE_NULL) return QSE_NULL; - - while (MATCH(awk,TOKEN_LOR)) - { - if (get_token(awk) <= -1) - { - qse_awk_clrpt (awk, left); - return QSE_NULL; - } - - if (MATCH(awk,TOKEN_GETLINE)) - { - qse_awk_nde_getline_t* nde; - qse_awk_nde_t* var = QSE_NULL; - - if (get_token(awk) <= -1) - { - qse_awk_clrpt (awk, left); - return QSE_NULL; - } - - /* TODO: is this correct? */ - if (MATCH(awk,TOKEN_IDENT)) - { - /* command | getline var */ - - var = parse_primary (awk, awk->token.line); - if (var == QSE_NULL) - { - qse_awk_clrpt (awk, left); - return QSE_NULL; - } - } - - nde = (qse_awk_nde_getline_t*) QSE_AWK_ALLOC ( - awk, QSE_SIZEOF(qse_awk_nde_getline_t)); - if (nde == QSE_NULL) - { - qse_awk_clrpt (awk, left); - - SETERRLIN (awk, QSE_AWK_ENOMEM, line); - return QSE_NULL; - } - - nde->type = QSE_AWK_NDE_GETLINE; - nde->line = line; - nde->next = QSE_NULL; - nde->var = var; - nde->in_type = QSE_AWK_IN_RWPIPE; - nde->in = left; - - left = (qse_awk_nde_t*)nde; - } - else - { - qse_awk_nde_exp_t* nde; - - right = parse_logical_and (awk, awk->token.line); - if (right == QSE_NULL) - { - qse_awk_clrpt (awk, left); - return QSE_NULL; - } - - 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); - - SETERRLIN (awk, QSE_AWK_ENOMEM, line); - return QSE_NULL; - } - - nde->type = QSE_AWK_NDE_EXP_BIN; - nde->line = line; - nde->next = QSE_NULL; - nde->opcode = QSE_AWK_BINOP_LOR; - nde->left = left; - nde->right = right; - - left = (qse_awk_nde_t*)nde; - } - } - - return left; + return parse_binary_expr (awk, line, 1, map, parse_logical_and); } static qse_awk_nde_t* parse_logical_and (qse_awk_t* awk, qse_size_t line) @@ -2458,117 +2359,14 @@ static qse_awk_nde_t* parse_regex_match (qse_awk_t* awk, qse_size_t line) static qse_awk_nde_t* parse_bitwise_or (qse_awk_t* awk, qse_size_t line) { - if (awk->option & QSE_AWK_RIO) + static binmap_t map[] = { - return parse_bitwise_or_with_io (awk, line); - } - else - { - static binmap_t map[] = - { - { TOKEN_BOR, QSE_AWK_BINOP_BOR }, - { TOKEN_EOF, 0 } - }; + { TOKEN_BOR, QSE_AWK_BINOP_BOR }, + { TOKEN_EOF, 0 } + }; - return parse_binary_expr ( - awk, line, 0, map, parse_bitwise_xor); - } -} - -static qse_awk_nde_t* parse_bitwise_or_with_io (qse_awk_t* awk, qse_size_t line) -{ - qse_awk_nde_t* left, * right; - - left = parse_bitwise_xor (awk, line); - if (left == QSE_NULL) return QSE_NULL; - - while (MATCH(awk,TOKEN_BOR)) - { - if (get_token(awk) <= -1) - { - qse_awk_clrpt (awk, left); - return QSE_NULL; - } - - if (MATCH(awk,TOKEN_GETLINE)) - { - qse_awk_nde_getline_t* nde; - qse_awk_nde_t* var = QSE_NULL; - - /* piped getline */ - if (get_token(awk) <= -1) - { - qse_awk_clrpt (awk, left); - return QSE_NULL; - } - - /* TODO: is this correct? */ - - if (MATCH(awk,TOKEN_IDENT)) - { - /* command | getline var */ - - var = parse_primary (awk, awk->token.line); - if (var == QSE_NULL) - { - qse_awk_clrpt (awk, left); - return QSE_NULL; - } - } - - nde = (qse_awk_nde_getline_t*) QSE_AWK_ALLOC ( - awk, QSE_SIZEOF(qse_awk_nde_getline_t)); - if (nde == QSE_NULL) - { - qse_awk_clrpt (awk, left); - - SETERRLIN (awk, QSE_AWK_ENOMEM, line); - return QSE_NULL; - } - - nde->type = QSE_AWK_NDE_GETLINE; - nde->line = line; - nde->next = QSE_NULL; - nde->var = var; - nde->in_type = QSE_AWK_IN_PIPE; - nde->in = left; - - left = (qse_awk_nde_t*)nde; - } - else - { - qse_awk_nde_exp_t* nde; - - right = parse_bitwise_xor (awk, awk->token.line); - if (right == QSE_NULL) - { - qse_awk_clrpt (awk, left); - return QSE_NULL; - } - - 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); - - SETERRLIN (awk, QSE_AWK_ENOMEM, line); - return QSE_NULL; - } - - nde->type = QSE_AWK_NDE_EXP_BIN; - nde->line = line; - nde->next = QSE_NULL; - nde->opcode = QSE_AWK_BINOP_BOR; - nde->left = left; - nde->right = right; - - left = (qse_awk_nde_t*)nde; - } - } - - return left; + return parse_binary_expr ( + awk, line, 0, map, parse_bitwise_xor); } static qse_awk_nde_t* parse_bitwise_xor (qse_awk_t* awk, qse_size_t line) @@ -2841,17 +2639,6 @@ static qse_awk_nde_t* parse_increment (qse_awk_t* awk, qse_size_t line) left = parse_primary (awk, line); if (left == QSE_NULL) return QSE_NULL; - if (awk->option & QSE_AWK_IMPLICIT) - { - /* concatenation operation by whitepaces are allowed - * if this option is set. the ++/-- operator following - * the primary should be treated specially. - * for example, "abc" ++ 10 => "abc" . ++10 - */ - /*if (!is_var(left)) return left; XXX */ - if (!is_var(left) && left->type != QSE_AWK_NDE_POS) return left; - } - /* check for postfix increment operator */ opcode2 = MATCH(awk,TOKEN_PLUSPLUS)? QSE_AWK_INCOP_PLUS: MATCH(awk,TOKEN_MINUSMINUS)? QSE_AWK_INCOP_MINUS: -1; @@ -2882,7 +2669,18 @@ static qse_awk_nde_t* parse_increment (qse_awk_t* awk, qse_size_t line) type = QSE_AWK_NDE_EXP_INCPST; opcode = opcode2; - if (get_token(awk) <= -1) return QSE_NULL; + if (get_token(awk) <= -1) + { + qse_awk_clrpt (awk, left); + return QSE_NULL; + } + } + + if (!is_var(left) && left->type != QSE_AWK_NDE_POS) + { + qse_awk_clrpt (awk, left); + SETERRLIN (awk, QSE_AWK_EINCDECOPR, line); + return QSE_NULL; } nde = (qse_awk_nde_exp_t*) @@ -2890,7 +2688,6 @@ static qse_awk_nde_t* parse_increment (qse_awk_t* awk, qse_size_t line) if (nde == QSE_NULL) { qse_awk_clrpt (awk, left); - SETERRLIN (awk, QSE_AWK_ENOMEM, line); return QSE_NULL; } @@ -2905,7 +2702,7 @@ static qse_awk_nde_t* parse_increment (qse_awk_t* awk, qse_size_t line) return (qse_awk_nde_t*)nde; } -static qse_awk_nde_t* parse_primary (qse_awk_t* awk, qse_size_t line) +static qse_awk_nde_t* parse_primary_nogetline (qse_awk_t* awk, qse_size_t line) { if (MATCH(awk,TOKEN_IDENT)) { @@ -3036,10 +2833,10 @@ static qse_awk_nde_t* parse_primary (qse_awk_t* awk, qse_size_t line) * of the context-sensitivity of the slash symbol. * if TOKEN_DIV is seen as a primary, it tries to compile * it as a regular expression */ - SET_TOKEN_TYPE (awk, TOKEN_REX); - + SET_TOKEN_TYPE (awk, &awk->token, TOKEN_REX); qse_str_clear (awk->token.name); - if (get_rexstr (awk) <= -1) return QSE_NULL; + if (get_rexstr (awk, &awk->token) <= -1) return QSE_NULL; + QSE_ASSERT (MATCH(awk,TOKEN_REX)); nde = (qse_awk_nde_rex_t*) QSE_AWK_ALLOC ( @@ -3270,10 +3067,95 @@ static qse_awk_nde_t* parse_primary (qse_awk_t* awk, qse_size_t line) /* valid expression introducer is expected */ SETERRLIN (awk, QSE_AWK_EEXPRES, - (MATCH(awk,TOKEN_EOF)? awk->token.prev.line: line)); + (MATCH(awk,TOKEN_EOF)? awk->ptoken.line: line)); return QSE_NULL; } +static qse_awk_nde_t* parse_primary (qse_awk_t* awk, qse_size_t line) +{ + qse_awk_nde_t* left; + qse_awk_nde_getline_t* nde; + qse_awk_nde_t* var; + + left = parse_primary_nogetline (awk, line); + + do + { + int intype = -1; + + if (awk->option & QSE_AWK_RIO) + { + if (MATCH(awk,TOKEN_BOR)) + { + intype = QSE_AWK_IN_PIPE; + } + else if (MATCH(awk,TOKEN_LOR)) + { + if (awk->option & QSE_AWK_RWPIPE) + intype = QSE_AWK_IN_RWPIPE; + } + } + + if (intype == -1) break; + + if (preget_token(awk) <= -1) + { + qse_awk_clrpt (awk, left); + return QSE_NULL; + } + + if (awk->atoken.type != TOKEN_GETLINE) break; + + var = QSE_NULL; + + /* consume atoken */ + get_token (awk); + + /* get the next token */ + if (get_token(awk) <= -1) + { + qse_awk_clrpt (awk, left); + return QSE_NULL; + } + + /* TODO: is this correct? */ + if (MATCH(awk,TOKEN_IDENT)) + { + /* command | getline var + * command || getline var */ + + var = parse_primary_ident (awk, awk->token.line); + if (var == QSE_NULL) + { + qse_awk_clrpt (awk, left); + return QSE_NULL; + } + } + + nde = (qse_awk_nde_getline_t*) QSE_AWK_ALLOC ( + awk, QSE_SIZEOF(qse_awk_nde_getline_t)); + if (nde == QSE_NULL) + { + qse_awk_clrpt (awk, left); + + SETERRLIN (awk, QSE_AWK_ENOMEM, line); + return QSE_NULL; + } + + nde->type = QSE_AWK_NDE_GETLINE; + nde->line = line; + nde->next = QSE_NULL; + nde->var = var; + nde->in_type = intype; + nde->in = left; + + left = (qse_awk_nde_t*)nde; + } + while (1); + + return left; +} + static qse_awk_nde_t* parse_primary_ident (qse_awk_t* awk, qse_size_t line) { qse_char_t* name_dup; @@ -3905,7 +3787,7 @@ static qse_awk_nde_t* parse_if (qse_awk_t* awk, qse_size_t line) return QSE_NULL; } - else_part = parse_statement (awk, awk->token.prev.line); + else_part = parse_statement (awk, awk->ptoken.line); if (else_part == QSE_NULL) { qse_awk_clrpt (awk, then_part); @@ -4184,7 +4066,7 @@ static qse_awk_nde_t* parse_dowhile (qse_awk_t* awk, qse_size_t line) qse_awk_nde_t* test, * body; qse_awk_nde_while_t* nde; - QSE_ASSERT (awk->token.prev.type == TOKEN_DO); + QSE_ASSERT (awk->ptoken.type == TOKEN_DO); body = parse_statement (awk, awk->token.line); if (body == QSE_NULL) return QSE_NULL; @@ -4273,7 +4155,7 @@ static qse_awk_nde_t* parse_break (qse_awk_t* awk, qse_size_t line) { qse_awk_nde_break_t* nde; - QSE_ASSERT (awk->token.prev.type == TOKEN_BREAK); + QSE_ASSERT (awk->ptoken.type == TOKEN_BREAK); if (awk->parse.depth.cur.loop <= 0) { SETERRLIN (awk, QSE_AWK_EBREAK, line); @@ -4299,7 +4181,7 @@ static qse_awk_nde_t* parse_continue (qse_awk_t* awk, qse_size_t line) { qse_awk_nde_continue_t* nde; - QSE_ASSERT (awk->token.prev.type == TOKEN_CONTINUE); + QSE_ASSERT (awk->ptoken.type == TOKEN_CONTINUE); if (awk->parse.depth.cur.loop <= 0) { SETERRLIN (awk, QSE_AWK_ECONTINUE, line); @@ -4326,7 +4208,7 @@ static qse_awk_nde_t* parse_return (qse_awk_t* awk, qse_size_t line) qse_awk_nde_return_t* nde; qse_awk_nde_t* val; - QSE_ASSERT (awk->token.prev.type == TOKEN_RETURN); + QSE_ASSERT (awk->ptoken.type == TOKEN_RETURN); nde = (qse_awk_nde_return_t*) QSE_AWK_ALLOC ( awk, QSE_SIZEOF(qse_awk_nde_return_t)); @@ -4364,7 +4246,7 @@ static qse_awk_nde_t* parse_exit (qse_awk_t* awk, qse_size_t line) qse_awk_nde_exit_t* nde; qse_awk_nde_t* val; - QSE_ASSERT (awk->token.prev.type == TOKEN_EXIT); + QSE_ASSERT (awk->ptoken.type == TOKEN_EXIT); nde = (qse_awk_nde_exit_t*) QSE_AWK_ALLOC (awk, QSE_SIZEOF(qse_awk_nde_exit_t)); @@ -4401,7 +4283,7 @@ static qse_awk_nde_t* parse_next (qse_awk_t* awk, qse_size_t line) { qse_awk_nde_next_t* nde; - QSE_ASSERT (awk->token.prev.type == TOKEN_NEXT); + QSE_ASSERT (awk->ptoken.type == TOKEN_NEXT); if (awk->parse.id.block == PARSE_BEGIN_BLOCK) { @@ -4464,7 +4346,7 @@ static qse_awk_nde_t* parse_delete (qse_awk_t* awk, qse_size_t line) qse_awk_nde_delete_t* nde; qse_awk_nde_t* var; - QSE_ASSERT (awk->token.prev.type == TOKEN_DELETE); + QSE_ASSERT (awk->ptoken.type == TOKEN_DELETE); if (!MATCH(awk,TOKEN_IDENT)) { SETERRTOK (awk, QSE_AWK_EIDENT); @@ -4503,7 +4385,7 @@ static qse_awk_nde_t* parse_reset (qse_awk_t* awk, qse_size_t line) qse_awk_nde_reset_t* nde; qse_awk_nde_t* var; - QSE_ASSERT (awk->token.prev.type == TOKEN_RESET); + QSE_ASSERT (awk->ptoken.type == TOKEN_RESET); if (!MATCH(awk,TOKEN_IDENT)) { SETERRTOK (awk, QSE_AWK_EIDENT); @@ -4590,7 +4472,7 @@ static qse_awk_nde_t* parse_print (qse_awk_t* awk, qse_size_t line, int type) /* print 1 > 2 would print 1 to the file named 2. * print (1 > 2) would print (1 > 2) on the console */ - if (awk->token.prev.type != TOKEN_RPAREN && + if (awk->ptoken.type != TOKEN_RPAREN && args_tail->type == QSE_AWK_NDE_EXP_BIN) { int i; @@ -4707,18 +4589,11 @@ static qse_awk_nde_t* parse_print (qse_awk_t* awk, qse_size_t line, int type) return (qse_awk_nde_t*)nde; } -static int get_token (qse_awk_t* awk) +static int get_token_into (qse_awk_t* awk, qse_awk_token_t* token) { qse_cint_t c; - qse_size_t line; int n; - line = awk->token.line; - - awk->token.prev.type = awk->token.type; - awk->token.prev.line = awk->token.line; - awk->token.prev.column = awk->token.column; - do { if (skip_spaces(awk) <= -1) return -1; @@ -4726,27 +4601,27 @@ static int get_token (qse_awk_t* awk) } while (n >= 1); - qse_str_clear (awk->token.name); - awk->token.line = awk->src.lex.line; - awk->token.column = awk->src.lex.column; + qse_str_clear (token->name); + token->line = awk->src.lex.line; + token->column = awk->src.lex.column; c = awk->src.lex.curc; if (c == QSE_CHAR_EOF) { - ADD_TOKEN_STR (awk, QSE_T(""), 5); - SET_TOKEN_TYPE (awk, TOKEN_EOF); + ADD_TOKEN_STR (awk, token, QSE_T(""), 5); + SET_TOKEN_TYPE (awk, token, TOKEN_EOF); } else if (c == QSE_T('\n')) { - /*ADD_TOKEN_CHAR (awk, QSE_T('\n'));*/ - ADD_TOKEN_STR (awk, QSE_T(""), 4); - SET_TOKEN_TYPE (awk, TOKEN_NEWLINE); + /*ADD_TOKEN_CHAR (awk, token, QSE_T('\n'));*/ + ADD_TOKEN_STR (awk, token, QSE_T(""), 4); + SET_TOKEN_TYPE (awk, token, TOKEN_NEWLINE); GET_CHAR (awk); } else if (QSE_AWK_ISDIGIT (awk, c)/*|| c == QSE_T('.')*/) { - if (get_number (awk) <= -1) return -1; + if (get_number (awk, token) <= -1) return -1; } else if (c == QSE_T('.')) { @@ -4757,19 +4632,19 @@ static int get_token (qse_awk_t* awk) { awk->src.lex.curc = QSE_T('.'); UNGET_CHAR (awk, c); - if (get_number (awk) <= -1) return -1; + if (get_number (awk, token) <= -1) return -1; } else /*if (QSE_AWK_ISSPACE (awk, c) || c == QSE_CHAR_EOF)*/ { - SET_TOKEN_TYPE (awk, TOKEN_PERIOD); - ADD_TOKEN_CHAR (awk, QSE_T('.')); + SET_TOKEN_TYPE (awk, token, TOKEN_PERIOD); + ADD_TOKEN_CHAR (awk, token, QSE_T('.')); } /* else { qse_awk_seterror ( - awk, QSE_AWK_ELXCHR, awk->token.line, + awk, QSE_AWK_ELXCHR, token->line, QSE_T("floating point not followed by any valid digits")); return -1; } @@ -4782,7 +4657,7 @@ static int get_token (qse_awk_t* awk) /* identifier */ do { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); } while (c == QSE_T('_') || @@ -4790,290 +4665,294 @@ static int get_token (qse_awk_t* awk) QSE_AWK_ISDIGIT (awk, c)); type = classify_ident (awk, - QSE_STR_PTR(awk->token.name), - QSE_STR_LEN(awk->token.name)); - SET_TOKEN_TYPE (awk, type); + QSE_STR_PTR(token->name), + QSE_STR_LEN(token->name)); + SET_TOKEN_TYPE (awk, token, type); } else if (c == QSE_T('\"')) { - SET_TOKEN_TYPE (awk, TOKEN_STR); - if (get_charstr(awk) <= -1) return -1; + SET_TOKEN_TYPE (awk, token, TOKEN_STR); + if (get_charstr(awk, token) <= -1) return -1; } else if (c == QSE_T('=')) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); if (c == QSE_T('=')) { - SET_TOKEN_TYPE (awk, TOKEN_EQ); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_EQ); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else { - SET_TOKEN_TYPE (awk, TOKEN_ASSIGN); + SET_TOKEN_TYPE (awk, token, TOKEN_ASSIGN); } } else if (c == QSE_T('!')) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); if (c == QSE_T('=')) { - SET_TOKEN_TYPE (awk, TOKEN_NE); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_NE); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else if (c == QSE_T('~')) { - SET_TOKEN_TYPE (awk, TOKEN_NM); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_NM); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else { - SET_TOKEN_TYPE (awk, TOKEN_LNOT); + SET_TOKEN_TYPE (awk, token, TOKEN_LNOT); } } else if (c == QSE_T('>')) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); if (c == QSE_T('>')) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); if ((awk->option & QSE_AWK_SHIFT) && c == QSE_T('=')) { - SET_TOKEN_TYPE (awk, TOKEN_RSHIFT_ASSIGN); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_RSHIFT_ASSIGN); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else { - SET_TOKEN_TYPE (awk, TOKEN_RSHIFT); + SET_TOKEN_TYPE (awk, token, TOKEN_RSHIFT); } } else if (c == QSE_T('=')) { - SET_TOKEN_TYPE (awk, TOKEN_GE); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_GE); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else { - SET_TOKEN_TYPE (awk, TOKEN_GT); + SET_TOKEN_TYPE (awk, token, TOKEN_GT); } } else if (c == QSE_T('<')) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); if ((awk->option & QSE_AWK_SHIFT) && c == QSE_T('<')) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); if (c == QSE_T('=')) { - SET_TOKEN_TYPE (awk, TOKEN_LSHIFT_ASSIGN); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_LSHIFT_ASSIGN); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else { - SET_TOKEN_TYPE (awk, TOKEN_LSHIFT); + SET_TOKEN_TYPE (awk, token, TOKEN_LSHIFT); } } else if (c == QSE_T('=')) { - SET_TOKEN_TYPE (awk, TOKEN_LE); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_LE); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else { - SET_TOKEN_TYPE (awk, TOKEN_LT); + SET_TOKEN_TYPE (awk, token, TOKEN_LT); } } else if (c == QSE_T('|')) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); if (c == QSE_T('|')) { - SET_TOKEN_TYPE (awk, TOKEN_LOR); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_LOR); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else if (c == QSE_T('=')) { - SET_TOKEN_TYPE (awk, TOKEN_BOR_ASSIGN); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_BOR_ASSIGN); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else { - SET_TOKEN_TYPE (awk, TOKEN_BOR); + SET_TOKEN_TYPE (awk, token, TOKEN_BOR); } } else if (c == QSE_T('&')) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); if (c == QSE_T('&')) { - SET_TOKEN_TYPE (awk, TOKEN_LAND); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_LAND); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else if (c == QSE_T('=')) { - SET_TOKEN_TYPE (awk, TOKEN_BAND_ASSIGN); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_BAND_ASSIGN); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else { - SET_TOKEN_TYPE (awk, TOKEN_BAND); + SET_TOKEN_TYPE (awk, token, TOKEN_BAND); } } else if (c == QSE_T('^')) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); if (c == QSE_T('=')) { - SET_TOKEN_TYPE (awk, ((awk->option & QSE_AWK_BXOR)? - TOKEN_BXOR_ASSIGN: TOKEN_EXP_ASSIGN)); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, + ((awk->option & QSE_AWK_BXOR)? + TOKEN_BXOR_ASSIGN: TOKEN_EXP_ASSIGN) + ); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else { - SET_TOKEN_TYPE (awk, ((awk->option & QSE_AWK_BXOR)? - TOKEN_BXOR: TOKEN_EXP)); + SET_TOKEN_TYPE (awk, token, + ((awk->option & QSE_AWK_BXOR)? + TOKEN_BXOR: TOKEN_EXP) + ); } } else if (c == QSE_T('+')) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); if (c == QSE_T('+')) { - SET_TOKEN_TYPE (awk, TOKEN_PLUSPLUS); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_PLUSPLUS); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else if (c == QSE_T('=')) { - SET_TOKEN_TYPE (awk, TOKEN_PLUS_ASSIGN); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_PLUS_ASSIGN); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else { - SET_TOKEN_TYPE (awk, TOKEN_PLUS); + SET_TOKEN_TYPE (awk, token, TOKEN_PLUS); } } else if (c == QSE_T('-')) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); if (c == QSE_T('-')) { - SET_TOKEN_TYPE (awk, TOKEN_MINUSMINUS); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_MINUSMINUS); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else if (c == QSE_T('=')) { - SET_TOKEN_TYPE (awk, TOKEN_MINUS_ASSIGN); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_MINUS_ASSIGN); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else { - SET_TOKEN_TYPE (awk, TOKEN_MINUS); + SET_TOKEN_TYPE (awk, token, TOKEN_MINUS); } } else if (c == QSE_T('*')) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); if (c == QSE_T('=')) { - SET_TOKEN_TYPE (awk, TOKEN_MUL_ASSIGN); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_MUL_ASSIGN); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else if (c == QSE_T('*')) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); if (c == QSE_T('=')) { - SET_TOKEN_TYPE (awk, TOKEN_EXP_ASSIGN); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_EXP_ASSIGN); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else { - SET_TOKEN_TYPE (awk, TOKEN_EXP); + SET_TOKEN_TYPE (awk, token, TOKEN_EXP); } } else { - SET_TOKEN_TYPE (awk, TOKEN_MUL); + SET_TOKEN_TYPE (awk, token, TOKEN_MUL); } } else if (c == QSE_T('/')) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); if (c == QSE_T('=')) { - SET_TOKEN_TYPE (awk, TOKEN_DIV_ASSIGN); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_DIV_ASSIGN); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else if ((awk->option & QSE_AWK_IDIV) && c == QSE_T('/')) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); if (c == QSE_T('=')) { - SET_TOKEN_TYPE (awk, TOKEN_IDIV_ASSIGN); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_IDIV_ASSIGN); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else { - SET_TOKEN_TYPE (awk, TOKEN_IDIV); + SET_TOKEN_TYPE (awk, token, TOKEN_IDIV); } } else { - SET_TOKEN_TYPE (awk, TOKEN_DIV); + SET_TOKEN_TYPE (awk, token, TOKEN_DIV); } } else if (c == QSE_T('%')) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); if (c == QSE_T('=')) { - SET_TOKEN_TYPE (awk, TOKEN_MOD_ASSIGN); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, TOKEN_MOD_ASSIGN); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else { - SET_TOKEN_TYPE (awk, TOKEN_MOD); + SET_TOKEN_TYPE (awk, token, TOKEN_MOD); } } else @@ -5104,8 +4983,8 @@ static int get_token (qse_awk_t* awk) { if (c == tab[i].c) { - SET_TOKEN_TYPE (awk, tab[i].t); - ADD_TOKEN_CHAR (awk, c); + SET_TOKEN_TYPE (awk, token, tab[i].t); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); goto get_token_ok; } @@ -5113,12 +4992,12 @@ static int get_token (qse_awk_t* awk) if (c == QSE_T('\0')) { - SETERRARG (awk, QSE_AWK_ELXCHR, awk->token.line, QSE_T(""), 5); + SETERRARG (awk, QSE_AWK_ELXCHR, token->line, QSE_T(""), 5); } else { qse_char_t cc = (qse_char_t)c; - SETERRARG (awk, QSE_AWK_ELXCHR, awk->token.line, &cc, 1); + SETERRARG (awk, QSE_AWK_ELXCHR, token->line, &cc, 1); } return -1; } @@ -5127,18 +5006,44 @@ get_token_ok: return 0; } -static int get_number (qse_awk_t* awk) +static int get_token (qse_awk_t* awk) +{ + awk->ptoken.type = awk->token.type; + awk->ptoken.line = awk->token.line; + awk->ptoken.column = awk->token.column; + + if (QSE_STR_LEN(awk->atoken.name) > 0) + { + awk->token.type = awk->atoken.type; + awk->token.line = awk->atoken.line; + awk->token.column = awk->token.column; + + qse_str_swap (awk->token.name, awk->atoken.name); + qse_str_clear (awk->atoken.name); + + return 0; + } + + return get_token_into (awk, &awk->token); +} + +static int preget_token (qse_awk_t* awk) +{ + return get_token_into (awk, &awk->atoken); +} + +static int get_number (qse_awk_t* awk, qse_awk_token_t* token) { qse_cint_t c; - QSE_ASSERT (QSE_STR_LEN(awk->token.name) == 0); - SET_TOKEN_TYPE (awk, TOKEN_INT); + QSE_ASSERT (QSE_STR_LEN(token->name) == 0); + SET_TOKEN_TYPE (awk, token, TOKEN_INT); c = awk->src.lex.curc; if (c == QSE_T('0')) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); if (c == QSE_T('x') || c == QSE_T('X')) @@ -5146,7 +5051,7 @@ static int get_number (qse_awk_t* awk) /* hexadecimal number */ do { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); } while (QSE_AWK_ISXDIGIT (awk, c)); @@ -5158,7 +5063,7 @@ static int get_number (qse_awk_t* awk) /* binary number */ do { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); } while (c == QSE_T('0') || c == QSE_T('1')); @@ -5170,7 +5075,7 @@ static int get_number (qse_awk_t* awk) /* octal number */ while (c >= QSE_T('0') && c <= QSE_T('7')) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); } @@ -5187,41 +5092,41 @@ static int get_number (qse_awk_t* awk) while (QSE_AWK_ISDIGIT (awk, c)) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); } if (c == QSE_T('.')) { /* floating-point number */ - SET_TOKEN_TYPE (awk, TOKEN_REAL); + SET_TOKEN_TYPE (awk, token, TOKEN_REAL); - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); while (QSE_AWK_ISDIGIT (awk, c)) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); } } if (c == QSE_T('E') || c == QSE_T('e')) { - SET_TOKEN_TYPE (awk, TOKEN_REAL); + SET_TOKEN_TYPE (awk, token, TOKEN_REAL); - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); if (c == QSE_T('+') || c == QSE_T('-')) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); } while (QSE_AWK_ISDIGIT (awk, c)) { - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); } } @@ -5229,18 +5134,18 @@ static int get_number (qse_awk_t* awk) return 0; } -static int get_charstr (qse_awk_t* awk) +static int get_charstr (qse_awk_t* awk, qse_awk_token_t* token) { if (awk->src.lex.curc != QSE_T('\"')) { /* the starting quote has been consumed before this function * has been called */ - ADD_TOKEN_CHAR (awk, awk->src.lex.curc); + ADD_TOKEN_CHAR (awk, token, awk->src.lex.curc); } - return get_string (awk, QSE_T('\"'), QSE_T('\\'), QSE_FALSE, 0); + return get_string (awk, QSE_T('\"'), QSE_T('\\'), QSE_FALSE, 0, token); } -static int get_rexstr (qse_awk_t* awk) +static int get_rexstr (qse_awk_t* awk, qse_awk_token_t* token) { if (awk->src.lex.curc == QSE_T('/')) { @@ -5269,17 +5174,17 @@ static int get_rexstr (qse_awk_t* awk) { /* add other initial characters here as get_string() * begins with reading the next character */ - ADD_TOKEN_CHAR (awk, awk->src.lex.curc); + ADD_TOKEN_CHAR (awk, token, awk->src.lex.curc); } - return get_string (awk, - QSE_T('/'), QSE_T('\\'), QSE_TRUE, escaped); + return get_string ( + awk, QSE_T('/'), QSE_T('\\'), QSE_TRUE, escaped, token); } } static int get_string ( qse_awk_t* awk, qse_char_t end_char, qse_char_t esc_char, qse_bool_t keep_esc_char, - int preescaped) + int preescaped, qse_awk_token_t* token) { qse_cint_t c; int escaped = preescaped; @@ -5304,14 +5209,14 @@ static int get_string ( digit_count++; if (digit_count >= escaped) { - ADD_TOKEN_CHAR (awk, c_acc); + ADD_TOKEN_CHAR (awk, token, c_acc); escaped = 0; } continue; } else { - ADD_TOKEN_CHAR (awk, c_acc); + ADD_TOKEN_CHAR (awk, token, c_acc); escaped = 0; } } @@ -5323,7 +5228,7 @@ static int get_string ( digit_count++; if (digit_count >= escaped) { - ADD_TOKEN_CHAR (awk, c_acc); + ADD_TOKEN_CHAR (awk, token, c_acc); escaped = 0; } continue; @@ -5334,7 +5239,7 @@ static int get_string ( digit_count++; if (digit_count >= escaped) { - ADD_TOKEN_CHAR (awk, c_acc); + ADD_TOKEN_CHAR (awk, token, c_acc); escaped = 0; } continue; @@ -5345,7 +5250,7 @@ static int get_string ( digit_count++; if (digit_count >= escaped) { - ADD_TOKEN_CHAR (awk, c_acc); + ADD_TOKEN_CHAR (awk, token, c_acc); escaped = 0; } continue; @@ -5357,8 +5262,9 @@ static int get_string ( rc = (escaped == 2)? QSE_T('x'): (escaped == 4)? QSE_T('u'): QSE_T('U'); - if (digit_count == 0) ADD_TOKEN_CHAR (awk, rc); - else ADD_TOKEN_CHAR (awk, c_acc); + if (digit_count == 0) + ADD_TOKEN_CHAR (awk, token, rc); + else ADD_TOKEN_CHAR (awk, token, c_acc); escaped = 0; } @@ -5419,13 +5325,13 @@ static int get_string ( #endif else if (keep_esc_char) { - ADD_TOKEN_CHAR (awk, esc_char); + ADD_TOKEN_CHAR (awk, token, esc_char); } escaped = 0; } - ADD_TOKEN_CHAR (awk, c); + ADD_TOKEN_CHAR (awk, token, c); } return 0; @@ -5969,8 +5875,6 @@ exit_deparse: return n; } - - static qse_map_walk_t deparse_func ( qse_map_t* map, qse_map_pair_t* pair, void* arg) { diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index c69500fb..40ef61f9 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c 230 2009-07-13 08:51:23Z hyunghwan.chung $ + * $Id: run.c 232 2009-07-14 08:06:14Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -4021,7 +4021,8 @@ static int __cmp_int_str ( qse_awk_rtx_valtostr_out_t out; int n; - if (rtx->awk->option & QSE_AWK_NCMPONSTR || right->nstr > 0) + /* SCO CC doesn't seem to handle right->nstr > 0 properly */ + if (rtx->awk->option & QSE_AWK_NCMPONSTR || right->nstr /*> 0*/) { qse_long_t ll; qse_real_t rr; @@ -4107,7 +4108,8 @@ static int __cmp_real_str ( qse_awk_rtx_valtostr_out_t out; int n; - if (rtx->awk->option & QSE_AWK_NCMPONSTR || right->nstr > 0) + /* SCO CC doesn't seem to handle right->nstr > 0 properly */ + if (rtx->awk->option & QSE_AWK_NCMPONSTR || right->nstr /*> 0*/) { const qse_char_t* end; qse_real_t rr; diff --git a/qse/lib/awk/tree.c b/qse/lib/awk/tree.c index d5e878fa..89246b91 100644 --- a/qse/lib/awk/tree.c +++ b/qse/lib/awk/tree.c @@ -1,5 +1,5 @@ /* - * $Id: tree.c 210 2009-06-24 08:29:33Z hyunghwan.chung $ + * $Id: tree.c 232 2009-07-14 08:06:14Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -552,6 +552,9 @@ static int print_expression (qse_awk_t* awk, qse_awk_nde_t* nde) case QSE_AWK_NDE_GETLINE: { qse_awk_nde_getline_t* px = (qse_awk_nde_getline_t*)nde; + + PUT_SRCSTR (awk, QSE_T("(")); + if (px->in != QSE_NULL && (px->in_type == QSE_AWK_IN_PIPE || px->in_type == QSE_AWK_IN_RWPIPE)) @@ -578,6 +581,8 @@ static int print_expression (qse_awk_t* awk, qse_awk_nde_t* nde) PUT_SRCSTR (awk, QSE_T(" ")); PRINT_EXPRESSION (awk, px->in); } + + PUT_SRCSTR (awk, QSE_T(")")); break; } diff --git a/qse/regress/awk/lang-032.awk b/qse/regress/awk/lang-032.awk new file mode 100644 index 00000000..d3b11aaa --- /dev/null +++ b/qse/regress/awk/lang-032.awk @@ -0,0 +1,14 @@ +BEGIN { + a=91 + print a ++10; # print 9110 + print a ++10; # print 9210 + print (a) ++10; # print 9310 + print ((a)) ++10; # print 9410 + print ((a)++) 10; # print 9510 + + print "---------------------" + a=91 + print (++(a)) 10; # print 9210 +} + + diff --git a/qse/regress/awk/lang-033.awk b/qse/regress/awk/lang-033.awk new file mode 100644 index 00000000..50f93069 --- /dev/null +++ b/qse/regress/awk/lang-033.awk @@ -0,0 +1,4 @@ +BEGIN { + while ("cat lang-033.awk" | getline x > 0) + print x +} diff --git a/qse/regress/awk/regress.out b/qse/regress/awk/regress.out index cd7f4a0b..e613b78b 100644 --- a/qse/regress/awk/regress.out +++ b/qse/regress/awk/regress.out @@ -1352,7 +1352,7 @@ BEGIN { printf ("%s\n",10.34); } -ERROR: CODE [110] LINE [3] recursion detected in format conversion +ERROR: CODE [111] LINE [3] recursion detected in format conversion -------------------------------------------------------------------------------- ../../cmd/awk/qseawk --newline=on -o- -f lang-014.awk &1 -------------------------------------------------------------------------------- @@ -1520,7 +1520,7 @@ BEGIN { delete iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiix; } -ERROR: CODE [84] LINE [3] variable 'iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiix' not deletable +ERROR: CODE [85] LINE [3] variable 'iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiix' not deletable -------------------------------------------------------------------------------- ../../cmd/awk/qseawk --newline=on -o- -f lang-026.awk &1 -------------------------------------------------------------------------------- @@ -1532,7 +1532,7 @@ BEGIN { } abc -ERROR: CODE [92] LINE [4] map 'abc' not assignable with a scalar +ERROR: CODE [93] LINE [4] map 'abc' not assignable with a scalar -------------------------------------------------------------------------------- ../../cmd/awk/qseawk --newline=on -o- -f lang-027.awk &1 -------------------------------------------------------------------------------- @@ -1632,6 +1632,40 @@ BEGIN { 0 -1 -------------------------- -------------------------------------------------------------------------------- +../../cmd/awk/qseawk --newline=on -o- -f lang-032.awk &1 +-------------------------------------------------------------------------------- +BEGIN { + a = 91; + print ((a)++ 10); + print ((a)++ 10); + print ((a)++ 10); + print ((a)++ 10); + print ((a)++ 10); + print "---------------------"; + a = 91; + print (++(a) 10); +} + +9110 +9210 +9310 +9410 +9510 +--------------------- +9210 +-------------------------------------------------------------------------------- +../../cmd/awk/qseawk --newline=on -o- -f lang-033.awk &1 +-------------------------------------------------------------------------------- +BEGIN { + while ((("cat lang-033.awk" | getline x) > 0)) + print x; +} + +BEGIN { + while ("cat lang-033.awk" | getline x > 0) + print x +} +-------------------------------------------------------------------------------- ../../cmd/awk/qseawk -f quicksort.awk quicksort.dat &1 -------------------------------------------------------------------------------- 0.0000000000 diff --git a/qse/regress/awk/regress.sh b/qse/regress/awk/regress.sh index 155b2075..085064f6 100755 --- a/qse/regress/awk/regress.sh +++ b/qse/regress/awk/regress.sh @@ -134,6 +134,8 @@ PROGS=" lang-029.awk///--explicit=on --newline=on -o- lang-030.awk///--newline=on -o- lang-031.awk///--newline=on -o- + lang-032.awk///--newline=on -o- + lang-033.awk///--newline=on -o- quicksort.awk/quicksort.dat// quicksort2.awk/quicksort2.dat// diff --git a/qse/samples/awk/awk07.cpp b/qse/samples/awk/awk07.cpp index d33c53d1..5b3b5128 100644 --- a/qse/samples/awk/awk07.cpp +++ b/qse/samples/awk/awk07.cpp @@ -37,7 +37,7 @@ static int run_awk (QSE::StdAwk& awk) "function pa (x) {\n" " reset ret;\n" " for (i in x) { print i, \"=>\", x[i]; ret += x[i]; }\n" - " return ret;\n" + " return ret + DAMN++;\n" "}\n" "function pb (x) {\n" " reset ret;\n" @@ -46,6 +46,10 @@ static int run_awk (QSE::StdAwk& awk) "}" )); + // add a global variable 'DAMN' + int damn = awk.addGlobal (QSE_T("DAMN")); + if (damn <= -1) return -1; + // parse the script and perform no deparsing run = awk.parse (in, QSE::StdAwk::Source::NONE); if (run == QSE_NULL) return -1; @@ -59,6 +63,11 @@ static int run_awk (QSE::StdAwk& awk) run, QSE::StdAwk::Value::IntIndex(i), i*20) <= -1) return -1; } + // set 'DAMN' to 100000 + QSE::StdAwk::Value damnv (run); + if (damnv.setInt (100000) <= -1) return -1; + if (awk.setGlobal (damn, damnv) <= -1) return -1; + QSE::StdAwk::Value r; // call the 'pa' function @@ -69,6 +78,12 @@ static int run_awk (QSE::StdAwk& awk) qse_printf (QSE_T(" (real) [%Lf]\n"), (long double)r.toReal()); qse_printf (QSE_T(" (str) [%s]\n"), r.toStr(QSE_NULL)); + // get the value of 'DAMN' + if (awk.getGlobal (damn, damnv) <= -1) return -1; + qse_printf (QSE_T("DAMN: (int) [%lld]\n"), (long long)damnv.toInt()); + qse_printf (QSE_T(" (real) [%Lf]\n"), (long double)damnv.toReal()); + qse_printf (QSE_T(" (str) [%s]\n"), damnv.toStr(QSE_NULL)); + // call the 'pb' function if (awk.call (QSE_T("pb"), &r, arg, QSE_COUNTOF(arg)) <= -1) return -1;