Compare commits
2 Commits
d82d51a0ee
...
7b9cab4b47
| Author | SHA1 | Date | |
|---|---|---|---|
| 7b9cab4b47 | |||
| 62f1c3695f |
@@ -617,7 +617,7 @@ PACKAGE_TARNAME='hawk'
|
|||||||
PACKAGE_VERSION='1.0.0'
|
PACKAGE_VERSION='1.0.0'
|
||||||
PACKAGE_STRING='hawk 1.0.0'
|
PACKAGE_STRING='hawk 1.0.0'
|
||||||
PACKAGE_BUGREPORT='Chung, Hyung-Hwan (hyunghwan.chung@gmail.com)'
|
PACKAGE_BUGREPORT='Chung, Hyung-Hwan (hyunghwan.chung@gmail.com)'
|
||||||
PACKAGE_URL='https://code.miflux.net/hyung-hwan/hawk'
|
PACKAGE_URL='https://code.miflux.com/hyung-hwan/hawk'
|
||||||
|
|
||||||
# Factoring default headers for most tests.
|
# Factoring default headers for most tests.
|
||||||
ac_includes_default="\
|
ac_includes_default="\
|
||||||
@@ -1617,7 +1617,7 @@ Use these variables to override the choices made by 'configure' or to help
|
|||||||
it to find libraries and programs with nonstandard names/locations.
|
it to find libraries and programs with nonstandard names/locations.
|
||||||
|
|
||||||
Report bugs to <Chung, Hyung-Hwan (hyunghwan.chung@gmail.com)>.
|
Report bugs to <Chung, Hyung-Hwan (hyunghwan.chung@gmail.com)>.
|
||||||
hawk home page: <https://code.miflux.net/hyung-hwan/hawk>.
|
hawk home page: <https://code.miflux.com/hyung-hwan/hawk>.
|
||||||
_ACEOF
|
_ACEOF
|
||||||
ac_status=$?
|
ac_status=$?
|
||||||
fi
|
fi
|
||||||
@@ -30097,7 +30097,7 @@ Configuration commands:
|
|||||||
$config_commands
|
$config_commands
|
||||||
|
|
||||||
Report bugs to <Chung, Hyung-Hwan (hyunghwan.chung@gmail.com)>.
|
Report bugs to <Chung, Hyung-Hwan (hyunghwan.chung@gmail.com)>.
|
||||||
hawk home page: <https://code.miflux.net/hyung-hwan/hawk>."
|
hawk home page: <https://code.miflux.com/hyung-hwan/hawk>."
|
||||||
|
|
||||||
_ACEOF
|
_ACEOF
|
||||||
ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"`
|
ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"`
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
dnl AC_PREREQ([2.71])
|
dnl AC_PREREQ([2.71])
|
||||||
|
|
||||||
AC_INIT([hawk],[1.0.0],[Chung, Hyung-Hwan (hyunghwan.chung@gmail.com)],[],[https://code.miflux.net/hyung-hwan/hawk])
|
AC_INIT([hawk],[1.0.0],[Chung, Hyung-Hwan (hyunghwan.chung@gmail.com)],[],[https://code.miflux.com/hyung-hwan/hawk])
|
||||||
|
|
||||||
AC_CONFIG_HEADERS([lib/hawk-cfg.h])
|
AC_CONFIG_HEADERS([lib/hawk-cfg.h])
|
||||||
AC_CONFIG_AUX_DIR([ac])
|
AC_CONFIG_AUX_DIR([ac])
|
||||||
|
|||||||
+1
-1
@@ -466,7 +466,7 @@ enum hawk_nde_type_t
|
|||||||
HAWK_NDE_CND,
|
HAWK_NDE_CND,
|
||||||
HAWK_NDE_FNCALL_FNC,
|
HAWK_NDE_FNCALL_FNC,
|
||||||
HAWK_NDE_FNCALL_FUN,
|
HAWK_NDE_FNCALL_FUN,
|
||||||
HAWK_NDE_FNCALL_VAR,
|
HAWK_NDE_FNCALL_EXPR,
|
||||||
HAWK_NDE_CHAR,
|
HAWK_NDE_CHAR,
|
||||||
HAWK_NDE_BCHR,
|
HAWK_NDE_BCHR,
|
||||||
HAWK_NDE_INT,
|
HAWK_NDE_INT,
|
||||||
|
|||||||
+92
-37
@@ -258,7 +258,7 @@ static hawk_nde_t* parse_hashidx (hawk_t* hawk, const hawk_oocs_t* name, const h
|
|||||||
static hawk_nde_t* parse_dotidx (hawk_t* hawk, const hawk_oocs_t* name, const hawk_loc_t* xloc);
|
static hawk_nde_t* parse_dotidx (hawk_t* hawk, const hawk_oocs_t* name, const hawk_loc_t* xloc);
|
||||||
|
|
||||||
#define FNCALL_FLAG_NOARG (1 << 0) /* no argument */
|
#define FNCALL_FLAG_NOARG (1 << 0) /* no argument */
|
||||||
#define FNCALL_FLAG_VAR (1 << 1)
|
#define FNCALL_FLAG_EXPR (1 << 1)
|
||||||
#define FNCALL_FLAG_MAP (1 << 2)
|
#define FNCALL_FLAG_MAP (1 << 2)
|
||||||
static hawk_nde_t* parse_fncall (hawk_t* hawk, const hawk_oocs_t* name, hawk_fnc_t* fnc, const hawk_loc_t* xloc, int flags, int closer_token);
|
static hawk_nde_t* parse_fncall (hawk_t* hawk, const hawk_oocs_t* name, hawk_fnc_t* fnc, const hawk_loc_t* xloc, int flags, int closer_token);
|
||||||
|
|
||||||
@@ -290,7 +290,11 @@ struct kwent_t
|
|||||||
static kwent_t kwtab[] =
|
static kwent_t kwtab[] =
|
||||||
{
|
{
|
||||||
/* keep this table in sync with the kw_t enums in "parse-prv.h".
|
/* keep this table in sync with the kw_t enums in "parse-prv.h".
|
||||||
* also keep it sorted by the first field for binary search */
|
* also keep it sorted by the first field for binary search.
|
||||||
|
* there are extra keywords that are alias to the main entries
|
||||||
|
* in classify_ident. e.g. "func". such aliases are not placed
|
||||||
|
* here because of direct access by index in hawk_getkwname() */
|
||||||
|
|
||||||
{ { HAWK_T("@abort"), 6 }, TOK_XABORT, 0 },
|
{ { HAWK_T("@abort"), 6 }, TOK_XABORT, 0 },
|
||||||
{ { HAWK_T("@argc"), 5 }, TOK_XARGC, 0 },
|
{ { HAWK_T("@argc"), 5 }, TOK_XARGC, 0 },
|
||||||
{ { HAWK_T("@argv"), 5 }, TOK_XARGV, 0 },
|
{ { HAWK_T("@argv"), 5 }, TOK_XARGV, 0 },
|
||||||
@@ -315,7 +319,6 @@ static kwent_t kwtab[] =
|
|||||||
{ { HAWK_T("else"), 4 }, TOK_ELSE, 0 },
|
{ { HAWK_T("else"), 4 }, TOK_ELSE, 0 },
|
||||||
{ { HAWK_T("exit"), 4 }, TOK_EXIT, 0 },
|
{ { HAWK_T("exit"), 4 }, TOK_EXIT, 0 },
|
||||||
{ { HAWK_T("for"), 3 }, TOK_FOR, 0 },
|
{ { HAWK_T("for"), 3 }, TOK_FOR, 0 },
|
||||||
{ { HAWK_T("func"), 4 }, TOK_FUNCTION, 0 },
|
|
||||||
{ { HAWK_T("function"), 8 }, TOK_FUNCTION, 0 },
|
{ { HAWK_T("function"), 8 }, TOK_FUNCTION, 0 },
|
||||||
{ { HAWK_T("getbline"), 8 }, TOK_GETBLINE, HAWK_RIO },
|
{ { HAWK_T("getbline"), 8 }, TOK_GETBLINE, HAWK_RIO },
|
||||||
{ { HAWK_T("getline"), 7 }, TOK_GETLINE, HAWK_RIO },
|
{ { HAWK_T("getline"), 7 }, TOK_GETLINE, HAWK_RIO },
|
||||||
@@ -1102,16 +1105,18 @@ static int parse_progunit (hawk_t* hawk)
|
|||||||
((trait = HAWK_PEDANTIC) && hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("pedantic"), 0) == 0) ||
|
((trait = HAWK_PEDANTIC) && hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("pedantic"), 0) == 0) ||
|
||||||
((trait = HAWK_RWPIPE) && hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("rwpipe"), 0) == 0))
|
((trait = HAWK_RWPIPE) && hawk_comp_oochars_oocstr(name.ptr, name.len, HAWK_T("rwpipe"), 0) == 0))
|
||||||
{
|
{
|
||||||
/* @pragma implicit on
|
/* @pragma implicit on (default)
|
||||||
* @pragma implicit off
|
* @pragma implicit off
|
||||||
* @pragma multilinestr on
|
* @pragma multilinestr on
|
||||||
* @pragma multilinestr off
|
* @pragma multilinestr off (defualt)
|
||||||
* @pragma pedantic on
|
* @pragma pedantic on
|
||||||
* @pragma pedantic off
|
* @pragma pedantic off (default)
|
||||||
* @pragma rwpipe on
|
* @pragma rwpipe on (default)
|
||||||
* @pragma rwpipe off
|
* @pragma rwpipe off
|
||||||
*
|
*
|
||||||
* The initial values of these pragmas are set in hawk_clear()
|
* The initial values of these pragmas are set in hawk_clear()
|
||||||
|
* The pragma items defined in this block is compile-time only unlike
|
||||||
|
* the items defined in the next block.
|
||||||
*/
|
*/
|
||||||
hawk_oocs_t value;
|
hawk_oocs_t value;
|
||||||
|
|
||||||
@@ -1155,8 +1160,15 @@ static int parse_progunit (hawk_t* hawk)
|
|||||||
*
|
*
|
||||||
* The initial values of these pragmas are set in hawk_clear()
|
* The initial values of these pragmas are set in hawk_clear()
|
||||||
*
|
*
|
||||||
* Take note the global STRIPRECSPC is available for context based change.
|
* The effect of the pragma items listed here are modified at runtime
|
||||||
* STRIPRECSPC takes precedence over this pragma.
|
* with corresponding globals values. The interpreter uses these
|
||||||
|
* macros to detemine the actual effect as defined in hawk-prv.h.
|
||||||
|
* - HAWK_RTX_IS_NUMSTRDETECT_ON(rtx)
|
||||||
|
* - HAWK_RTX_IS_PIPECLOEXEC_ON(rtx)
|
||||||
|
* - HAWK_RTX_IS_STRIPRECSPC_ON(rtx)
|
||||||
|
* - HAWK_RTX_IS_STRIPSTRSPC_ON(rtx)
|
||||||
|
* In general, the runtime global variable value takes precedence
|
||||||
|
* over the compile-time pragma specifier value.
|
||||||
*/
|
*/
|
||||||
int is_on;
|
int is_on;
|
||||||
hawk_oocs_t value;
|
hawk_oocs_t value;
|
||||||
@@ -4010,7 +4022,9 @@ static hawk_nde_t* parse_statement_nb (hawk_t* hawk, const hawk_loc_t* xloc)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (nde) hawk_clrpt(hawk, nde);
|
if (nde) hawk_clrpt(hawk, nde);
|
||||||
hawk_seterrnum(hawk, &hawk->ptok.loc, HAWK_ESTMEND);
|
hawk_seterrbfmt(hawk, &hawk->tok.loc, HAWK_ESTMEND,
|
||||||
|
"statement not ending with a semicolon and got '%.*js'",
|
||||||
|
HAWK_OOECS_LEN(hawk->tok.name), HAWK_OOECS_PTR(hawk->tok.name));
|
||||||
return HAWK_NULL;
|
return HAWK_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5562,8 +5576,8 @@ oops:
|
|||||||
|
|
||||||
static hawk_nde_t* _parse_primary_array_or_map (hawk_t* hawk, const hawk_loc_t* xloc, const hawk_oocs_t* full, const hawk_oocs_t segs[], int nsegs, int closer_token)
|
static hawk_nde_t* _parse_primary_array_or_map (hawk_t* hawk, const hawk_loc_t* xloc, const hawk_oocs_t* full, const hawk_oocs_t segs[], int nsegs, int closer_token)
|
||||||
{
|
{
|
||||||
/* treat it as if it's hawk::array() */
|
/* called for @[ or @{ handling. the caller of this function passes "hawk::array" or
|
||||||
|
* "hawk:map" via "full'. */
|
||||||
hawk_mod_t* mod;
|
hawk_mod_t* mod;
|
||||||
hawk_mod_sym_t sym;
|
hawk_mod_sym_t sym;
|
||||||
hawk_fnc_t fnc;
|
hawk_fnc_t fnc;
|
||||||
@@ -5587,6 +5601,7 @@ static hawk_nde_t* _parse_primary_array_or_map (hawk_t* hawk, const hawk_loc_t*
|
|||||||
fnc.spec = sym.u.fnc_;
|
fnc.spec = sym.u.fnc_;
|
||||||
fnc.mod = mod;
|
fnc.mod = mod;
|
||||||
|
|
||||||
|
/* convert it to a function call */
|
||||||
return parse_fncall(hawk, full, &fnc, xloc, (closer_token == TOK_RBRACE? FNCALL_FLAG_MAP: 0), closer_token);
|
return parse_fncall(hawk, full, &fnc, xloc, (closer_token == TOK_RBRACE? FNCALL_FLAG_MAP: 0), closer_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6026,10 +6041,10 @@ static hawk_nde_t* parse_primary_nopipe (hawk_t* hawk, const hawk_loc_t* xloc)
|
|||||||
case TOK_IDENT:
|
case TOK_IDENT:
|
||||||
return parse_primary_ident(hawk, xloc);
|
return parse_primary_ident(hawk, xloc);
|
||||||
|
|
||||||
case TOK_ATBRACK:
|
case TOK_ATBRACK: /* @[ */
|
||||||
return parse_primary_array(hawk, xloc);
|
return parse_primary_array(hawk, xloc);
|
||||||
|
|
||||||
case TOK_ATBRACE:
|
case TOK_ATBRACE: /* @{ */
|
||||||
return parse_primary_map(hawk, xloc);
|
return parse_primary_map(hawk, xloc);
|
||||||
|
|
||||||
case TOK_CHAR:
|
case TOK_CHAR:
|
||||||
@@ -6262,7 +6277,7 @@ static hawk_nde_t* parse_variable (hawk_t* hawk, const hawk_loc_t* xloc, hawk_nd
|
|||||||
|
|
||||||
#if defined(HAWK_ENABLE_FUN_AS_VALUE)
|
#if defined(HAWK_ENABLE_FUN_AS_VALUE)
|
||||||
if (!is_fcv) return (hawk_nde_t*)nde;
|
if (!is_fcv) return (hawk_nde_t*)nde;
|
||||||
return parse_fncall(hawk, (const hawk_oocs_t*)nde, HAWK_NULL, xloc, FNCALL_FLAG_VAR, TOK_RPAREN);
|
return parse_fncall(hawk, (const hawk_oocs_t*)nde, HAWK_NULL, xloc, FNCALL_FLAG_EXPR, TOK_RPAREN);
|
||||||
#else
|
#else
|
||||||
return (hawk_nde_t*)nde;
|
return (hawk_nde_t*)nde;
|
||||||
#endif
|
#endif
|
||||||
@@ -6464,7 +6479,7 @@ static hawk_nde_t* parse_primary_ident_noseg (hawk_t* hawk, const hawk_loc_t* xl
|
|||||||
*
|
*
|
||||||
* it is a function call so long as it's followed
|
* it is a function call so long as it's followed
|
||||||
* by a left parenthesis if concatenation by blanks
|
* by a left parenthesis if concatenation by blanks
|
||||||
* is not allowed.
|
* (HAWK_BLANKCONCAT) is not allowed.
|
||||||
*/
|
*/
|
||||||
int is_fncall_var = 0;
|
int is_fncall_var = 0;
|
||||||
|
|
||||||
@@ -6524,7 +6539,7 @@ static hawk_nde_t* parse_primary_ident_noseg (hawk_t* hawk, const hawk_loc_t* xl
|
|||||||
|
|
||||||
#if defined(HAWK_ENABLE_FUN_AS_VALUE)
|
#if defined(HAWK_ENABLE_FUN_AS_VALUE)
|
||||||
if (is_fncall_var)
|
if (is_fncall_var)
|
||||||
nde = parse_fncall(hawk, (const hawk_oocs_t*)nde, HAWK_NULL, xloc, FNCALL_FLAG_VAR, TOK_RPAREN);
|
nde = parse_fncall(hawk, (const hawk_oocs_t*)nde, HAWK_NULL, xloc, FNCALL_FLAG_EXPR, TOK_RPAREN);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6771,7 +6786,7 @@ oops:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static hawk_nde_t* finalize_hashidx (hawk_t* hawk, const hawk_oocs_t* name, const hawk_loc_t* xloc, hawk_nde_t* idx)
|
static hawk_nde_t* make_hashidx_access_node (hawk_t* hawk, const hawk_oocs_t* name, const hawk_loc_t* xloc, hawk_nde_t* idx)
|
||||||
{
|
{
|
||||||
hawk_nde_var_t* nde;
|
hawk_nde_var_t* nde;
|
||||||
hawk_oow_t idxa;
|
hawk_oow_t idxa;
|
||||||
@@ -6779,7 +6794,6 @@ static hawk_nde_t* finalize_hashidx (hawk_t* hawk, const hawk_oocs_t* name, cons
|
|||||||
nde = (hawk_nde_var_t*)hawk_callocmem(hawk, HAWK_SIZEOF(*nde));
|
nde = (hawk_nde_var_t*)hawk_callocmem(hawk, HAWK_SIZEOF(*nde));
|
||||||
if (HAWK_UNLIKELY(!nde))
|
if (HAWK_UNLIKELY(!nde))
|
||||||
{
|
{
|
||||||
hawk_clrpt(hawk, idx);
|
|
||||||
ADJERR_LOC(hawk, xloc);
|
ADJERR_LOC(hawk, xloc);
|
||||||
return HAWK_NULL;
|
return HAWK_NULL;
|
||||||
}
|
}
|
||||||
@@ -6882,17 +6896,19 @@ static hawk_nde_t* finalize_hashidx (hawk_t* hawk, const hawk_oocs_t* name, cons
|
|||||||
return (hawk_nde_t*)nde;
|
return (hawk_nde_t*)nde;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -- ERROR down here -- */
|
||||||
|
|
||||||
/* undefined variable */
|
/* undefined variable */
|
||||||
hawk_seterrfmt(hawk, xloc, HAWK_EUNDEF, FMT_EUNDEF, name->len, name->ptr);
|
hawk_seterrfmt(hawk, xloc, HAWK_EUNDEF, FMT_EUNDEF, name->len, name->ptr);
|
||||||
|
|
||||||
exit_func:
|
exit_func:
|
||||||
hawk_clrpt(hawk, idx);
|
/* didn't take over 'name' and 'idx'. just free the node structure
|
||||||
|
* using hawk_freemem(). no call to hawk_clrpt() */
|
||||||
hawk_freemem(hawk, nde);
|
hawk_freemem(hawk, nde);
|
||||||
|
|
||||||
return HAWK_NULL;
|
return HAWK_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static hawk_nde_t* parse_hashidx_common (hawk_t* hawk, const hawk_oocs_t* name, const hawk_loc_t* xloc)
|
static hawk_nde_t* parse_idx_chain (hawk_t* hawk, const hawk_loc_t* xloc)
|
||||||
{
|
{
|
||||||
nde_chain_t idx = { HAWK_NULL, HAWK_NULL };
|
nde_chain_t idx = { HAWK_NULL, HAWK_NULL };
|
||||||
|
|
||||||
@@ -6903,34 +6919,47 @@ static hawk_nde_t* parse_hashidx_common (hawk_t* hawk, const hawk_oocs_t* name,
|
|||||||
#if defined(HAWK_ENABLE_GC)
|
#if defined(HAWK_ENABLE_GC)
|
||||||
while (MATCH(hawk, TOK_LBRACK) || MATCH(hawk, TOK_PERIOD))
|
while (MATCH(hawk, TOK_LBRACK) || MATCH(hawk, TOK_PERIOD))
|
||||||
{
|
{
|
||||||
hawk_nde_t* tmp;
|
hawk_nde_t* splitter;
|
||||||
|
|
||||||
/* additional index - a[10][20] or a.b.c ...
|
/* additional index - a[10][20] or a.b.c ...
|
||||||
* use the NULL node as a splitter */
|
* use the NULL node as a splitter */
|
||||||
tmp = (hawk_nde_t*)hawk_callocmem(hawk, HAWK_SIZEOF(*tmp));
|
splitter = (hawk_nde_t*)hawk_callocmem(hawk, HAWK_SIZEOF(*splitter));
|
||||||
if (HAWK_UNLIKELY(!tmp))
|
if (HAWK_UNLIKELY(!splitter))
|
||||||
{
|
{
|
||||||
ADJERR_LOC(hawk, xloc);
|
ADJERR_LOC(hawk, xloc);
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp->type = HAWK_NDE_NULL;
|
splitter->type = HAWK_NDE_NULL;
|
||||||
|
|
||||||
HAWK_ASSERT(idx.tail != HAWK_NULL);
|
HAWK_ASSERT(idx.tail != HAWK_NULL);
|
||||||
idx.tail->next = tmp;
|
idx.tail->next = splitter;
|
||||||
idx.tail = tmp;
|
idx.tail = splitter;
|
||||||
|
|
||||||
if (parse_single_idx(hawk, &idx) <= -1) goto oops;
|
if (parse_single_idx(hawk, &idx) <= -1) goto oops;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return finalize_hashidx(hawk, name, xloc, idx.head);
|
return idx.head;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
if (idx.head) hawk_clrpt(hawk, idx.head);
|
if (idx.head) hawk_clrpt(hawk, idx.head);
|
||||||
return HAWK_NULL;
|
return HAWK_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static hawk_nde_t* parse_hashidx_common (hawk_t* hawk, const hawk_oocs_t* name, const hawk_loc_t* xloc)
|
||||||
|
{
|
||||||
|
hawk_nde_t* idx;
|
||||||
|
hawk_nde_t* h;
|
||||||
|
|
||||||
|
idx = parse_idx_chain(hawk, xloc);
|
||||||
|
if (HAWK_UNLIKELY(!idx)) return HAWK_NULL;
|
||||||
|
|
||||||
|
h = make_hashidx_access_node(hawk, name, xloc, idx);
|
||||||
|
if (HAWK_UNLIKELY(!h)) hawk_clrpt(hawk, idx);
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
static hawk_nde_t* parse_hashidx (hawk_t* hawk, const hawk_oocs_t* name, const hawk_loc_t* xloc)
|
static hawk_nde_t* parse_hashidx (hawk_t* hawk, const hawk_oocs_t* name, const hawk_loc_t* xloc)
|
||||||
{
|
{
|
||||||
HAWK_ASSERT(MATCH(hawk, TOK_LBRACK));
|
HAWK_ASSERT(MATCH(hawk, TOK_LBRACK));
|
||||||
@@ -6979,19 +7008,29 @@ static hawk_nde_t* parse_fncall (hawk_t* hawk, const hawk_oocs_t* name, hawk_fnc
|
|||||||
|
|
||||||
if (MATCH(hawk, closer_token))
|
if (MATCH(hawk, closer_token))
|
||||||
{
|
{
|
||||||
|
if ((flags & FNCALL_FLAG_MAP) && (nargs & 1))
|
||||||
|
{
|
||||||
|
/* a value part is missing after colon inside @{} */
|
||||||
|
goto colon_expected;
|
||||||
|
}
|
||||||
if (get_token(hawk) <= -1) goto oops;
|
if (get_token(hawk) <= -1) goto oops;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & FNCALL_FLAG_MAP) && (nargs & 1))
|
if ((flags & FNCALL_FLAG_MAP) && (nargs & 1))
|
||||||
{
|
{
|
||||||
|
/* inside @{},
|
||||||
|
* - it expects a colon after each key
|
||||||
|
* - after value, a comma is expected */
|
||||||
if (!MATCH(hawk, TOK_COLON))
|
if (!MATCH(hawk, TOK_COLON))
|
||||||
{
|
{
|
||||||
|
colon_expected:
|
||||||
hawk_seterrfmt(hawk, &hawk->tok.loc, HAWK_ECOLON, FMT_ECOLON, HAWK_OOECS_LEN(hawk->tok.name), HAWK_OOECS_PTR(hawk->tok.name));
|
hawk_seterrfmt(hawk, &hawk->tok.loc, HAWK_ECOLON, FMT_ECOLON, HAWK_OOECS_LEN(hawk->tok.name), HAWK_OOECS_PTR(hawk->tok.name));
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
if (!MATCH(hawk, TOK_COMMA))
|
if (!MATCH(hawk, TOK_COMMA))
|
||||||
{
|
{
|
||||||
hawk_seterrfmt(hawk, &hawk->tok.loc, HAWK_ECOMMA, FMT_ECOMMA, HAWK_OOECS_LEN(hawk->tok.name), HAWK_OOECS_PTR(hawk->tok.name));
|
hawk_seterrfmt(hawk, &hawk->tok.loc, HAWK_ECOMMA, FMT_ECOMMA, HAWK_OOECS_LEN(hawk->tok.name), HAWK_OOECS_PTR(hawk->tok.name));
|
||||||
@@ -7005,7 +7044,6 @@ static hawk_nde_t* parse_fncall (hawk_t* hawk, const hawk_oocs_t* name, hawk_fnc
|
|||||||
}
|
}
|
||||||
while (MATCH(hawk,TOK_NEWLINE));
|
while (MATCH(hawk,TOK_NEWLINE));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
make_node:
|
make_node:
|
||||||
@@ -7016,11 +7054,13 @@ make_node:
|
|||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & FNCALL_FLAG_VAR)
|
if (flags & FNCALL_FLAG_EXPR)
|
||||||
{
|
{
|
||||||
call->type = HAWK_NDE_FNCALL_VAR;
|
/* special case. "name" is not of the const hawk_oocs_t* type.
|
||||||
|
* it points to the node directly */
|
||||||
|
call->type = HAWK_NDE_FNCALL_EXPR;
|
||||||
call->loc = *xloc;
|
call->loc = *xloc;
|
||||||
call->u.var.var = (hawk_nde_var_t*)name; /* name is a pointer to a variable node */
|
call->u.expr.callable = (hawk_nde_t*)name; /* name is a pointer to a callable expression node */
|
||||||
call->args = head;
|
call->args = head;
|
||||||
call->nargs = nargs;
|
call->nargs = nargs;
|
||||||
}
|
}
|
||||||
@@ -7068,8 +7108,8 @@ make_node:
|
|||||||
return (hawk_nde_t*)call;
|
return (hawk_nde_t*)call;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
if (call) hawk_freemem(hawk, call);
|
if (call) hawk_freemem(hawk, call); /* destroy the call node itself */
|
||||||
if (head) hawk_clrpt(hawk, head);
|
if (head) hawk_clrpt(hawk, head); /* clear the argument list separately from the call node */
|
||||||
return HAWK_NULL;
|
return HAWK_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7099,6 +7139,13 @@ static int get_number (hawk_t* hawk, hawk_tok_t* tok)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if (c == 'o' || c == 'O')
|
||||||
|
{
|
||||||
|
/* octal number */
|
||||||
|
ADD_TOKEN_CHAR(hawk, tok, c);
|
||||||
|
GET_CHAR_TO(hawk, c);
|
||||||
|
goto octal;
|
||||||
|
}
|
||||||
else if (c == 'b' || c == 'B')
|
else if (c == 'b' || c == 'B')
|
||||||
{
|
{
|
||||||
/* binary number */
|
/* binary number */
|
||||||
@@ -7114,6 +7161,7 @@ static int get_number (hawk_t* hawk, hawk_tok_t* tok)
|
|||||||
else if (c != '.')
|
else if (c != '.')
|
||||||
{
|
{
|
||||||
/* octal number */
|
/* octal number */
|
||||||
|
octal:
|
||||||
while (c >= '0' && c <= '7')
|
while (c >= '0' && c <= '7')
|
||||||
{
|
{
|
||||||
ADD_TOKEN_CHAR(hawk, tok, c);
|
ADD_TOKEN_CHAR(hawk, tok, c);
|
||||||
@@ -8187,7 +8235,14 @@ static int classify_ident (hawk_t* hawk, const hawk_oocs_t* name)
|
|||||||
|
|
||||||
/* declaring left, right, mid to be the int type is ok
|
/* declaring left, right, mid to be the int type is ok
|
||||||
* because we know kwtab is small enough. */
|
* because we know kwtab is small enough. */
|
||||||
int left = 0, right = HAWK_COUNTOF(kwtab) - 1, mid;
|
int left, right, mid;
|
||||||
|
|
||||||
|
/* extra alias keywords which are not part of the main kwtab */
|
||||||
|
if (hawk_comp_oochars_bcstr(name->ptr, name->len, "func", 0) == 0) return TOK_FUNCTION;
|
||||||
|
|
||||||
|
/* search in the main kwtab */
|
||||||
|
left = 0;
|
||||||
|
right = HAWK_COUNTOF(kwtab) - 1;
|
||||||
|
|
||||||
while (left <= right)
|
while (left <= right)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7408,13 +7408,35 @@ static HAWK_INLINE hawk_val_t* eval_fncall_fun (hawk_rtx_t* rtx, hawk_nde_t* nde
|
|||||||
return hawk_rtx_evalcall(rtx, call, fun, push_arg_from_nde, HAWK_NULL/*fun->argspec*/, HAWK_NULL, HAWK_NULL);
|
return hawk_rtx_evalcall(rtx, call, fun, push_arg_from_nde, HAWK_NULL/*fun->argspec*/, HAWK_NULL, HAWK_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HAWK_INLINE int nde_is_var (const hawk_nde_t* nde)
|
||||||
|
{
|
||||||
|
switch (nde->type)
|
||||||
|
{
|
||||||
|
case HAWK_NDE_NAMED:
|
||||||
|
case HAWK_NDE_GBL:
|
||||||
|
case HAWK_NDE_LCL:
|
||||||
|
case HAWK_NDE_ARG:
|
||||||
|
case HAWK_NDE_NAMEDIDX:
|
||||||
|
case HAWK_NDE_GBLIDX:
|
||||||
|
case HAWK_NDE_LCLIDX:
|
||||||
|
case HAWK_NDE_ARGIDX:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static hawk_val_t* eval_fncall_var (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
static hawk_val_t* eval_fncall_var (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
||||||
{
|
{
|
||||||
hawk_nde_fncall_t* call = (hawk_nde_fncall_t*)nde;
|
hawk_nde_fncall_t* call = (hawk_nde_fncall_t*)nde;
|
||||||
|
hawk_nde_t* callee;
|
||||||
hawk_val_t* fv, * rv;
|
hawk_val_t* fv, * rv;
|
||||||
hawk_fun_t* fun;
|
hawk_fun_t* fun;
|
||||||
|
|
||||||
fv = eval_expression(rtx, (hawk_nde_t*)call->u.var.var);
|
callee = call->u.expr.callable;
|
||||||
|
|
||||||
|
fv = eval_expression(rtx, callee);
|
||||||
if (HAWK_UNLIKELY(!fv)) return HAWK_NULL;
|
if (HAWK_UNLIKELY(!fv)) return HAWK_NULL;
|
||||||
|
|
||||||
hawk_rtx_refupval(rtx, fv);
|
hawk_rtx_refupval(rtx, fv);
|
||||||
@@ -7422,14 +7444,24 @@ static hawk_val_t* eval_fncall_var (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
|||||||
if (HAWK_UNLIKELY(!fun))
|
if (HAWK_UNLIKELY(!fun))
|
||||||
{
|
{
|
||||||
if (hawk_rtx_geterrnum(rtx) == HAWK_EINVAL)
|
if (hawk_rtx_geterrnum(rtx) == HAWK_EINVAL)
|
||||||
hawk_rtx_seterrfmt(rtx, &nde->loc, HAWK_ENOTFUN, HAWK_T("non-function value in %.*js"), call->u.var.var->id.name.len, call->u.var.var->id.name.ptr);
|
{
|
||||||
|
if (nde_is_var(callee))
|
||||||
|
{
|
||||||
|
hawk_nde_var_t* v = (hawk_nde_var_t*)callee;
|
||||||
|
hawk_rtx_seterrfmt(rtx, &nde->loc, HAWK_ENOTFUN,
|
||||||
|
HAWK_T("non-function value in '%.*js'"),
|
||||||
|
v->id.name.len, v->id.name.ptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hawk_rtx_seterrnum(rtx, &nde->loc, HAWK_ENOTFUN);
|
||||||
|
}
|
||||||
|
}
|
||||||
ADJERR_LOC(rtx, &nde->loc);
|
ADJERR_LOC(rtx, &nde->loc);
|
||||||
rv = HAWK_NULL;
|
rv = HAWK_NULL;
|
||||||
}
|
}
|
||||||
else if (call->nargs > fun->nargs && !fun->variadic)
|
else if (call->nargs > fun->nargs && !fun->variadic)
|
||||||
{
|
{
|
||||||
/* TODO: is this correct? what if i want to
|
|
||||||
* allow arbitarary numbers of arguments? */
|
|
||||||
hawk_rtx_seterrfmt(rtx, &nde->loc, HAWK_EARGTM, HAWK_T("too many arguments to '%.*js'"), fun->name.len, fun->name.ptr);
|
hawk_rtx_seterrfmt(rtx, &nde->loc, HAWK_EARGTM, HAWK_T("too many arguments to '%.*js'"), fun->name.len, fun->name.ptr);
|
||||||
rv = HAWK_NULL;
|
rv = HAWK_NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -235,7 +235,7 @@ struct hawk_nde_var_t
|
|||||||
hawk_uint8_t is_const;
|
hawk_uint8_t is_const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* HAWK_NDE_FNCALL_FNC, HAWK_NDE_FNCALL_FUN, HAWK_NDE_FNCALL_VAR */
|
/* HAWK_NDE_FNCALL_FNC, HAWK_NDE_FNCALL_FUN, HAWK_NDE_FNCALL_EXPR */
|
||||||
struct hawk_nde_fncall_t
|
struct hawk_nde_fncall_t
|
||||||
{
|
{
|
||||||
HAWK_NDE_HDR;
|
HAWK_NDE_HDR;
|
||||||
@@ -257,8 +257,8 @@ struct hawk_nde_fncall_t
|
|||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
hawk_nde_var_t* var;
|
hawk_nde_t* callable;
|
||||||
} var;
|
} expr;
|
||||||
} u;
|
} u;
|
||||||
hawk_nde_t* args;
|
hawk_nde_t* args;
|
||||||
hawk_oow_t nargs;
|
hawk_oow_t nargs;
|
||||||
|
|||||||
+4
-4
@@ -788,10 +788,10 @@ static int print_expr (hawk_t* hawk, hawk_nde_t* nde)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case HAWK_NDE_FNCALL_VAR:
|
case HAWK_NDE_FNCALL_EXPR:
|
||||||
{
|
{
|
||||||
hawk_nde_fncall_t* px = (hawk_nde_fncall_t*)nde;
|
hawk_nde_fncall_t* px = (hawk_nde_fncall_t*)nde;
|
||||||
PRINT_EXPR(hawk, (hawk_nde_t*)px->u.var.var);
|
PRINT_EXPR(hawk, (hawk_nde_t*)px->u.expr.callable);
|
||||||
PUT_SRCSTR(hawk, HAWK_T("("));
|
PUT_SRCSTR(hawk, HAWK_T("("));
|
||||||
PRINT_EXPR_LIST(hawk, px->args);
|
PRINT_EXPR_LIST(hawk, px->args);
|
||||||
PUT_SRCSTR(hawk, HAWK_T(")"));
|
PUT_SRCSTR(hawk, HAWK_T(")"));
|
||||||
@@ -1624,10 +1624,10 @@ void hawk_clrpt (hawk_t* hawk, hawk_nde_t* tree)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case HAWK_NDE_FNCALL_VAR:
|
case HAWK_NDE_FNCALL_EXPR:
|
||||||
{
|
{
|
||||||
hawk_nde_fncall_t* px = (hawk_nde_fncall_t*)p;
|
hawk_nde_fncall_t* px = (hawk_nde_fncall_t*)p;
|
||||||
hawk_clrpt(hawk, (hawk_nde_t*)px->u.var.var);
|
hawk_clrpt(hawk, (hawk_nde_t*)px->u.expr.callable);
|
||||||
hawk_clrpt(hawk, px->args);
|
hawk_clrpt(hawk, px->args);
|
||||||
hawk_freemem(hawk, p);
|
hawk_freemem(hawk, p);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -2726,6 +2726,10 @@ hawk_int_t hawk_uchars_to_int (const hawk_uch_t* str, hawk_oow_t len, int option
|
|||||||
{
|
{
|
||||||
p++; base = 16;
|
p++; base = 16;
|
||||||
}
|
}
|
||||||
|
else if (*p == 'o' || *p == 'O')
|
||||||
|
{
|
||||||
|
p++; base = 8;
|
||||||
|
}
|
||||||
else if (*p == 'b' || *p == 'B')
|
else if (*p == 'b' || *p == 'B')
|
||||||
{
|
{
|
||||||
p++; base = 2;
|
p++; base = 2;
|
||||||
@@ -2738,6 +2742,10 @@ hawk_int_t hawk_uchars_to_int (const hawk_uch_t* str, hawk_oow_t len, int option
|
|||||||
{
|
{
|
||||||
if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) p += 2;
|
if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) p += 2;
|
||||||
}
|
}
|
||||||
|
else if (rem >= 2 && base == 8)
|
||||||
|
{
|
||||||
|
if (*p == '0' && (*(p + 1) == 'o' || *(p + 1) == 'O')) p += 2;
|
||||||
|
}
|
||||||
else if (rem >= 2 && base == 2)
|
else if (rem >= 2 && base == 2)
|
||||||
{
|
{
|
||||||
if (*p == '0' && (*(p + 1) == 'b' || *(p + 1) == 'B')) p += 2;
|
if (*p == '0' && (*(p + 1) == 'b' || *(p + 1) == 'B')) p += 2;
|
||||||
@@ -2947,6 +2955,10 @@ hawk_uint_t hawk_uchars_to_uint (const hawk_uch_t* str, hawk_oow_t len, int opti
|
|||||||
{
|
{
|
||||||
p++; base = 16;
|
p++; base = 16;
|
||||||
}
|
}
|
||||||
|
else if (*p == 'o' || *p == 'O')
|
||||||
|
{
|
||||||
|
p++; base = 8;
|
||||||
|
}
|
||||||
else if (*p == 'b' || *p == 'B')
|
else if (*p == 'b' || *p == 'B')
|
||||||
{
|
{
|
||||||
p++; base = 2;
|
p++; base = 2;
|
||||||
@@ -2959,6 +2971,10 @@ hawk_uint_t hawk_uchars_to_uint (const hawk_uch_t* str, hawk_oow_t len, int opti
|
|||||||
{
|
{
|
||||||
if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) p += 2;
|
if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X')) p += 2;
|
||||||
}
|
}
|
||||||
|
else if (rem >= 2 && base == 8)
|
||||||
|
{
|
||||||
|
if (*p == '0' && (*(p + 1) == 'o' || *(p + 1) == 'O')) p += 2;
|
||||||
|
}
|
||||||
else if (rem >= 2 && base == 2)
|
else if (rem >= 2 && base == 2)
|
||||||
{
|
{
|
||||||
if (*p == '0' && (*(p + 1) == 'b' || *(p + 1) == 'B')) p += 2;
|
if (*p == '0' && (*(p + 1) == 'b' || *(p + 1) == 'B')) p += 2;
|
||||||
|
|||||||
Reference in New Issue
Block a user