Compare commits

..

2 Commits

Author SHA1 Message Date
hyung-hwan 7b9cab4b47 added the octal number notation with the prefix 0o
continuous-integration/drone/push Build is passing
did some code refactor
2026-02-03 12:47:09 +09:00
hyung-hwan 62f1c3695f fixed the keyword check data and function 2026-01-27 15:24:34 +09:00
8 changed files with 157 additions and 54 deletions
Vendored
+3 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
{ {
+36 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+16
View File
@@ -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;