added QSE_AWK_MOD_INT and QSE_AWK_MOD_FLT

added qse_awk_mod_sym_int_t and qse_awk_mod_sym_flt_t
This commit is contained in:
hyung-hwan 2012-10-26 15:44:23 +00:00
parent 66da8f46c7
commit c6a0a99e84
4 changed files with 109 additions and 39 deletions

View File

@ -7,6 +7,7 @@
- @ref awk_ext_teq "TEQ OPERATOR" - @ref awk_ext_teq "TEQ OPERATOR"
- @ref awk_ext_vardecl "VARIABLE DECLARATION" - @ref awk_ext_vardecl "VARIABLE DECLARATION"
- @ref awk_ext_include "INCLUDE" - @ref awk_ext_include "INCLUDE"
- @ref awk_ext_funcall "FUNCTION CALL"
- @ref awk_ext_print "EXTENDED PRINT/PRINTF" - @ref awk_ext_print "EXTENDED PRINT/PRINTF"
- @ref awk_ext_exprgroup "GROUPED EXPRESSION" - @ref awk_ext_exprgroup "GROUPED EXPRESSION"
- @ref awk_ext_rwpipe "TWO-WAY PIPE" - @ref awk_ext_rwpipe "TWO-WAY PIPE"
@ -21,6 +22,7 @@
- @ref awk_ext_ioenc "I/O ENCODING" - @ref awk_ext_ioenc "I/O ENCODING"
@section awk_intro INTRODUCTION @section awk_intro INTRODUCTION
QSEAWK is an AWK interpreter and is a part of the @ref qse_intro "QSE" library. QSEAWK is an AWK interpreter and is a part of the @ref qse_intro "QSE" library.
@ -379,6 +381,33 @@ BEGIN { func_in_abc(); }
If #QSE_AWK_NEWLINE is off, the semicolon is required. If #QSE_AWK_NEWLINE is off, the semicolon is required.
@subsection awk_ext_funcall FUNCTIONC CALL
name(1);
if there is no space between 'name' and the left parenthesis, the
name is treated as a function name.
name (1);
If there is a space, the name is treated as a function name if the
name has been declared as the function or if #QSE_AWK_IMPLICIT is on,
it may be 'name' concatenated with the expression in the parentheses.
The following is a valid program.
@code
@pragma implicit off
BEGIN { name (1); }
function name(a) { print a; }'
@endcode
However, in this program, the first 'name' becomes a named global variable.
so the function declaration with 'name' triggers the variable redefinition
error.
@pragma implicit on
BEGIN { name (1); }
function name(a) { print a; }'
@endcode
@subsection awk_ext_print EXTENDED PRINT/PRINTF @subsection awk_ext_print EXTENDED PRINT/PRINTF
When #QSE_AWK_TOLERANT is on, print and printf are treated as if When #QSE_AWK_TOLERANT is on, print and printf are treated as if
they are function calls. In this mode, they return a negative number they are function calls. In this mode, they return a negative number

View File

@ -754,12 +754,18 @@ struct qse_awk_mod_t
enum qse_awk_mod_sym_type_t enum qse_awk_mod_sym_type_t
{ {
QSE_AWK_MOD_FNC = 0 /*, QSE_AWK_MOD_FNC = 0,
QSE_AWK_MOD_VAR */ QSE_AWK_MOD_INT, /* constant */
QSE_AWK_MOD_FLT /* constant */
/*QSE_AWK_MOD_STR,
QSE_AWK_MOD_VAR,
*/
}; };
typedef enum qse_awk_mod_sym_type_t qse_awk_mod_sym_type_t; typedef enum qse_awk_mod_sym_type_t qse_awk_mod_sym_type_t;
typedef struct qse_awk_mod_sym_fnc_t qse_awk_mod_sym_fnc_t; typedef struct qse_awk_mod_sym_fnc_t qse_awk_mod_sym_fnc_t;
typedef struct qse_awk_mod_sym_int_t qse_awk_mod_sym_int_t;
typedef struct qse_awk_mod_sym_flt_t qse_awk_mod_sym_flt_t;
struct qse_awk_mod_sym_fnc_t struct qse_awk_mod_sym_fnc_t
{ {
struct struct
@ -770,12 +776,24 @@ struct qse_awk_mod_sym_fnc_t
qse_awk_fnc_impl_t impl; qse_awk_fnc_impl_t impl;
}; };
struct qse_awk_mod_sym_int_t
{
qse_long_t val;
};
struct qse_awk_mod_sym_flt_t
{
qse_flt_t val;
};
struct qse_awk_mod_sym_t struct qse_awk_mod_sym_t
{ {
qse_awk_mod_sym_type_t type; qse_awk_mod_sym_type_t type;
union union
{ {
qse_awk_mod_sym_fnc_t fnc; qse_awk_mod_sym_fnc_t fnc;
qse_awk_mod_sym_int_t in;
qse_awk_mod_sym_flt_t flt;
} u; } u;
}; };

View File

@ -2079,6 +2079,10 @@ static qse_awk_nde_t* parse_if (qse_awk_t* awk, const qse_awk_loc_t* xloc)
goto oops; goto oops;
} }
/* TODO: optimization. if you know 'tese' evaluates to true or false,
* you can drop the 'if' statement and take either the 'then_part'
* or 'else_part'. */
if (get_token(awk) <= -1) goto oops; if (get_token(awk) <= -1) goto oops;
tloc = awk->tok.loc; tloc = awk->tok.loc;
@ -5000,30 +5004,41 @@ static qse_awk_nde_t* parse_primary_ident_segs (
} }
else else
{ {
if (sym.type == QSE_AWK_MOD_FNC) switch (sym.type)
{ {
if (MATCH(awk,TOK_LPAREN)) case QSE_AWK_MOD_FNC:
{ if (MATCH(awk,TOK_LPAREN))
QSE_MEMSET (&fnc, 0, QSE_SIZEOF(fnc)); {
QSE_MEMSET (&fnc, 0, QSE_SIZEOF(fnc));
fnc.name.ptr = full->ptr;
fnc.name.len = full->len;
fnc.arg.min = sym.u.fnc.arg.min;
fnc.arg.max = sym.u.fnc.arg.max;
fnc.handler = sym.u.fnc.impl;
fnc.mod = mod;
nde = parse_fncall (awk, full, &fnc, xloc, 0);
}
else
{
SETERR_TOK (awk, QSE_AWK_ELPAREN);
}
break;
fnc.name.ptr = full->ptr; case QSE_AWK_MOD_INT:
fnc.name.len = full->len; nde = new_int_node (awk, sym.u.in.val, xloc);
fnc.arg.min = sym.u.fnc.arg.min; /* i don't remember the symbol in the original form */
fnc.arg.max = sym.u.fnc.arg.max; break;
fnc.handler = sym.u.fnc.impl;
fnc.mod = mod;
nde = parse_fncall (awk, full, &fnc, xloc, 0); case QSE_AWK_MOD_FLT:
} nde = new_flt_node (awk, sym.u.flt.val, xloc);
else /* i don't remember the symbol in the original form */
{ break;
SETERR_TOK (awk, QSE_AWK_ELPAREN);
} default:
} /* TODO: support MOD_VAR */
else SETERR_ARG_LOC (awk, QSE_AWK_EUNDEF, full->ptr, full->len, xloc);
{ break;
/* TODO: support MOD_VAR */
SETERR_ARG_LOC (awk, QSE_AWK_EUNDEF, full->ptr, full->len, xloc);
} }
} }

View File

@ -45,14 +45,10 @@ static int fnc_fork (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
static int fnc_wait (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) static int fnc_wait (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{ {
qse_size_t nargs;
qse_long_t lv; qse_long_t lv;
qse_awk_val_t* retv; qse_awk_val_t* retv;
int n; int n;
nargs = qse_awk_rtx_getnargs (rtx);
QSE_ASSERT (nargs == 1);
/* TODO: handle more parameters */ /* TODO: handle more parameters */
n = qse_awk_rtx_valtolong (rtx, qse_awk_rtx_getarg (rtx, 0), &lv); n = qse_awk_rtx_valtolong (rtx, qse_awk_rtx_getarg (rtx, 0), &lv);
@ -83,7 +79,6 @@ static int fnc_wait (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
static int fnc_sleep (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) static int fnc_sleep (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{ {
qse_size_t nargs;
qse_long_t lv; qse_long_t lv;
qse_awk_val_t* retv; qse_awk_val_t* retv;
int n; int n;
@ -118,11 +113,23 @@ struct fnctab_t
qse_awk_mod_sym_fnc_t info; qse_awk_mod_sym_fnc_t info;
}; };
typedef struct inttab_t inttab_t;
struct inttab_t
{
const qse_char_t* name;
qse_awk_mod_sym_int_t info;
};
static fnctab_t fnctab[] = static fnctab_t fnctab[] =
{ {
{ QSE_T("fork"), { { 0, 0 }, fnc_fork } }, { QSE_T("fork"), { { 0, 0 }, fnc_fork } },
{ QSE_T("sleep"), { { 1, 1 }, fnc_sleep } }, { QSE_T("sleep"), { { 1, 1 }, fnc_sleep } },
{ QSE_T("wait"), { { 1, 1 }, fnc_wait } } { QSE_T("wait"), { { 1, 1 }, fnc_wait } }
};
static inttab_t inttab[] =
{
{ QSE_T("WNOHANG"), { WNOHANG } }
}; };
static int query (qse_awk_mod_t* mod, qse_awk_t* awk, const qse_char_t* name, qse_awk_mod_sym_t* sym) static int query (qse_awk_mod_t* mod, qse_awk_t* awk, const qse_char_t* name, qse_awk_mod_sym_t* sym)
@ -130,7 +137,7 @@ static int query (qse_awk_mod_t* mod, qse_awk_t* awk, const qse_char_t* name, qs
qse_cstr_t ea; qse_cstr_t ea;
int i; int i;
/* TODO: binary search */ /* TODO: binary search or something better */
for (i = 0; i < QSE_COUNTOF(fnctab); i++) for (i = 0; i < QSE_COUNTOF(fnctab); i++)
{ {
if (qse_strcmp (fnctab[i].name, name) == 0) if (qse_strcmp (fnctab[i].name, name) == 0)
@ -141,14 +148,15 @@ static int query (qse_awk_mod_t* mod, qse_awk_t* awk, const qse_char_t* name, qs
} }
} }
/* for (i = 0; i < QSE_COUNTOF(inttab); i++)
if (qse_strcmp (name, QSE_T("WNOHANG")) == 0)
{ {
sym->type = QSE_AWK_MOD_INTCON; if (qse_strcmp (inttab[i].name, name) == 0)
sym->u.c.ivalue = WNOHANG; {
return 0; sym->type = QSE_AWK_MOD_INT;
sym->u.in = inttab[i].info;
return 0;
}
} }
*/
ea.ptr = name; ea.ptr = name;
ea.len = qse_strlen(name); ea.len = qse_strlen(name);