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_vardecl "VARIABLE DECLARATION"
- @ref awk_ext_include "INCLUDE"
- @ref awk_ext_funcall "FUNCTION CALL"
- @ref awk_ext_print "EXTENDED PRINT/PRINTF"
- @ref awk_ext_exprgroup "GROUPED EXPRESSION"
- @ref awk_ext_rwpipe "TWO-WAY PIPE"
@ -21,6 +22,7 @@
- @ref awk_ext_ioenc "I/O ENCODING"
@section awk_intro INTRODUCTION
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.
@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
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

View File

@ -754,12 +754,18 @@ struct qse_awk_mod_t
enum qse_awk_mod_sym_type_t
{
QSE_AWK_MOD_FNC = 0 /*,
QSE_AWK_MOD_VAR */
QSE_AWK_MOD_FNC = 0,
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 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
@ -770,12 +776,24 @@ struct qse_awk_mod_sym_fnc_t
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
{
qse_awk_mod_sym_type_t type;
union
{
qse_awk_mod_sym_fnc_t fnc;
qse_awk_mod_sym_int_t in;
qse_awk_mod_sym_flt_t flt;
} 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;
}
/* 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;
tloc = awk->tok.loc;
@ -5000,30 +5004,41 @@ static qse_awk_nde_t* parse_primary_ident_segs (
}
else
{
if (sym.type == QSE_AWK_MOD_FNC)
switch (sym.type)
{
if (MATCH(awk,TOK_LPAREN))
{
QSE_MEMSET (&fnc, 0, QSE_SIZEOF(fnc));
case QSE_AWK_MOD_FNC:
if (MATCH(awk,TOK_LPAREN))
{
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;
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;
case QSE_AWK_MOD_INT:
nde = new_int_node (awk, sym.u.in.val, xloc);
/* i don't remember the symbol in the original form */
break;
nde = parse_fncall (awk, full, &fnc, xloc, 0);
}
else
{
SETERR_TOK (awk, QSE_AWK_ELPAREN);
}
}
else
{
/* TODO: support MOD_VAR */
SETERR_ARG_LOC (awk, QSE_AWK_EUNDEF, full->ptr, full->len, xloc);
case QSE_AWK_MOD_FLT:
nde = new_flt_node (awk, sym.u.flt.val, xloc);
/* i don't remember the symbol in the original form */
break;
default:
/* TODO: support MOD_VAR */
SETERR_ARG_LOC (awk, QSE_AWK_EUNDEF, full->ptr, full->len, xloc);
break;
}
}

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)
{
qse_size_t nargs;
qse_long_t lv;
qse_awk_val_t* retv;
int n;
nargs = qse_awk_rtx_getnargs (rtx);
QSE_ASSERT (nargs == 1);
/* TODO: handle more parameters */
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)
{
qse_size_t nargs;
qse_long_t lv;
qse_awk_val_t* retv;
int n;
@ -118,11 +113,23 @@ struct fnctab_t
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[] =
{
{ QSE_T("fork"), { { 0, 0 }, fnc_fork } },
{ QSE_T("sleep"), { { 1, 1 }, fnc_sleep } },
{ QSE_T("wait"), { { 1, 1 }, fnc_wait } }
{ QSE_T("fork"), { { 0, 0 }, fnc_fork } },
{ QSE_T("sleep"), { { 1, 1 }, fnc_sleep } },
{ 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)
@ -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;
int i;
/* TODO: binary search */
/* TODO: binary search or something better */
for (i = 0; i < QSE_COUNTOF(fnctab); i++)
{
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
}
}
/*
if (qse_strcmp (name, QSE_T("WNOHANG")) == 0)
for (i = 0; i < QSE_COUNTOF(inttab); i++)
{
sym->type = QSE_AWK_MOD_INTCON;
sym->u.c.ivalue = WNOHANG;
return 0;
if (qse_strcmp (inttab[i].name, name) == 0)
{
sym->type = QSE_AWK_MOD_INT;
sym->u.in = inttab[i].info;
return 0;
}
}
*/
ea.ptr = name;
ea.len = qse_strlen(name);