diff --git a/qse/cmd/awk/awk.c b/qse/cmd/awk/awk.c index 649ebde0..9bdecdba 100644 --- a/qse/cmd/awk/awk.c +++ b/qse/cmd/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c 237 2009-07-16 12:43:47Z hyunghwan.chung $ + * $Id: awk.c 238 2009-07-17 12:42:02Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -325,9 +325,7 @@ struct opttab_t { { QSE_T("implicit"), QSE_AWK_IMPLICIT, QSE_T("allow undeclared variables") }, { QSE_T("explicit"), QSE_AWK_EXPLICIT, QSE_T("allow declared variables(local,global)") }, - { QSE_T("bxor"), QSE_AWK_BXOR, QSE_T("enable bit-wise XOR operator(^)") }, - { QSE_T("shift"), QSE_AWK_SHIFT, QSE_T("enable shift operators(<<,>>)") }, - { QSE_T("idiv"), QSE_AWK_IDIV, QSE_T("enable idiv operator(//)") }, + { QSE_T("extraops"), QSE_AWK_EXTRAOPS, QSE_T("enable extra operators(<<,>>,^^,//)") }, { QSE_T("rio"), QSE_AWK_RIO, QSE_T("enable builtin I/O including getline & print") }, { QSE_T("rwpipe"), QSE_AWK_RWPIPE, QSE_T("allow a dual-directional pipe") }, { QSE_T("newline"), QSE_AWK_NEWLINE, QSE_T("enable a newline to terminate a statement") }, @@ -372,13 +370,12 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg) { { QSE_T(":implicit"), QSE_T('\0') }, { QSE_T(":explicit"), QSE_T('\0') }, - { QSE_T(":bxor"), QSE_T('\0') }, - { QSE_T(":shift"), QSE_T('\0') }, - { QSE_T(":idiv"), QSE_T('\0') }, + { QSE_T(":extraops"), QSE_T('\0') }, { QSE_T(":rio"), QSE_T('\0') }, { QSE_T(":rwpipe"), QSE_T('\0') }, { QSE_T(":newline"), QSE_T('\0') }, - { QSE_T(":stripspaces"), QSE_T('\0') }, + { QSE_T(":striprecspc"), QSE_T('\0') }, + { QSE_T(":stripstrspc"), QSE_T('\0') }, { QSE_T(":nextofile"), QSE_T('\0') }, { QSE_T(":reset"), QSE_T('\0') }, { QSE_T(":crlf"), QSE_T('\0') }, @@ -531,8 +528,13 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg) { if (qse_strcmp (opt.arg, QSE_T("off")) == 0) arg->optoff |= opttab[i].opt; - else + else if (qse_strcmp (opt.arg, QSE_T("on")) == 0) arg->opton |= opttab[i].opt; + else + { + print_err (QSE_T("invalid value for '%s' - '%s'\n"), opt.lngopt, opt.arg); + goto oops; + } break; } } diff --git a/qse/include/qse/awk/Awk.hpp b/qse/include/qse/awk/Awk.hpp index 407506c3..cc2602cd 100644 --- a/qse/include/qse/awk/Awk.hpp +++ b/qse/include/qse/awk/Awk.hpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.hpp 237 2009-07-16 12:43:47Z hyunghwan.chung $ + * $Id: Awk.hpp 238 2009-07-17 12:42:02Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -843,9 +843,7 @@ public: { OPT_IMPLICIT = QSE_AWK_IMPLICIT, OPT_EXPLICIT = QSE_AWK_EXPLICIT, - OPT_BXOR = QSE_AWK_BXOR, - OPT_SHIFT = QSE_AWK_SHIFT, - OPT_IDIV = QSE_AWK_IDIV, + OPT_EXTRAOPS = QSE_AWK_EXTRAOPS, OPT_RIO = QSE_AWK_RIO, OPT_RWPIPE = QSE_AWK_RWPIPE, diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index b1d75832..e22c2201 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h 237 2009-07-16 12:43:47Z hyunghwan.chung $ + * $Id: awk.h 238 2009-07-17 12:42:02Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -499,23 +499,24 @@ enum qse_awk_option_t */ QSE_AWK_EXPLICIT = (1 << 1), - /** changes @b ^ from exponentation to bitwise xor */ - QSE_AWK_BXOR = (1 << 3), - - /** supports shift operators: @b << and @b >> */ - QSE_AWK_SHIFT = (1 << 4), - - /** enables the idiv operator: @b // */ - QSE_AWK_IDIV = (1 << 5), + /** + * supports extra operators: + * - @b <<, <<= left-shift + * - @b >>, >>= right-shiftt + * - @b ^^, ^^= xor + * - @b ~ bitwise-not + * - @b // idiv (get quotient) + */ + QSE_AWK_EXTRAOPS = (1 << 2), /** supports @b getline and @b print */ - QSE_AWK_RIO = (1 << 7), + QSE_AWK_RIO = (1 << 3), /** supports dual direction pipe if #QSE_AWK_RIO is on */ - QSE_AWK_RWPIPE = (1 << 8), + QSE_AWK_RWPIPE = (1 << 4), /** a new line can terminate a statement */ - QSE_AWK_NEWLINE = (1 << 9), + QSE_AWK_NEWLINE = (1 << 5), /** * strips off leading and trailing spaces when splitting a record @@ -531,30 +532,30 @@ enum qse_awk_option_t * " a b c " is split to [a], [b], [c] if #QSE_AWK_STRIPRSPC is on. * Otherwise, it is split to [], [a], [b], [c], []. */ - QSE_AWK_STRIPRECSPC = (1 << 10), + QSE_AWK_STRIPRECSPC = (1 << 6), /** * strips off leading spaces when converting a string to a number. */ - QSE_AWK_STRIPSTRSPC = (1 << 11), + QSE_AWK_STRIPSTRSPC = (1 << 7), /** enables @b nextofile */ - QSE_AWK_NEXTOFILE = (1 << 12), + QSE_AWK_NEXTOFILE = (1 << 8), /** enables @b reset */ - QSE_AWK_RESET = (1 << 13), + QSE_AWK_RESET = (1 << 9), /** CR + LF by default */ - QSE_AWK_CRLF = (1 << 14), + QSE_AWK_CRLF = (1 << 10), /** allows the assignment of a map value to a variable */ - QSE_AWK_MAPTOVAR = (1 << 15), + QSE_AWK_MAPTOVAR = (1 << 11), /** allows @b BEGIN, @b END, pattern-action blocks */ - QSE_AWK_PABLOCK = (1 << 16), + QSE_AWK_PABLOCK = (1 << 12), /** allows {n,m} in a regular expression. */ - QSE_AWK_REXBOUND = (1 << 17), + QSE_AWK_REXBOUND = (1 << 13), /** * performs numeric comparison when a string convertable @@ -564,14 +565,14 @@ enum qse_awk_option_t * - 9 is greater if #QSE_AWK_NCMPONSTR is off; * - "10.9" is greater if #QSE_AWK_NCMPONSTR is on */ - QSE_AWK_NCMPONSTR = (1 << 18), + QSE_AWK_NCMPONSTR = (1 << 14), /** * enables the strict naming rule. * - a parameter can not be the same as the owning function name. * - a local variable can not be the same as the owning function name. */ - QSE_AWK_STRICTNAMING = (1 << 19), + QSE_AWK_STRICTNAMING = (1 << 15), /** * makes #qse_awk_t to behave as compatibly as classical AWK diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index 0a0193ac..99d3219b 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c 232 2009-07-14 08:06:14Z hyunghwan.chung $ + * $Id: parse.c 238 2009-07-17 12:42:02Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -33,8 +33,8 @@ enum token_t TOKEN_IDIV_ASSIGN, TOKEN_MOD_ASSIGN, TOKEN_EXP_ASSIGN, - TOKEN_RSHIFT_ASSIGN, - TOKEN_LSHIFT_ASSIGN, + TOKEN_RS_ASSIGN, + TOKEN_LS_ASSIGN, TOKEN_BAND_ASSIGN, TOKEN_BXOR_ASSIGN, TOKEN_BOR_ASSIGN, @@ -61,8 +61,8 @@ enum token_t TOKEN_BXOR, TOKEN_BAND, TOKEN_TILDE, /* used for unary bitwise-not and regex match */ - TOKEN_RSHIFT, - TOKEN_LSHIFT, + TOKEN_RS, + TOKEN_LS, TOKEN_IN, TOKEN_EXP, @@ -2415,15 +2415,15 @@ static qse_awk_nde_t* parse_relational (qse_awk_t* awk, qse_size_t line) }; return parse_binary_expr (awk, line, 0, map, - ((awk->option & QSE_AWK_SHIFT)? parse_shift: parse_concat)); + ((awk->option & QSE_AWK_EXTRAOPS)? parse_shift: parse_concat)); } static qse_awk_nde_t* parse_shift (qse_awk_t* awk, qse_size_t line) { static binmap_t map[] = { - { TOKEN_LSHIFT, QSE_AWK_BINOP_LSHIFT }, - { TOKEN_RSHIFT, QSE_AWK_BINOP_RSHIFT }, + { TOKEN_LS, QSE_AWK_BINOP_LS }, + { TOKEN_RS, QSE_AWK_BINOP_RS }, { TOKEN_EOF, 0 } }; @@ -2526,7 +2526,8 @@ static qse_awk_nde_t* parse_unary (qse_awk_t* awk, qse_size_t line) opcode = (MATCH(awk,TOKEN_PLUS))? QSE_AWK_UNROP_PLUS: (MATCH(awk,TOKEN_MINUS))? QSE_AWK_UNROP_MINUS: (MATCH(awk,TOKEN_LNOT))? QSE_AWK_UNROP_LNOT: - (MATCH(awk,TOKEN_TILDE))? QSE_AWK_UNROP_BNOT: -1; + ((awk->option & QSE_AWK_EXTRAOPS) && MATCH(awk,TOKEN_TILDE))? + QSE_AWK_UNROP_BNOT: -1; /*if (opcode <= -1) return parse_increment (awk);*/ if (opcode <= -1) return parse_exponent (awk, line); @@ -2584,7 +2585,8 @@ static qse_awk_nde_t* parse_unary_exp (qse_awk_t* awk, qse_size_t line) opcode = (MATCH(awk,TOKEN_PLUS))? QSE_AWK_UNROP_PLUS: (MATCH(awk,TOKEN_MINUS))? QSE_AWK_UNROP_MINUS: (MATCH(awk,TOKEN_LNOT))? QSE_AWK_UNROP_LNOT: - (MATCH(awk,TOKEN_TILDE))? QSE_AWK_UNROP_BNOT: -1; + ((awk->option & QSE_AWK_EXTRAOPS) && MATCH(awk,TOKEN_TILDE))? + QSE_AWK_UNROP_BNOT: -1; if (opcode <= -1) return parse_increment (awk, line); @@ -4429,7 +4431,7 @@ static qse_awk_nde_t* parse_print (qse_awk_t* awk, qse_size_t line, int type) if (!MATCH_TERMINATOR(awk) && !MATCH(awk,TOKEN_GT) && - !MATCH(awk,TOKEN_RSHIFT) && + !MATCH(awk,TOKEN_RS) && !MATCH(awk,TOKEN_BOR) && !MATCH(awk,TOKEN_LOR)) { @@ -4490,7 +4492,7 @@ static qse_awk_nde_t* parse_print (qse_awk_t* awk, qse_size_t line, int type) 0 }, { - QSE_AWK_BINOP_RSHIFT, + QSE_AWK_BINOP_RS, QSE_AWK_OUT_APFILE, 0 }, @@ -4534,7 +4536,7 @@ static qse_awk_nde_t* parse_print (qse_awk_t* awk, qse_size_t line, int type) if (out == QSE_NULL) { out_type = MATCH(awk,TOKEN_GT)? QSE_AWK_OUT_FILE: - MATCH(awk,TOKEN_RSHIFT)? QSE_AWK_OUT_APFILE: + MATCH(awk,TOKEN_RS)? QSE_AWK_OUT_APFILE: MATCH(awk,TOKEN_BOR)? QSE_AWK_OUT_PIPE: ((awk->option & QSE_AWK_RWPIPE) && MATCH(awk,TOKEN_LOR))? QSE_AWK_OUT_RWPIPE: @@ -4674,6 +4676,61 @@ static int get_token_into (qse_awk_t* awk, qse_awk_token_t* token) SET_TOKEN_TYPE (awk, token, TOKEN_STR); if (get_charstr(awk, token) <= -1) return -1; } + +/* +// TODO: compacct the code with this table +{ QSE_T("=="), TOKEN_EQ, 0 }, +{ QSE_T("="), TOKEN_ASSIGN, 0 }, +{ QSE_T("!=") TOKEN_NE, 0 }, +{ QSE_T("!~") TOKEN_NM, 0 }, +{ QSE_T("!") TOKEN_LNOT, 0 }, +{ QSE_T(">>=") TOKEN_RS_ASSIGN, QSE_AWK_EXTRAOPS }, +{ QSE_T(">>") TOKEN_RS, 0 }, +{ QSE_T(">=") TOKEN_GE, 0 }, +{ QSE_T(">") TOKEN_GT, 0 }, +{ QSE_T(">>=") TOKEN_LS_ASSIGN, QSE_AWK_EXTRAOPS }, +{ QSE_T(">>") TOKEN_LS, 0 }, +{ QSE_T(">=") TOKEN_LE, 0 }, +{ QSE_T(">") TOKEN_LT, 0 }, +{ QSE_T("||") TOKEN_LOR, 0 }, +{ QSE_T("|=") TOKEN_BOR_ASSIGN, 0 }, +{ QSE_T("|") TOKEN_BOR, 0 }, +{ QSE_T("&&") TOKEN_LAND, 0 }, +{ QSE_T("&=") TOKEN_BAND_ASSIGN, 0 }, +{ QSE_T("&") TOKEN_BAND, 0 }, +{ QSE_T("^^=") TOKEN_BXOR_ASSIGN, QSE_AWK_EXTRAOPS }, +{ QSE_T("^^") TOKEN_BXOR, QSE_AWK_EXTRAOPS }, +{ QSE_T("^=") TOKEN_EXP_ASSIGN, 0 }, +{ QSE_T("^") TOKEN_EXP, 0 }, +{ QSE_T("++") TOKEN_PLUSPLUS, 0 }, +{ QSE_T("+=") TOKEN_PLUS_ASSIGN, 0 }, +{ QSE_T("+") TOKEN_PLUS, 0 }, +{ QSE_T("--") TOKEN_MINUSMINUS, 0 }, +{ QSE_T("-=") TOKEN_MINUS_ASSIGN, 0 }, +{ QSE_T("-") TOKEN_MINUS, 0 }, +{ QSE_T("**=") TOKEN_EXP_ASSIGN, QSE_AWK_EXTRAOPS }, +{ QSE_T("**") TOKEN_EXP, QSE_AWK_EXTRAOPS }, +{ QSE_T("*=") TOKEN_MUL_ASSIGN, 0 }, +{ QSE_T("*") TOKEN_MUL, 0 }, +{ QSE_T("//=") TOKEN_IDIV_ASSIGN, 0 }, +{ QSE_T("//") TOKEN_IDIV, QSE_AWK_EXTRAOPS }, +{ QSE_T("/=") TOKEN_DIV_ASSIGN, QSE_AWK_EXTRAOPS }, +{ QSE_T("/") TOKEN_DIV, 0 }, +{ QSE_T("%=") TOKEN_MOD_ASSIGN, 0 }, +{ QSE_T("%") TOKEN_MOD, 0 }, +{ QSE_T("~"), TOKEN_TILDE, 0 }, +{ QSE_T("("), TOKEN_LPAREN, 0 }, +{ QSE_T(")"), TOKEN_RPAREN, 0 }, +{ QSE_T("{"), TOKEN_LBRACE, 0 }, +{ QSE_T("}"), TOKEN_RBRACE, 0 }, +{ QSE_T("["), TOKEN_LBRACK, 0 }, +{ QSE_T("]"), TOKEN_RBRACK, 0 }, +{ QSE_T("$"), TOKEN_DOLLAR, 0 }, +{ QSE_T(","), TOKEN_COMMA, 0 }, +{ QSE_T(";"), TOKEN_SEMICOLON, 0 }, +{ QSE_T(":"), TOKEN_COLON, 0 }, +{ QSE_T("?"), TOKEN_QUEST, 0 }, + */ else if (c == QSE_T('=')) { ADD_TOKEN_CHAR (awk, token, c); @@ -4718,15 +4775,15 @@ static int get_token_into (qse_awk_t* awk, qse_awk_token_t* token) { ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); - if ((awk->option & QSE_AWK_SHIFT) && c == QSE_T('=')) + if ((awk->option & QSE_AWK_EXTRAOPS) && c == QSE_T('=')) { - SET_TOKEN_TYPE (awk, token, TOKEN_RSHIFT_ASSIGN); + SET_TOKEN_TYPE (awk, token, TOKEN_RS_ASSIGN); ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else { - SET_TOKEN_TYPE (awk, token, TOKEN_RSHIFT); + SET_TOKEN_TYPE (awk, token, TOKEN_RS); } } else if (c == QSE_T('=')) @@ -4745,19 +4802,19 @@ static int get_token_into (qse_awk_t* awk, qse_awk_token_t* token) ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); - if ((awk->option & QSE_AWK_SHIFT) && c == QSE_T('<')) + if ((awk->option & QSE_AWK_EXTRAOPS) && c == QSE_T('<')) { ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); if (c == QSE_T('=')) { - SET_TOKEN_TYPE (awk, token, TOKEN_LSHIFT_ASSIGN); + SET_TOKEN_TYPE (awk, token, TOKEN_LS_ASSIGN); ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else { - SET_TOKEN_TYPE (awk, token, TOKEN_LSHIFT); + SET_TOKEN_TYPE (awk, token, TOKEN_LS); } } else if (c == QSE_T('=')) @@ -4818,21 +4875,30 @@ static int get_token_into (qse_awk_t* awk, qse_awk_token_t* token) ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); - if (c == QSE_T('=')) + if ((awk->option & QSE_AWK_EXTRAOPS) && c == QSE_T('^')) { - SET_TOKEN_TYPE (awk, token, - ((awk->option & QSE_AWK_BXOR)? - TOKEN_BXOR_ASSIGN: TOKEN_EXP_ASSIGN) - ); + ADD_TOKEN_CHAR (awk, token, c); + GET_CHAR_TO (awk, c); + if (c == QSE_T('=')) + { + SET_TOKEN_TYPE (awk, token, TOKEN_BXOR_ASSIGN); + ADD_TOKEN_CHAR (awk, token, c); + GET_CHAR (awk); + } + else + { + SET_TOKEN_TYPE (awk, token, TOKEN_BXOR); + } + } + else if (c == QSE_T('=')) + { + SET_TOKEN_TYPE (awk, token, TOKEN_EXP_ASSIGN); ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } else { - SET_TOKEN_TYPE (awk, token, - ((awk->option & QSE_AWK_BXOR)? - TOKEN_BXOR: TOKEN_EXP) - ); + SET_TOKEN_TYPE (awk, token, TOKEN_EXP); } } else if (c == QSE_T('+')) @@ -4919,7 +4985,7 @@ static int get_token_into (qse_awk_t* awk, qse_awk_token_t* token) ADD_TOKEN_CHAR (awk, token, c); GET_CHAR (awk); } - else if ((awk->option & QSE_AWK_IDIV) && c == QSE_T('/')) + else if ((awk->option & QSE_AWK_EXTRAOPS) && c == QSE_T('/')) { ADD_TOKEN_CHAR (awk, token, c); GET_CHAR_TO (awk, c); @@ -5596,8 +5662,8 @@ static int assign_to_opcode (qse_awk_t* awk) QSE_AWK_ASSOP_IDIV, QSE_AWK_ASSOP_MOD, QSE_AWK_ASSOP_EXP, - QSE_AWK_ASSOP_RSHIFT, - QSE_AWK_ASSOP_LSHIFT, + QSE_AWK_ASSOP_RS, + QSE_AWK_ASSOP_LS, QSE_AWK_ASSOP_BAND, QSE_AWK_ASSOP_BXOR, QSE_AWK_ASSOP_BOR diff --git a/qse/lib/awk/run.h b/qse/lib/awk/run.h index a9454349..95b9469b 100644 --- a/qse/lib/awk/run.h +++ b/qse/lib/awk/run.h @@ -1,5 +1,5 @@ /* - * $Id: run.h 75 2009-02-22 14:10:34Z hyunghwan.chung $ + * $Id: run.h 238 2009-07-17 12:42:02Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -31,8 +31,8 @@ enum qse_awk_assop_type_t QSE_AWK_ASSOP_IDIV, /* //= */ QSE_AWK_ASSOP_MOD, /* %= */ QSE_AWK_ASSOP_EXP, /* **= */ - QSE_AWK_ASSOP_RSHIFT, /* >>= */ - QSE_AWK_ASSOP_LSHIFT, /* <<= */ + QSE_AWK_ASSOP_RS, /* >>= */ + QSE_AWK_ASSOP_LS, /* <<= */ QSE_AWK_ASSOP_BAND, /* &= */ QSE_AWK_ASSOP_BXOR, /* ^= */ QSE_AWK_ASSOP_BOR /* |= */ @@ -57,8 +57,8 @@ enum qse_awk_binop_type_t QSE_AWK_BINOP_LT, QSE_AWK_BINOP_LE, - QSE_AWK_BINOP_LSHIFT, - QSE_AWK_BINOP_RSHIFT, + QSE_AWK_BINOP_LS, + QSE_AWK_BINOP_RS, QSE_AWK_BINOP_PLUS, QSE_AWK_BINOP_MINUS,