diff --git a/ase/awk/parse.c b/ase/awk/parse.c index eccdf434..dcc84707 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.129 2006-06-29 15:40:30 bacon Exp $ + * $Id: parse.c,v 1.130 2006-06-30 03:53:16 bacon Exp $ */ #include @@ -68,6 +68,10 @@ enum TOKEN_BEGIN, TOKEN_END, TOKEN_FUNCTION, + + TOKEN_LOCAL, + TOKEN_GLOBAL, + TOKEN_IF, TOKEN_ELSE, TOKEN_WHILE, @@ -78,15 +82,12 @@ enum TOKEN_RETURN, TOKEN_EXIT, TOKEN_DELETE, - TOKEN_GETLINE, TOKEN_NEXT, TOKEN_NEXTFILE, TOKEN_PRINT, TOKEN_PRINTF, - TOKEN_LOCAL, - TOKEN_GLOBAL, - + TOKEN_GETLINE, TOKEN_IDENT, TOKEN_INT, TOKEN_REAL, @@ -184,11 +185,20 @@ struct __kwent static struct __kwent __kwtab[] = { + /* operators */ + { XP_T("in"), TOKEN_IN, 0 }, + + /* top-level block starters */ { XP_T("BEGIN"), TOKEN_BEGIN, 0 }, { XP_T("END"), TOKEN_END, 0 }, - { XP_T("function"), TOKEN_FUNCTION, 0 }, { XP_T("func"), TOKEN_FUNCTION, 0 }, + + /* keywords for variable declaration */ + { XP_T("local"), TOKEN_LOCAL, XP_AWK_EXPLICIT }, + { XP_T("global"), TOKEN_GLOBAL, XP_AWK_EXPLICIT }, + + /* keywords that start statements excluding expression statements */ { XP_T("if"), TOKEN_IF, 0 }, { XP_T("else"), TOKEN_ELSE, 0 }, { XP_T("while"), TOKEN_WHILE, 0 }, @@ -199,16 +209,13 @@ static struct __kwent __kwtab[] = { XP_T("return"), TOKEN_RETURN, 0 }, { XP_T("exit"), TOKEN_EXIT, 0 }, { XP_T("delete"), TOKEN_DELETE, 0 }, - { XP_T("getline"), TOKEN_GETLINE, XP_AWK_EXTIO }, { XP_T("next"), TOKEN_NEXT, 0 }, { XP_T("nextfile"), TOKEN_NEXTFILE, 0 }, { XP_T("print"), TOKEN_PRINT, XP_AWK_EXTIO }, { XP_T("printf"), TOKEN_PRINTF, XP_AWK_EXTIO }, - { XP_T("local"), TOKEN_LOCAL, XP_AWK_EXPLICIT }, - { XP_T("global"), TOKEN_GLOBAL, XP_AWK_EXPLICIT }, - - { XP_T("in"), TOKEN_IN, 0 }, + /* keywords that can start an expression */ + { XP_T("getline"), TOKEN_GETLINE, XP_AWK_EXTIO }, { XP_NULL, 0, 0 } }; @@ -1629,7 +1636,7 @@ static xp_awk_nde_t* __parse_concat (xp_awk_t* awk) /* TODO: write a better code to do this.... * first of all, is the following check sufficient??? */ - while (awk->token.type > TOKEN_QUEST) + while (MATCH(awk,TOKEN_LPAREN) || awk->token.type >= TOKEN_GETLINE) { right = __parse_additive (awk); if (right == XP_NULL) diff --git a/ase/awk/run.c b/ase/awk/run.c index 61093f95..8de281f9 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.115 2006-06-29 15:40:30 bacon Exp $ + * $Id: run.c,v 1.116 2006-06-30 03:53:16 bacon Exp $ */ #include @@ -13,6 +13,8 @@ #include #endif +#define DEF_BUF_CAPA 256 + #define STACK_INCREMENT 512 #define STACK_AT(run,n) ((run)->stack[(run)->stack_base+(n)]) @@ -250,14 +252,14 @@ static int __open_run ( run->input.buf_pos = 0; run->input.buf_len = 0; - if (xp_str_open (&run->input.line, 256) == XP_NULL) + if (xp_str_open (&run->input.line, DEF_BUF_CAPA) == XP_NULL) { run->errnum = XP_AWK_ENOMEM; return -1; } if (xp_awk_map_open (&run->named, - run, 256, __free_namedval) == XP_NULL) + run, DEF_BUF_CAPA, __free_namedval) == XP_NULL) { xp_str_close (&run->input.line); run->errnum = XP_AWK_ENOMEM; @@ -2342,9 +2344,49 @@ static xp_awk_val_t* __eval_binop_exp ( static xp_awk_val_t* __eval_binop_concat ( xp_awk_run_t* run, xp_awk_val_t* left, xp_awk_val_t* right) { -xp_printf (XP_T("eval_binop_concat not implemented yet...\n")); - PANIC (run, XP_AWK_EINTERNAL); - return XP_NULL; + xp_str_t lv, rv; + xp_awk_val_t* res; + int errnum; + + if (xp_str_open (&lv, DEF_BUF_CAPA) == XP_NULL) + { + PANIC (run, XP_AWK_ENOMEM); + } + + if (xp_str_open (&rv, DEF_BUF_CAPA) == XP_NULL) + { + xp_str_close (&lv); + PANIC (run, XP_AWK_ENOMEM); + } + + if (xp_awk_valtostr (left, &errnum, &lv) == XP_NULL) + { + xp_str_close (&lv); + xp_str_close (&rv); + PANIC (run, errnum); + } + + if (xp_awk_valtostr (right, &errnum, &rv) == XP_NULL) + { + xp_str_close (&lv); + xp_str_close (&rv); + PANIC (run, errnum); + } + + res = xp_awk_makestrval2 ( + XP_STR_BUF(&lv), XP_STR_LEN(&lv), + XP_STR_BUF(&rv), XP_STR_LEN(&rv)); + if (res == XP_NULL) + { + xp_str_close (&lv); + xp_str_close (&rv); + PANIC (run, XP_AWK_ENOMEM); + } + + xp_str_close (&lv); + xp_str_close (&rv); + + return res; } static xp_awk_val_t* __eval_binop_ma ( @@ -3108,7 +3150,7 @@ static xp_awk_val_t* __eval_getline (xp_awk_run_t* run, xp_awk_nde_t* nde) dst = (in == XP_NULL)? XP_T(""): in; /* TODO: optimization in line buffer management */ - if (xp_str_open (&buf, 256) == XP_NULL) + if (xp_str_open (&buf, DEF_BUF_CAPA) == XP_NULL) { if (in != XP_NULL) xp_free (in); PANIC (run, XP_AWK_ENOMEM); @@ -3306,7 +3348,7 @@ static xp_char_t* __idxnde_to_str (xp_awk_run_t* run, xp_awk_nde_t* nde) /* multidimensional index */ xp_str_t idxstr; - if (xp_str_open (&idxstr, 256) == XP_NULL) + if (xp_str_open (&idxstr, DEF_BUF_CAPA) == XP_NULL) { PANIC (run, XP_AWK_ENOMEM); } diff --git a/ase/test/awk/t12.awk b/ase/test/awk/t12.awk index 8811ee27..e3ff76f5 100644 --- a/ase/test/awk/t12.awk +++ b/ase/test/awk/t12.awk @@ -29,5 +29,6 @@ BEGIN getline x < "abc"; print x > "abc"; + print 1 2 getline j j; print "abc" 1 + 2 3 + 49 2 / 3; }