updated the compiler to be more strict when it comes to the places where methods can be defined.
yet to fix test cases
This commit is contained in:
52
lib/comp.c
52
lib/comp.c
@ -337,6 +337,14 @@ static int is_in_class_init_scope (hak_t* hak)
|
|||||||
return fbi->clsblk_top >= 0;
|
return fbi->clsblk_top >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int is_in_class_init_scope_but_not_at_llvl (hak_t* hak, hak_oow_t llvl)
|
||||||
|
{
|
||||||
|
hak_funblk_info_t* fbi;
|
||||||
|
HAK_ASSERT(hak, hak->c->funblk.depth >= 0);
|
||||||
|
fbi = &hak->c->funblk.info[hak->c->funblk.depth];
|
||||||
|
return fbi->clsblk_top >= 0 && hak->c->clsblk.info[fbi->clsblk_top].def_llvl != llvl;
|
||||||
|
}
|
||||||
|
|
||||||
static int is_in_class_method_scope (hak_t* hak)
|
static int is_in_class_method_scope (hak_t* hak)
|
||||||
{
|
{
|
||||||
hak_oow_t i;
|
hak_oow_t i;
|
||||||
@ -345,9 +353,7 @@ static int is_in_class_method_scope (hak_t* hak)
|
|||||||
for (i = hak->c->funblk.depth + 1; i > 0; )
|
for (i = hak->c->funblk.depth + 1; i > 0; )
|
||||||
{
|
{
|
||||||
hak_funblk_info_t* fbi;
|
hak_funblk_info_t* fbi;
|
||||||
|
|
||||||
fbi = &hak->c->funblk.info[--i];
|
fbi = &hak->c->funblk.info[--i];
|
||||||
|
|
||||||
if (fbi->clsblk_top >= 0)
|
if (fbi->clsblk_top >= 0)
|
||||||
{
|
{
|
||||||
if (i >= hak->c->funblk.depth) return 0; /* in class initialization scope */
|
if (i >= hak->c->funblk.depth) return 0; /* in class initialization scope */
|
||||||
@ -1143,7 +1149,7 @@ static void pop_ctlblk (hak_t* hak)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int push_clsblk (
|
static int push_clsblk (
|
||||||
hak_t* hak, const hak_loc_t* errloc, hak_cnode_t* class_name, hak_oow_t nivars, hak_oow_t ncvars,
|
hak_t* hak, const hak_loc_t* errloc, hak_oow_t llvl, hak_cnode_t* class_name, hak_oow_t nivars, hak_oow_t ncvars,
|
||||||
const hak_ooch_t* ivars_str, hak_oow_t ivars_strlen, const hak_ooch_t* cvars_str, hak_oow_t cvars_strlen)
|
const hak_ooch_t* ivars_str, hak_oow_t ivars_strlen, const hak_ooch_t* cvars_str, hak_oow_t cvars_strlen)
|
||||||
{
|
{
|
||||||
hak_oow_t new_depth;
|
hak_oow_t new_depth;
|
||||||
@ -1179,6 +1185,7 @@ static int push_clsblk (
|
|||||||
|
|
||||||
ci = &hak->c->clsblk.info[new_depth];
|
ci = &hak->c->clsblk.info[new_depth];
|
||||||
HAK_MEMSET(ci, 0, HAK_SIZEOF(*ci));
|
HAK_MEMSET(ci, 0, HAK_SIZEOF(*ci));
|
||||||
|
ci->def_llvl = llvl;
|
||||||
ci->class_name = class_name;
|
ci->class_name = class_name;
|
||||||
ci->nivars = nivars;
|
ci->nivars = nivars;
|
||||||
ci->ncvars = ncvars;
|
ci->ncvars = ncvars;
|
||||||
@ -2940,6 +2947,7 @@ static int compile_class (hak_t* hak, hak_cnode_t* src)
|
|||||||
cf = GET_TOP_CFRAME(hak);
|
cf = GET_TOP_CFRAME(hak);
|
||||||
cf->u._class.nsuperclasses = 0; /* unsed for CLASS_P2 */
|
cf->u._class.nsuperclasses = 0; /* unsed for CLASS_P2 */
|
||||||
cf->u._class.indexed_type = indexed_type;
|
cf->u._class.indexed_type = indexed_type;
|
||||||
|
cf->u._class.llvl = HAK_CNODE_GET_LLVL(src);
|
||||||
cf->u._class.start_loc = *HAK_CNODE_GET_LOC(src); /* TODO: use *HAK_CNODE_GET_LOC(cmd) instead? */
|
cf->u._class.start_loc = *HAK_CNODE_GET_LOC(src); /* TODO: use *HAK_CNODE_GET_LOC(cmd) instead? */
|
||||||
cf->u._class.cmd_cnode = cmd;
|
cf->u._class.cmd_cnode = cmd;
|
||||||
cf->u._class.class_name_cnode = class_name; /* duplicate with operand to COP_COMPILE_CLASS_P2 */
|
cf->u._class.class_name_cnode = class_name; /* duplicate with operand to COP_COMPILE_CLASS_P2 */
|
||||||
@ -2948,6 +2956,7 @@ static int compile_class (hak_t* hak, hak_cnode_t* src)
|
|||||||
cf = GET_TOP_CFRAME(hak);
|
cf = GET_TOP_CFRAME(hak);
|
||||||
cf->u._class.nsuperclasses = nsuperclasses; /* this needs to change if we support multiple superclasses... */
|
cf->u._class.nsuperclasses = nsuperclasses; /* this needs to change if we support multiple superclasses... */
|
||||||
cf->u._class.indexed_type = indexed_type;
|
cf->u._class.indexed_type = indexed_type;
|
||||||
|
cf->u._class.llvl = HAK_CNODE_GET_LLVL(src);
|
||||||
cf->u._class.start_loc = *HAK_CNODE_GET_LOC(src); /* TODO: use *HAK_CNODE_GET_LOC(cmd) instead? */
|
cf->u._class.start_loc = *HAK_CNODE_GET_LOC(src); /* TODO: use *HAK_CNODE_GET_LOC(cmd) instead? */
|
||||||
cf->u._class.cmd_cnode = cmd;
|
cf->u._class.cmd_cnode = cmd;
|
||||||
cf->u._class.class_name_cnode = class_name;
|
cf->u._class.class_name_cnode = class_name;
|
||||||
@ -2993,7 +3002,7 @@ static HAK_INLINE int compile_class_p1 (hak_t* hak)
|
|||||||
|
|
||||||
if (check_block_expression_as_body(hak, obj, cf->u._class.cmd_cnode, FOR_CLASS) <= -1) return -1;
|
if (check_block_expression_as_body(hak, obj, cf->u._class.cmd_cnode, FOR_CLASS) <= -1) return -1;
|
||||||
|
|
||||||
if (push_clsblk(hak, &cf->u._class.start_loc,
|
if (push_clsblk(hak, &cf->u._class.start_loc, cf->u._class.llvl,
|
||||||
cf->u._class.class_name_cnode, vardcl.nivars, vardcl.ncvars,
|
cf->u._class.class_name_cnode, vardcl.nivars, vardcl.ncvars,
|
||||||
&hak->c->tv.s.ptr[vardcl.ivar_start], vardcl.ivar_len,
|
&hak->c->tv.s.ptr[vardcl.ivar_start], vardcl.ivar_len,
|
||||||
&hak->c->tv.s.ptr[vardcl.cvar_start], vardcl.cvar_len) <= -1) goto oops;
|
&hak->c->tv.s.ptr[vardcl.cvar_start], vardcl.cvar_len) <= -1) goto oops;
|
||||||
@ -3423,6 +3432,26 @@ static int compile_fun (hak_t* hak, hak_cnode_t* src)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (src->cn_llvl >= 2 && is_in_class_init_scope_but_not_at_llvl(hak, src->cn_llvl - 2))
|
||||||
|
{
|
||||||
|
if (fun_name)
|
||||||
|
{
|
||||||
|
hak_setsynerrbfmt(
|
||||||
|
hak, HAK_SYNERR_FUN, HAK_CNODE_GET_LOC(cmd), HAK_NULL,
|
||||||
|
"function '%.*js' defined with '%.*js' prohibited in class initialziation context",
|
||||||
|
HAK_CNODE_GET_TOKLEN(fun_name), HAK_CNODE_GET_TOKPTR(fun_name),
|
||||||
|
HAK_CNODE_GET_TOKLEN(cmd), HAK_CNODE_GET_TOKPTR(cmd));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hak_setsynerrbfmt(
|
||||||
|
hak, HAK_SYNERR_FUN, HAK_CNODE_GET_LOC(cmd), HAK_NULL,
|
||||||
|
"unnamed function defined with '%.*js' prohibited in class initialziation context",
|
||||||
|
HAK_CNODE_GET_TOKLEN(cmd), HAK_CNODE_GET_TOKPTR(cmd));
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!fun_name && is_in_class_init_scope(hak))
|
if (!fun_name && is_in_class_init_scope(hak))
|
||||||
{
|
{
|
||||||
/* TODO: it must allow as rvalue..
|
/* TODO: it must allow as rvalue..
|
||||||
@ -3465,7 +3494,7 @@ static int compile_fun (hak_t* hak, hak_cnode_t* src)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else /* !next */
|
||||||
{
|
{
|
||||||
/* nothing after 'fun' (e.g. fun ) */
|
/* nothing after 'fun' (e.g. fun ) */
|
||||||
hak_setsynerrbfmt(
|
hak_setsynerrbfmt(
|
||||||
@ -3921,7 +3950,6 @@ static int compile_var (hak_t* hak, hak_cnode_t* src)
|
|||||||
POP_CFRAME(hak);
|
POP_CFRAME(hak);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -5802,12 +5830,12 @@ static int compile_object_list (hak_t* hak)
|
|||||||
|
|
||||||
cf = GET_TOP_CFRAME(hak);
|
cf = GET_TOP_CFRAME(hak);
|
||||||
HAK_ASSERT(hak, cf->opcode == COP_COMPILE_ARGUMENT_LIST ||
|
HAK_ASSERT(hak, cf->opcode == COP_COMPILE_ARGUMENT_LIST ||
|
||||||
cf->opcode == COP_COMPILE_OBJECT_LIST ||
|
cf->opcode == COP_COMPILE_OBJECT_LIST ||
|
||||||
cf->opcode == COP_COMPILE_OBJECT_LIST_TAIL ||
|
cf->opcode == COP_COMPILE_OBJECT_LIST_TAIL ||
|
||||||
cf->opcode == COP_COMPILE_IF_OBJECT_LIST ||
|
cf->opcode == COP_COMPILE_IF_OBJECT_LIST ||
|
||||||
cf->opcode == COP_COMPILE_IF_OBJECT_LIST_TAIL ||
|
cf->opcode == COP_COMPILE_IF_OBJECT_LIST_TAIL ||
|
||||||
cf->opcode == COP_COMPILE_TRY_OBJECT_LIST ||
|
cf->opcode == COP_COMPILE_TRY_OBJECT_LIST ||
|
||||||
cf->opcode == COP_COMPILE_TRY_OBJECT_LIST_TAIL);
|
cf->opcode == COP_COMPILE_TRY_OBJECT_LIST_TAIL);
|
||||||
|
|
||||||
cop = cf->opcode;
|
cop = cf->opcode;
|
||||||
oprnd = cf->operand;
|
oprnd = cf->operand;
|
||||||
|
@ -460,6 +460,7 @@ typedef enum hak_cnode_flag_t hak_cnode_flag_t;
|
|||||||
|
|
||||||
#define HAK_CNODE_GET_TYPE(x) ((x)->cn_type)
|
#define HAK_CNODE_GET_TYPE(x) ((x)->cn_type)
|
||||||
#define HAK_CNODE_GET_FLAGS(x) ((x)->cn_flags)
|
#define HAK_CNODE_GET_FLAGS(x) ((x)->cn_flags)
|
||||||
|
#define HAK_CNODE_GET_LLVL(x) ((x)->cn_llvl)
|
||||||
#define HAK_CNODE_GET_LOC(x) (&(x)->cn_loc)
|
#define HAK_CNODE_GET_LOC(x) (&(x)->cn_loc)
|
||||||
#define HAK_CNODE_GET_TOK(x) (&(x)->cn_tok)
|
#define HAK_CNODE_GET_TOK(x) (&(x)->cn_tok)
|
||||||
#define HAK_CNODE_GET_TOKPTR(x) ((x)->cn_tok.ptr)
|
#define HAK_CNODE_GET_TOKPTR(x) ((x)->cn_tok.ptr)
|
||||||
@ -505,6 +506,7 @@ struct hak_cnode_t
|
|||||||
int cn_flags;
|
int cn_flags;
|
||||||
hak_loc_t cn_loc;
|
hak_loc_t cn_loc;
|
||||||
hak_oocs_t cn_tok;
|
hak_oocs_t cn_tok;
|
||||||
|
hak_oow_t cn_llvl; /* list level */
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
@ -685,6 +687,7 @@ struct hak_cframe_t
|
|||||||
{
|
{
|
||||||
hak_ooi_t nsuperclasses;
|
hak_ooi_t nsuperclasses;
|
||||||
unsigned int indexed_type;
|
unsigned int indexed_type;
|
||||||
|
hak_oow_t llvl; /* copied from cnode->cn_llvl */
|
||||||
hak_loc_t start_loc;
|
hak_loc_t start_loc;
|
||||||
hak_cnode_t* cmd_cnode;
|
hak_cnode_t* cmd_cnode;
|
||||||
hak_cnode_t* class_name_cnode;
|
hak_cnode_t* class_name_cnode;
|
||||||
@ -738,6 +741,7 @@ typedef struct hak_funblk_info_t hak_funblk_info_t;
|
|||||||
|
|
||||||
struct hak_clsblk_info_t
|
struct hak_clsblk_info_t
|
||||||
{
|
{
|
||||||
|
hak_oow_t def_llvl; /* defined list level */
|
||||||
hak_cnode_t* class_name;
|
hak_cnode_t* class_name;
|
||||||
|
|
||||||
hak_oocsc_t ivars;
|
hak_oocsc_t ivars;
|
||||||
|
10
lib/read.c
10
lib/read.c
@ -1553,6 +1553,7 @@ static int feed_process_token (hak_t* hak)
|
|||||||
int oldflagv;
|
int oldflagv;
|
||||||
frd->expect_vlist_item = 0;
|
frd->expect_vlist_item = 0;
|
||||||
frd->obj = leave_list(hak, &frd->list_loc, &frd->flagv, &oldflagv);
|
frd->obj = leave_list(hak, &frd->list_loc, &frd->flagv, &oldflagv);
|
||||||
|
if (HAK_LIKELY(frd->obj)) frd->obj->cn_llvl = frd->level;
|
||||||
frd->level--;
|
frd->level--;
|
||||||
frd->flagv |= AT_BEGINNING;
|
frd->flagv |= AT_BEGINNING;
|
||||||
list_loc = &frd->list_loc;
|
list_loc = &frd->list_loc;
|
||||||
@ -1786,6 +1787,7 @@ static int feed_process_token (hak_t* hak)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
frd->obj = leave_list(hak, &frd->list_loc, &frd->flagv, &oldflagv);
|
frd->obj = leave_list(hak, &frd->list_loc, &frd->flagv, &oldflagv);
|
||||||
|
if (HAK_LIKELY(frd->obj)) frd->obj->cn_llvl = frd->level; /* list level */
|
||||||
frd->level--;
|
frd->level--;
|
||||||
frd->flagv |= AT_BEGINNING; /* the current one is over. move on the beginning for the next expression */
|
frd->flagv |= AT_BEGINNING; /* the current one is over. move on the beginning for the next expression */
|
||||||
list_loc = &frd->list_loc;
|
list_loc = &frd->list_loc;
|
||||||
@ -2027,6 +2029,8 @@ static int feed_process_token (hak_t* hak)
|
|||||||
|
|
||||||
if (!frd->obj) goto oops; /* TODO: this doesn't have to be checked if jump has been made to auto_xlist... so restructure the flow */
|
if (!frd->obj) goto oops; /* TODO: this doesn't have to be checked if jump has been made to auto_xlist... so restructure the flow */
|
||||||
|
|
||||||
|
frd->obj->cn_llvl = frd->level; /* list level */
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* check if the element is read for a quoted list */
|
/* check if the element is read for a quoted list */
|
||||||
while (flagv & QUOTED)
|
while (flagv & QUOTED)
|
||||||
@ -2539,7 +2543,7 @@ static int flx_dollared_ident (hak_t* hak, hak_ooci_t c)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hak_setsynerrbfmt (
|
hak_setsynerrbfmt(
|
||||||
hak, HAK_SYNERR_ILTOK, TOKEN_LOC(hak), HAK_NULL,
|
hak, HAK_SYNERR_ILTOK, TOKEN_LOC(hak), HAK_NULL,
|
||||||
"invalid dollar-prefixed identifier character '%jc' after '%.*js'", c,
|
"invalid dollar-prefixed identifier character '%jc' after '%.*js'", c,
|
||||||
TOKEN_NAME_LEN(hak), TOKEN_NAME_PTR(hak));
|
TOKEN_NAME_LEN(hak), TOKEN_NAME_PTR(hak));
|
||||||
@ -2853,7 +2857,7 @@ static int flx_hmarked_ident (hak_t* hak, hak_ooci_t c)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hak_setsynerrbfmt (
|
hak_setsynerrbfmt(
|
||||||
hak, HAK_SYNERR_ILTOK, TOKEN_LOC(hak), HAK_NULL,
|
hak, HAK_SYNERR_ILTOK, TOKEN_LOC(hak), HAK_NULL,
|
||||||
"invalid symbol character '%jc' after '%.*js'", c,
|
"invalid symbol character '%jc' after '%.*js'", c,
|
||||||
TOKEN_NAME_LEN(hak), TOKEN_NAME_PTR(hak));
|
TOKEN_NAME_LEN(hak), TOKEN_NAME_PTR(hak));
|
||||||
@ -2963,7 +2967,7 @@ static int flx_plain_ident (hak_t* hak, hak_ooci_t c) /* identifier */
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hak_setsynerrbfmt (
|
hak_setsynerrbfmt(
|
||||||
hak, HAK_SYNERR_ILTOK, TOKEN_LOC(hak), HAK_NULL,
|
hak, HAK_SYNERR_ILTOK, TOKEN_LOC(hak), HAK_NULL,
|
||||||
"invalid identifier character '%jc' after '%.*js'", c,
|
"invalid identifier character '%jc' after '%.*js'", c,
|
||||||
TOKEN_NAME_LEN(hak), TOKEN_NAME_PTR(hak));
|
TOKEN_NAME_LEN(hak), TOKEN_NAME_PTR(hak));
|
||||||
|
Reference in New Issue
Block a user