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:
parent
66da8f46c7
commit
c6a0a99e84
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user