fixed a flaw in collect_local_vardcl().

This commit is contained in:
hyung-hwan 2021-04-20 16:17:15 +00:00
parent 5a519faf77
commit 4ff6fff433

View File

@ -1499,7 +1499,7 @@ static HCL_INLINE int compile_else (hcl_t* hcl)
/* ========================================================================= */ /* ========================================================================= */
static hcl_cnode_t* collect_local_vardcl (hcl_t* hcl, hcl_cnode_t* obj, hcl_oow_t tv_dup_check_start, hcl_oow_t* nvardcls) static int collect_local_vardcl (hcl_t* hcl, hcl_cnode_t* obj, hcl_cnode_t** nextobj, hcl_oow_t tv_dup_check_start, hcl_oow_t* nvardcls)
{ {
hcl_oow_t ndcls = 0; hcl_oow_t ndcls = 0;
@ -1518,13 +1518,13 @@ static hcl_cnode_t* collect_local_vardcl (hcl_t* hcl, hcl_cnode_t* obj, hcl_oow_
if (!HCL_CNODE_IS_SYMBOL(var)) if (!HCL_CNODE_IS_SYMBOL(var))
{ {
hcl_setsynerrbfmt (hcl, HCL_SYNERR_ARGNAME, HCL_CNODE_GET_LOC(var), HCL_CNODE_GET_TOK(var), "local variable not a symbol"); hcl_setsynerrbfmt (hcl, HCL_SYNERR_ARGNAME, HCL_CNODE_GET_LOC(var), HCL_CNODE_GET_TOK(var), "local variable not a symbol");
return HCL_NULL; return -1;
} }
if (HCL_CNODE_IS_SYMBOL(var) && HCL_CNODE_SYMBOL_SYNCODE(var) /* || HCL_OBJ_GET_FLAGS_KERNEL(var) >= 2 */) if (HCL_CNODE_IS_SYMBOL(var) && HCL_CNODE_SYMBOL_SYNCODE(var) /* || HCL_OBJ_GET_FLAGS_KERNEL(var) >= 2 */)
{ {
hcl_setsynerrbfmt (hcl, HCL_SYNERR_BANNEDARGNAME, HCL_CNODE_GET_LOC(var), HCL_CNODE_GET_TOK(var), "special symbol not to be declared as a local variable"); hcl_setsynerrbfmt (hcl, HCL_SYNERR_BANNEDARGNAME, HCL_CNODE_GET_LOC(var), HCL_CNODE_GET_TOK(var), "special symbol not to be declared as a local variable");
return HCL_NULL; return -1;
} }
#else #else
/* the above checks are not needed as the reader guarantees the followings */ /* the above checks are not needed as the reader guarantees the followings */
@ -1537,7 +1537,7 @@ static hcl_cnode_t* collect_local_vardcl (hcl_t* hcl, hcl_cnode_t* obj, hcl_oow_
{ {
hcl_setsynerrbfmt (hcl, HCL_SYNERR_ARGNAMEDUP, HCL_CNODE_GET_LOC(var), HCL_CNODE_GET_TOK(var), "duplicate local variable"); hcl_setsynerrbfmt (hcl, HCL_SYNERR_ARGNAMEDUP, HCL_CNODE_GET_LOC(var), HCL_CNODE_GET_TOK(var), "duplicate local variable");
} }
return HCL_NULL; return -1;
} }
ndcls++; ndcls++;
@ -1547,7 +1547,7 @@ static hcl_cnode_t* collect_local_vardcl (hcl_t* hcl, hcl_cnode_t* obj, hcl_oow_
if (!HCL_CNODE_IS_CONS(dcl)) if (!HCL_CNODE_IS_CONS(dcl))
{ {
hcl_setsynerrbfmt (hcl, HCL_SYNERR_DOTBANNED, HCL_CNODE_GET_LOC(dcl), HCL_CNODE_GET_TOK(dcl), "redundant cdr in local variable list"); hcl_setsynerrbfmt (hcl, HCL_SYNERR_DOTBANNED, HCL_CNODE_GET_LOC(dcl), HCL_CNODE_GET_TOK(dcl), "redundant cdr in local variable list");
return HCL_NULL; return -1;
} }
} }
while (1); while (1);
@ -1558,7 +1558,8 @@ static hcl_cnode_t* collect_local_vardcl (hcl_t* hcl, hcl_cnode_t* obj, hcl_oow_
} }
*nvardcls = ndcls; *nvardcls = ndcls;
return obj; *nextobj = obj;
return 0;
} }
static int compile_lambda (hcl_t* hcl, hcl_cnode_t* src, int defun) static int compile_lambda (hcl_t* hcl, hcl_cnode_t* src, int defun)
@ -1692,8 +1693,7 @@ static int compile_lambda (hcl_t* hcl, hcl_cnode_t* src, int defun)
obj = HCL_CNODE_CONS_CDR(obj); obj = HCL_CNODE_CONS_CDR(obj);
tv_dup_start = hcl->c->tv.s.len; tv_dup_start = hcl->c->tv.s.len;
obj = collect_local_vardcl(hcl, obj, tv_dup_start, &ntmprs); if (collect_local_vardcl(hcl, obj, &obj, tv_dup_start, &ntmprs) <= -1) return -1;
if (!obj) return -1;
ntmprs += nargs; /* ntmprs: number of temporary variables including arguments */ ntmprs += nargs; /* ntmprs: number of temporary variables including arguments */
HCL_ASSERT (hcl, ntmprs == hcl->c->tv.wcount - saved_tv_wcount); HCL_ASSERT (hcl, ntmprs == hcl->c->tv.wcount - saved_tv_wcount);
@ -1958,7 +1958,7 @@ static HCL_INLINE int patch_nearest_post_try (hcl_t* hcl, hcl_ooi_t* catch_skip_
static HCL_INLINE int compile_catch (hcl_t* hcl) static HCL_INLINE int compile_catch (hcl_t* hcl)
{ {
hcl_cnode_t* cmd, * obj, * src; hcl_cnode_t* cmd, * obj, * src, * exarg;
hcl_cframe_t* cf; hcl_cframe_t* cf;
hcl_ooi_t jump_inst_pos; hcl_ooi_t jump_inst_pos;
@ -1974,7 +1974,8 @@ static HCL_INLINE int compile_catch (hcl_t* hcl)
if (!obj) if (!obj)
{ {
hcl_setsynerrbfmt (hcl, HCL_SYNERR_ARGCOUNT, HCL_CNODE_GET_LOC(src), HCL_NULL, "no condition in %.*js", HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); /* TODO: change error code */
hcl_setsynerrbfmt (hcl, HCL_SYNERR_VARNAME, HCL_CNODE_GET_LOC(src), HCL_NULL, "no exception variable in %.*js", HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));
return -1; return -1;
} }
else if (!HCL_CNODE_IS_CONS(obj)) else if (!HCL_CNODE_IS_CONS(obj))
@ -1983,12 +1984,26 @@ static HCL_INLINE int compile_catch (hcl_t* hcl)
return -1; return -1;
} }
exarg = HCL_CNODE_CONS_CAR(obj);
if (HCL_CNODE_IS_ELIST_CONCODED(exarg, HCL_CONCODE_XLIST) || !HCL_CNODE_IS_CONS(exarg) || hcl_countcnodecons(hcl, exarg) != 1)
{
hcl_setsynerrbfmt (hcl, HCL_SYNERR_VARNAME, HCL_CNODE_GET_LOC(exarg), HCL_NULL, "not single exception variable in %.*js", HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));
return -1;
}
exarg = HCL_CNODE_CONS_CAR(exarg);
if (!HCL_CNODE_IS_SYMBOL(exarg) || HCL_CNODE_SYMBOL_SYNCODE(exarg))
{
hcl_setsynerrbfmt (hcl, HCL_SYNERR_VARNAME, HCL_CNODE_GET_LOC(exarg), HCL_CNODE_GET_TOK(exarg), "invalid exception variable name in %.*js", HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));
return -1;
}
/* TODO: add the exception variable to the local variable list... increase the number of local variables ... etc */
obj = HCL_CNODE_CONS_CDR(obj);
/* jump_inst_pos hold the instruction pointer that skips the catch block at the end of the try block */ /* jump_inst_pos hold the instruction pointer that skips the catch block at the end of the try block */
patch_nearest_post_try (hcl, &jump_inst_pos); patch_nearest_post_try (hcl, &jump_inst_pos);
/* TODO: HCL_TRAIT_INTERACTIVE??? */
/* TODO: nargs -> 1 ntmprs -> 1 */
SWITCH_TOP_CFRAME (hcl, COP_COMPILE_OBJECT_LIST, obj); SWITCH_TOP_CFRAME (hcl, COP_COMPILE_OBJECT_LIST, obj);
PUSH_SUBCFRAME (hcl, COP_POST_CATCH, cmd); PUSH_SUBCFRAME (hcl, COP_POST_CATCH, cmd);