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_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
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
fnc.name.ptr = full->ptr;
|
nde = parse_fncall (awk, full, &fnc, xloc, 0);
|
||||||
fnc.name.len = full->len;
|
}
|
||||||
fnc.arg.min = sym.u.fnc.arg.min;
|
else
|
||||||
fnc.arg.max = sym.u.fnc.arg.max;
|
{
|
||||||
fnc.handler = sym.u.fnc.impl;
|
SETERR_TOK (awk, QSE_AWK_ELPAREN);
|
||||||
fnc.mod = mod;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
nde = parse_fncall (awk, full, &fnc, xloc, 0);
|
case QSE_AWK_MOD_INT:
|
||||||
}
|
nde = new_int_node (awk, sym.u.in.val, xloc);
|
||||||
else
|
/* i don't remember the symbol in the original form */
|
||||||
{
|
break;
|
||||||
SETERR_TOK (awk, QSE_AWK_ELPAREN);
|
|
||||||
}
|
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;
|
||||||
/* TODO: support MOD_VAR */
|
|
||||||
SETERR_ARG_LOC (awk, QSE_AWK_EUNDEF, full->ptr, full->len, xloc);
|
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)
|
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user