adding code to support class attribute list. work in progress
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
hyung-hwan 2024-10-05 00:05:52 +09:00
parent f4d223f646
commit 3f350dd38a
8 changed files with 190 additions and 43 deletions

View File

@ -2464,6 +2464,132 @@ static HCL_INLINE int compile_else (hcl_t* hcl)
/* ========================================================================= */ /* ========================================================================= */
static int check_class_attr_list (hcl_t* hcl, hcl_cnode_t* attr_list, unsigned int* indexed_type, hcl_cnode_t* cmd, hcl_cnode_t* class_name)
{
static struct
{
const hcl_bch_t* name;
unsigned int flag;
} flag_tab[] = {
{ "v", HCL_CLASS_SPEC_FLAG_INDEXED },
{ "var", HCL_CLASS_SPEC_FLAG_INDEXED },
{ "variable", HCL_CLASS_SPEC_FLAG_INDEXED },
{ "immutable", HCL_CLASS_SPEC_FLAG_IMMUTABLE },
{ "uncopyable", HCL_CLASS_SPEC_FLAG_UNCOPYABLE },
};
static struct
{
const hcl_bch_t* name;
hcl_obj_type_t indexed_type;
} type_tab[] = {
{ "b", HCL_OBJ_TYPE_BYTE },
{ "byte", HCL_OBJ_TYPE_BYTE },
{ "c", HCL_OBJ_TYPE_CHAR },
{ "char", HCL_OBJ_TYPE_CHAR },
{ "character", HCL_OBJ_TYPE_CHAR },
{ "halfword", HCL_OBJ_TYPE_HALFWORD },
{ "hw", HCL_OBJ_TYPE_HALFWORD },
{ "w", HCL_OBJ_TYPE_WORD },
{ "word", HCL_OBJ_TYPE_WORD }
/* TODO: uint32 uint16 .. etc */
};
hcl_obj_type_t ct;
ct = HCL_OBJ_TYPE_OOP;
HCL_ASSERT (hcl, attr_list != HCL_NULL);
HCL_ASSERT (hcl, HCL_CNODE_IS_CONS_CONCODED(attr_list, HCL_CONCODE_XLIST) ||
HCL_CNODE_IS_ELIST_CONCODED(attr_list, HCL_CONCODE_XLIST));
if (HCL_CNODE_IS_ELIST_CONCODED(attr_list, HCL_CONCODE_XLIST))
{
/* don't allow empty attribute list */
if (class_name)
{
hcl_setsynerrbfmt (
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(attr_list), HCL_NULL,
"empty attribute list on '%.*js' for '%.*js'",
HCL_CNODE_GET_TOKLEN(class_name), HCL_CNODE_GET_TOKPTR(class_name),
HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));
}
else
{
hcl_setsynerrbfmt (
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(attr_list), HCL_NULL,
"empty attribute list on unamed class for '%.*js'",
HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));
}
return -1;
}
if (HCL_CNODE_IS_CONS_CONCODED(attr_list, HCL_CONCODE_XLIST))
{
hcl_cnode_t* c, * a;
const hcl_ooch_t* tokptr;
hcl_oow_t toklen, i;
c = attr_list;
while (c)
{
a = HCL_CNODE_CONS_CAR(c);
tokptr = HCL_CNODE_GET_TOKPTR(a);
toklen = HCL_CNODE_GET_TOKLEN(a);
if (!HCL_CNODE_IS_TYPED(a, HCL_CNODE_SYMLIT))
{
hcl_setsynerrbfmt (
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(a), HCL_NULL,
"invalid class attribute name '%.*js'", toklen, tokptr);
return -1;
}
for (i = 0; i < HCL_COUNTOF(flag_tab); i++)
{
if (hcl_comp_oochars_bcstr(tokptr, toklen, flag_tab[i].name) == 0)
{
if ((ct >> 8) & flag_tab[i].flag)
{
conflict:
hcl_setsynerrbfmt (
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(a), HCL_NULL,
"conflicting or duplicate class attribute name '%.*js'", toklen, tokptr);
return -1;
}
ct |= (flag_tab[i].flag << 8);
break;
}
}
if (i >= HCL_COUNTOF(flag_tab))
{
for (i = 0; i < HCL_COUNTOF(type_tab); i++)
{
if (hcl_comp_oochars_bcstr(tokptr, toklen, type_tab[i].name) == 0)
{
if (ct & 0x7F) goto conflict;
ct = type_tab[i].indexed_type;
break;
}
}
if (i >= HCL_COUNTOF(type_tab))
{
hcl_setsynerrbfmt (
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(a), HCL_NULL,
"unrecognized class attribute name '%.*js'", toklen, tokptr);
return -1;
}
}
c = HCL_CNODE_CONS_CDR(c);
}
}
*indexed_type = ct;
return 0;
}
/* /*
(class A (class A
[ x y ] ## instance variables [ x y ] ## instance variables
@ -2495,29 +2621,42 @@ static int compile_class (hcl_t* hcl, hcl_cnode_t* src)
{ {
hcl_cframe_t* cf; hcl_cframe_t* cf;
hcl_cnode_t* cmd, * obj, * tmp; hcl_cnode_t* cmd, * obj, * tmp;
hcl_cnode_t* attr_list;
hcl_cnode_t* class_name, * superclass; hcl_cnode_t* class_name, * superclass;
int nsuperclasses; int nsuperclasses;
unsigned int indexed_type;
cmd = HCL_CNODE_CONS_CAR(src); cmd = HCL_CNODE_CONS_CAR(src);
obj = HCL_CNODE_CONS_CDR(src); obj = HCL_CNODE_CONS_CDR(src);
attr_list = HCL_NULL;
class_name = HCL_NULL; class_name = HCL_NULL;
indexed_type = HCL_OBJ_TYPE_OOP;
HCL_ASSERT (hcl, HCL_CNODE_IS_TYPED(cmd, HCL_CNODE_CLASS)); HCL_ASSERT (hcl, HCL_CNODE_IS_TYPED(cmd, HCL_CNODE_CLASS));
/* TODO: attribute lsit */ if (obj)
if (obj /*&& HCL_CNODE_IS_CONS(obj)*/)
{ {
HCL_ASSERT (hcl, HCL_CNODE_IS_CONS(obj)); HCL_ASSERT (hcl, HCL_CNODE_IS_CONS(obj));
tmp = HCL_CNODE_CONS_CAR(obj); tmp = HCL_CNODE_CONS_CAR(obj);
if (HCL_CNODE_IS_ELIST_CONCODED(tmp, HCL_CONCODE_XLIST) || HCL_CNODE_IS_CONS_CONCODED(tmp, HCL_CONCODE_XLIST))
{
attr_list = tmp;
obj = HCL_CNODE_CONS_CAR(obj) ;
}
}
if (obj)
{
HCL_ASSERT (hcl, HCL_CNODE_IS_CONS(obj));
if (HCL_CNODE_IS_FOR_DATA_SIMPLE(tmp) || HCL_CNODE_IS_FOR_LANG(tmp)) if (HCL_CNODE_IS_FOR_DATA_SIMPLE(tmp) || HCL_CNODE_IS_FOR_LANG(tmp))
{ {
if (!HCL_CNODE_IS_SYMBOL_IDENT(tmp)) if (!HCL_CNODE_IS_SYMBOL_IDENT(tmp))
{ {
hcl_setsynerrbfmt ( hcl_setsynerrbfmt (
hcl, HCL_SYNERR_VARNAME, HCL_CNODE_GET_LOC(tmp), HCL_NULL, hcl, HCL_SYNERR_CLASS, HCL_CNODE_GET_LOC(tmp), HCL_NULL,
"invalid class name '%.*js' for '%.*js'", "invalid class name '%.*js' for '%.*js'",
HCL_CNODE_GET_TOKLEN(tmp), HCL_CNODE_GET_TOKPTR(tmp), HCL_CNODE_GET_TOKLEN(tmp), HCL_CNODE_GET_TOKPTR(tmp),
HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));
@ -2534,19 +2673,23 @@ static int compile_class (hcl_t* hcl, hcl_cnode_t* src)
if (class_name) if (class_name)
{ {
hcl_setsynerrbfmt ( hcl_setsynerrbfmt (
hcl, HCL_SYNERR_BLOCK, HCL_CNODE_GET_LOC(src), HCL_NULL, hcl, HCL_SYNERR_CLASS, HCL_CNODE_GET_LOC(src), HCL_NULL,
"no class body defined for '%.*js'", "incomplete definition of '%.*js' for '%.*js'",
HCL_CNODE_GET_TOKLEN(class_name), HCL_CNODE_GET_TOKPTR(class_name)); HCL_CNODE_GET_TOKLEN(class_name), HCL_CNODE_GET_TOKPTR(class_name),
HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));
} }
else else
{ {
hcl_setsynerrbfmt ( hcl_setsynerrbfmt (
hcl, HCL_SYNERR_BLOCK, HCL_CNODE_GET_LOC(src), HCL_NULL, hcl, HCL_SYNERR_CLASS, HCL_CNODE_GET_LOC(src), HCL_NULL,
"no class body defined for unnamed class"); "incomplete defintion of unnamed class for '%.*js'",
HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));
} }
return -1; return -1;
} }
if (attr_list && check_class_attr_list(hcl, attr_list, &indexed_type, cmd, class_name) <= -1) return -1;
tmp = HCL_CNODE_CONS_CAR(obj); tmp = HCL_CNODE_CONS_CAR(obj);
if (HCL_CNODE_IS_COLON(tmp)) /* check for superclass marker */ if (HCL_CNODE_IS_COLON(tmp)) /* check for superclass marker */
{ {
@ -2557,7 +2700,7 @@ static int compile_class (hcl_t* hcl, hcl_cnode_t* src)
if (!obj || !HCL_CNODE_IS_CONS(obj)) if (!obj || !HCL_CNODE_IS_CONS(obj))
{ {
hcl_setsynerrbfmt ( hcl_setsynerrbfmt (
hcl, HCL_SYNERR_EOX, HCL_CNODE_GET_LOC(marker), HCL_NULL, hcl, HCL_SYNERR_CLASS, HCL_CNODE_GET_LOC(marker), HCL_NULL,
"no expression or declaration after %.*js", "no expression or declaration after %.*js",
HCL_CNODE_GET_TOKLEN(marker), HCL_CNODE_GET_TOKPTR(marker)); HCL_CNODE_GET_TOKLEN(marker), HCL_CNODE_GET_TOKPTR(marker));
return -1; return -1;
@ -2570,7 +2713,7 @@ static int compile_class (hcl_t* hcl, hcl_cnode_t* src)
if (HCL_CNODE_IS_FOR_DATA_SIMPLE(superclass) || HCL_CNODE_IS_FOR_LANG(superclass)) if (HCL_CNODE_IS_FOR_DATA_SIMPLE(superclass) || HCL_CNODE_IS_FOR_LANG(superclass))
{ {
hcl_setsynerrbfmt ( hcl_setsynerrbfmt (
hcl, HCL_SYNERR_NAME, HCL_CNODE_GET_LOC(marker), HCL_NULL, hcl, HCL_SYNERR_CLASS, HCL_CNODE_GET_LOC(marker), HCL_NULL,
"invalid superclass name '%.*js' after '%.*js' for '%.*js'", "invalid superclass name '%.*js' after '%.*js' for '%.*js'",
HCL_CNODE_GET_TOKLEN(superclass), HCL_CNODE_GET_TOKPTR(superclass), HCL_CNODE_GET_TOKLEN(superclass), HCL_CNODE_GET_TOKPTR(superclass),
HCL_CNODE_GET_TOKLEN(marker), HCL_CNODE_GET_TOKPTR(marker), HCL_CNODE_GET_TOKLEN(marker), HCL_CNODE_GET_TOKPTR(marker),
@ -2579,7 +2722,7 @@ static int compile_class (hcl_t* hcl, hcl_cnode_t* src)
else else
{ {
hcl_setsynerrbfmt ( hcl_setsynerrbfmt (
hcl, HCL_SYNERR_NAME, HCL_CNODE_GET_LOC(marker), HCL_NULL, hcl, HCL_SYNERR_CLASS, HCL_CNODE_GET_LOC(marker), HCL_NULL,
"no valid superclass name after '%.*js' for '%.*js'", "no valid superclass name after '%.*js' for '%.*js'",
HCL_CNODE_GET_TOKLEN(marker), HCL_CNODE_GET_TOKPTR(marker), HCL_CNODE_GET_TOKLEN(marker), HCL_CNODE_GET_TOKPTR(marker),
HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));
@ -2631,12 +2774,14 @@ static int compile_class (hcl_t* hcl, hcl_cnode_t* src)
PUSH_CFRAME (hcl, COP_COMPILE_CLASS_P2, class_name); /* 3 - use class name for assignment */ PUSH_CFRAME (hcl, COP_COMPILE_CLASS_P2, class_name); /* 3 - use class name for assignment */
cf = GET_TOP_CFRAME(hcl); cf = GET_TOP_CFRAME(hcl);
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.start_loc = *HCL_CNODE_GET_LOC(src); /* TODO: use *HCL_CNODE_GET_LOC(cmd) instead? */ cf->u._class.start_loc = *HCL_CNODE_GET_LOC(src); /* TODO: use *HCL_CNODE_GET_LOC(cmd) instead? */
cf->u._class.cmd_cnode = cmd; cf->u._class.cmd_cnode = cmd;
PUSH_CFRAME (hcl, COP_COMPILE_CLASS_P1, obj); /* 2 - variables declaraions and actual body */ PUSH_CFRAME (hcl, COP_COMPILE_CLASS_P1, obj); /* 2 - variables declaraions and actual body */
cf = GET_TOP_CFRAME(hcl); cf = GET_TOP_CFRAME(hcl);
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.start_loc = *HCL_CNODE_GET_LOC(src); /* TODO: use *HCL_CNODE_GET_LOC(cmd) instead? */ cf->u._class.start_loc = *HCL_CNODE_GET_LOC(src); /* TODO: use *HCL_CNODE_GET_LOC(cmd) instead? */
cf->u._class.cmd_cnode = cmd; cf->u._class.cmd_cnode = cmd;
@ -2723,6 +2868,7 @@ static HCL_INLINE int compile_class_p1 (hcl_t* hcl)
/* class_enter nsuperclasses, nivars, ncvars */ /* class_enter nsuperclasses, nivars, ncvars */
if (emit_byte_instruction(hcl, HCL_CODE_CLASS_ENTER, &cf->u._class.start_loc) <= -1) goto oops; if (emit_byte_instruction(hcl, HCL_CODE_CLASS_ENTER, &cf->u._class.start_loc) <= -1) goto oops;
if (emit_byte_instruction(hcl, (hcl_oob_t)cf->u._class.indexed_type, &cf->u._class.start_loc) <= -1) goto oops;
if (emit_long_param(hcl, cf->u._class.nsuperclasses) <= -1) goto oops; if (emit_long_param(hcl, cf->u._class.nsuperclasses) <= -1) goto oops;
if (emit_long_param(hcl, vardcl.nivars) <= -1) goto oops; if (emit_long_param(hcl, vardcl.nivars) <= -1) goto oops;
if (emit_long_param(hcl, vardcl.ncvars) <= -1) goto oops; if (emit_long_param(hcl, vardcl.ncvars) <= -1) goto oops;
@ -2799,13 +2945,11 @@ static HCL_INLINE int compile_class_p2 (hcl_t* hcl)
/* ========================================================================= */ /* ========================================================================= */
static int check_fun_attr_list ( static int check_fun_attr_list (hcl_t* hcl, hcl_cnode_t* attr_list, unsigned int* fun_type, hcl_cnode_t* cmd, hcl_cnode_t* class_name, hcl_cnode_t* fun_name)
hcl_t* hcl, hcl_cnode_t* attr_list, unsigned int* fun_type,
hcl_cnode_t* cmd, hcl_cnode_t* class_name, hcl_cnode_t* fun_name)
{ {
unsigned int ft; unsigned int ft;
ft = 0; ft = FUN_IM;
HCL_ASSERT (hcl, attr_list != HCL_NULL); HCL_ASSERT (hcl, attr_list != HCL_NULL);
HCL_ASSERT (hcl, HCL_CNODE_IS_CONS_CONCODED(attr_list, HCL_CONCODE_XLIST) || HCL_ASSERT (hcl, HCL_CNODE_IS_CONS_CONCODED(attr_list, HCL_CONCODE_XLIST) ||
@ -2866,7 +3010,7 @@ static int check_fun_attr_list (
if (hcl_comp_oochars_bcstr(tokptr, toklen, "class") == 0 || if (hcl_comp_oochars_bcstr(tokptr, toklen, "class") == 0 ||
hcl_comp_oochars_bcstr(tokptr, toklen, "c") == 0) hcl_comp_oochars_bcstr(tokptr, toklen, "c") == 0)
{ {
if (ft != 0) if (ft != FUN_IM)
{ {
conflicting: conflicting:
hcl_setsynerrbfmt ( hcl_setsynerrbfmt (
@ -2879,7 +3023,7 @@ static int check_fun_attr_list (
else if (hcl_comp_oochars_bcstr(tokptr, toklen, "classinst") == 0 || else if (hcl_comp_oochars_bcstr(tokptr, toklen, "classinst") == 0 ||
hcl_comp_oochars_bcstr(tokptr, toklen, "ci") == 0) hcl_comp_oochars_bcstr(tokptr, toklen, "ci") == 0)
{ {
if (ft != 0) goto conflicting; if (ft != FUN_IM) goto conflicting;
ft = FUN_CIM; ft = FUN_CIM;
} }
else else
@ -3150,7 +3294,6 @@ static int compile_fun (hcl_t* hcl, hcl_cnode_t* src)
* class X { * class X {
* a := (fun x(){}) ## this context is also class_init_scope. so the check above isn't good enough * a := (fun x(){}) ## this context is also class_init_scope. so the check above isn't good enough
* } */ * } */
fun_type = FUN_IM;
if (check_fun_attr_list(hcl, attr_list, &fun_type, cmd, class_name, fun_name) <= -1) return -1; if (check_fun_attr_list(hcl, attr_list, &fun_type, cmd, class_name, fun_name) <= -1) return -1;
if (class_name) fun_type |= 0x100; /* defined in `fun class:xxx` style outside class */ if (class_name) fun_type |= 0x100; /* defined in `fun class:xxx` style outside class */
} }
@ -3177,7 +3320,7 @@ static int compile_fun (hcl_t* hcl, hcl_cnode_t* src)
{ {
if (is_in_class_init_scope(hcl) || class_name) if (is_in_class_init_scope(hcl) || class_name)
{ {
fun_type = FUN_IM; fun_type = FUN_IM;
if (class_name) fun_type |= 0x100; if (class_name) fun_type |= 0x100;
} }
} }
@ -5163,13 +5306,7 @@ redo:
goto redo; goto redo;
case HCL_CNODE_ELLIPSIS: case HCL_CNODE_ELLIPSIS:
hcl_setsynerrbfmt (hcl, HCL_SYNERR_ELLIPSISBANNED, HCL_CNODE_GET_LOC(oprnd), HCL_CNODE_GET_TOK(oprnd), "ellipsis disallowed in this context", HCL_CNODE_GET_TYPE(oprnd));
return -1;
case HCL_CNODE_TRPCOLONS: case HCL_CNODE_TRPCOLONS:
hcl_setsynerrbfmt (hcl, HCL_SYNERR_TRPCOLONSBANNED, HCL_CNODE_GET_LOC(oprnd), HCL_CNODE_GET_TOK(oprnd), "triple colons disallowed in this context", HCL_CNODE_GET_TYPE(oprnd));
return -1;
case HCL_CNODE_DBLCOLONS: case HCL_CNODE_DBLCOLONS:
case HCL_CNODE_COLON: case HCL_CNODE_COLON:
case HCL_CNODE_COLONLT: case HCL_CNODE_COLONLT:

View File

@ -379,13 +379,13 @@ int hcl_decode (hcl_t* hcl, const hcl_code_t* code, hcl_oow_t start, hcl_oow_t e
case HCL_CODE_CLASS_ENTER: case HCL_CODE_CLASS_ENTER:
{ {
hcl_oow_t b3; hcl_oow_t b0, b3;
FETCH_BYTE_CODE_TO (hcl, b0);
FETCH_PARAM_CODE_TO (hcl, b1); FETCH_PARAM_CODE_TO (hcl, b1);
FETCH_PARAM_CODE_TO (hcl, b2); FETCH_PARAM_CODE_TO (hcl, b2);
FETCH_PARAM_CODE_TO (hcl, b3); FETCH_PARAM_CODE_TO (hcl, b3);
LOG_INST_3 (hcl, "class_enter %zu %zu %zu", b1, b2, b3); LOG_INST_4 (hcl, "class_enter %zu %zu %zu %zu", b0, b1, b2, b3);
break; break;
} }

View File

@ -110,7 +110,6 @@ static const char* synerrstr[] =
"invalid radix for a numeric literal", "invalid radix for a numeric literal",
"sudden end of input", "sudden end of input",
"sudden end of expression",
"( expected", "( expected",
") expected", ") expected",
"] expected", "] expected",
@ -139,7 +138,6 @@ static const char* synerrstr[] =
"if body too big", "if body too big",
"block too big", "block too big",
"block too deep", "block too deep",
"name expected",
"argument name list expected", "argument name list expected",
"argument name expected", "argument name expected",
"duplicate argument name", "duplicate argument name",
@ -155,6 +153,7 @@ static const char* synerrstr[] =
"disallowed argument name", "disallowed argument name",
"disallowed", "disallowed",
"invalid class definition",
"invalid function definition", "invalid function definition",
"elif without if", "elif without if",
"else without if", "else without if",

View File

@ -4032,18 +4032,19 @@ static int execute (hcl_t* hcl)
push superclass (only if nsuperclassses > 0) push superclass (only if nsuperclassses > 0)
push ivars_string push ivars_string
push cvars_string push cvars_string
class_enter nsuperclasses nivars ncvars class_enter indexed_type nsuperclasses nivars ncvars
*/ */
hcl_oop_t superclass, ivars_str, cvars_str, class_name; hcl_oop_t superclass, ivars_str, cvars_str, class_name;
hcl_oop_t v; hcl_oop_t v;
hcl_oop_class_t class_obj; hcl_oop_class_t class_obj;
hcl_oow_t b3; hcl_oow_t b0, b3;
FETCH_BYTE_CODE_TO (hcl, b0); /* indexed_type */
FETCH_PARAM_CODE_TO (hcl, b1); /* nsuperclasses */ FETCH_PARAM_CODE_TO (hcl, b1); /* nsuperclasses */
FETCH_PARAM_CODE_TO (hcl, b2); /* nivars */ FETCH_PARAM_CODE_TO (hcl, b2); /* nivars */
FETCH_PARAM_CODE_TO (hcl, b3); /* ncvars */ FETCH_PARAM_CODE_TO (hcl, b3); /* ncvars */
LOG_INST_3 (hcl, "class_enter %zu %zu %zu", b1, b2, b3); LOG_INST_4 (hcl, "class_enter %zu %zu %zu %zu", b0, b1, b2, b3);
if (b3 > 0) if (b3 > 0)
{ {
@ -4073,7 +4074,6 @@ static int execute (hcl_t* hcl)
HCL_STACK_POP_TO(hcl, v); HCL_STACK_POP_TO(hcl, v);
//////////////
if (HCL_IS_CONS(hcl, v)) if (HCL_IS_CONS(hcl, v))
{ {
/* named class. the compiler generates code to push a pair holding /* named class. the compiler generates code to push a pair holding
@ -4091,15 +4091,22 @@ static int execute (hcl_t* hcl)
{ {
/* check if the new definition is compatible with kernel definition */ /* check if the new definition is compatible with kernel definition */
hcl_ooi_t spec, selfspec, nivars_super, nivars_super_real; hcl_ooi_t spec, selfspec, nivars_super, nivars_super_real;
hcl_obj_type_t indexed_type;
spec = HCL_OOP_TO_SMOOI(class_obj->spec); spec = HCL_OOP_TO_SMOOI(class_obj->spec);
selfspec = HCL_OOP_TO_SMOOI(class_obj->selfspec); selfspec = HCL_OOP_TO_SMOOI(class_obj->selfspec);
nivars_super = HCL_OOP_TO_SMOOI(class_obj->nivars_super); nivars_super = HCL_OOP_TO_SMOOI(class_obj->nivars_super);
nivars_super_real = HCL_IS_NIL(hcl, superclass)? 0: HCL_OOP_TO_SMOOI(((hcl_oop_class_t)superclass)->nivars_super); nivars_super_real = HCL_IS_NIL(hcl, superclass)? 0: HCL_OOP_TO_SMOOI(((hcl_oop_class_t)superclass)->nivars_super);
//if (HCL_CLASS_SPEC_IS_INDEXED(spec))
//indexed_type = (hcl_obj_type_t)HCL_CLASS_SPEC_INDEXED_TYPE(spec);
#if 0 #if 0
hcl_logbfmt (hcl, HCL_LOG_STDERR, ">>>%O c->sc=%O sc=%O b2=%d b3=%d nivars=%d ncvars=%d<<<\n", class_obj, class_obj->superclass, superclass, b2, b3, (int)HCL_CLASS_SPEC_NAMED_INSTVARS(spec), (int)HCL_CLASS_SELFSPEC_CLASSVARS(spec)); hcl_logbfmt (hcl, HCL_LOG_STDERR, ">>>%O c->sc=%O sc=%O b2=%d b3=%d nivars=%d ncvars=%d<<<\n", class_obj, class_obj->superclass, superclass, b2, b3, (int)HCL_CLASS_SPEC_NAMED_INSTVARS(spec), (int)HCL_CLASS_SELFSPEC_CLASSVARS(spec));
#endif #endif
if (class_obj->superclass != superclass || HCL_CLASS_SPEC_NAMED_INSTVARS(spec) != b2 || HCL_CLASS_SELFSPEC_CLASSVARS(selfspec) != b3 || nivars_super != nivars_super_real)
if (class_obj->superclass != superclass ||
HCL_CLASS_SPEC_NAMED_INSTVARS(spec) != b2 ||
HCL_CLASS_SELFSPEC_CLASSVARS(selfspec) != b3 ||
nivars_super != nivars_super_real)
{ {
hcl_seterrbfmt (hcl, HCL_EPERM, "incompatible redefintion of %.*js", HCL_OBJ_GET_SIZE(class_name), HCL_OBJ_GET_CHAR_SLOT(class_name)); hcl_seterrbfmt (hcl, HCL_EPERM, "incompatible redefintion of %.*js", HCL_OBJ_GET_SIZE(class_name), HCL_OBJ_GET_CHAR_SLOT(class_name));
if (do_throw_with_internal_errmsg(hcl, fetched_instruction_pointer) >= 0) break; if (do_throw_with_internal_errmsg(hcl, fetched_instruction_pointer) >= 0) break;
@ -4129,7 +4136,6 @@ hcl_logbfmt (hcl, HCL_LOG_STDERR, ">>>%O c->sc=%O sc=%O b2=%d b3=%d nivars=%d nc
class_obj = (hcl_oop_class_t)hcl_makeclass(hcl, class_name, superclass, b2, b3, ivars_str, cvars_str); class_obj = (hcl_oop_class_t)hcl_makeclass(hcl, class_name, superclass, b2, b3, ivars_str, cvars_str);
if (HCL_UNLIKELY(!class_obj)) goto oops_with_errmsg_supplement; if (HCL_UNLIKELY(!class_obj)) goto oops_with_errmsg_supplement;
} }
//////////////
/* push the class created to the class stack. but don't push to the normal operation stack */ /* push the class created to the class stack. but don't push to the normal operation stack */
HCL_CLSTACK_PUSH (hcl, (hcl_oop_t)class_obj); HCL_CLSTACK_PUSH (hcl, (hcl_oop_t)class_obj);
@ -5019,7 +5025,7 @@ hcl_oop_t hcl_execute (hcl_t* hcl)
HCL_ASSERT (hcl, hcl->code.bc.ptr[hcl->code.bc.len - 1] == HCL_CODE_POP_STACKTOP); HCL_ASSERT (hcl, hcl->code.bc.ptr[hcl->code.bc.len - 1] == HCL_CODE_POP_STACKTOP);
#if 1 #if 1
/* append RETURN_FROM_BLOCK /* append RETURN_FROM_BLOCK
if (hcl_emitbyteinstruction(hcl, HCL_CODE_RETURN_FROM_BLOCK) <= -1) return -1;*/ * if (hcl_emitbyteinstruction(hcl, HCL_CODE_RETURN_FROM_BLOCK) <= -1) return -1;*/
/* substitute RETURN_FROM_BLOCK for POP_STACKTOP) */ /* substitute RETURN_FROM_BLOCK for POP_STACKTOP) */
hcl->code.bc.ptr[hcl->code.bc.len - 1] = HCL_CODE_RETURN_FROM_BLOCK; hcl->code.bc.ptr[hcl->code.bc.len - 1] = HCL_CODE_RETURN_FROM_BLOCK;
#else #else

View File

@ -677,6 +677,7 @@ struct hcl_cframe_t
struct struct
{ {
hcl_ooi_t nsuperclasses; hcl_ooi_t nsuperclasses;
unsigned int indexed_type;
hcl_loc_t start_loc; hcl_loc_t start_loc;
hcl_cnode_t* cmd_cnode; hcl_cnode_t* cmd_cnode;
} _class; } _class;

View File

@ -114,7 +114,6 @@ enum hcl_synerrnum_t
HCL_SYNERR_RADIX, /* invalid radix for a numeric literal */ HCL_SYNERR_RADIX, /* invalid radix for a numeric literal */
HCL_SYNERR_EOF, /* sudden end of input */ HCL_SYNERR_EOF, /* sudden end of input */
HCL_SYNERR_EOX, /* sudden end of expression */
HCL_SYNERR_LPAREN, /* ( expected */ HCL_SYNERR_LPAREN, /* ( expected */
HCL_SYNERR_RPAREN, /* ) expected */ HCL_SYNERR_RPAREN, /* ) expected */
HCL_SYNERR_RBRACK, /* ] expected */ HCL_SYNERR_RBRACK, /* ] expected */
@ -143,7 +142,6 @@ enum hcl_synerrnum_t
HCL_SYNERR_IFFLOOD, /* if body too big */ HCL_SYNERR_IFFLOOD, /* if body too big */
HCL_SYNERR_BLKFLOOD, /* block too big */ HCL_SYNERR_BLKFLOOD, /* block too big */
HCL_SYNERR_BLKDEPTH, /* block too deep */ HCL_SYNERR_BLKDEPTH, /* block too deep */
HCL_SYNERR_NAME, /* name expected */
HCL_SYNERR_ARGNAMELIST, /* argument name list expected */ HCL_SYNERR_ARGNAMELIST, /* argument name list expected */
HCL_SYNERR_ARGNAME, /* argument name expected */ HCL_SYNERR_ARGNAME, /* argument name expected */
HCL_SYNERR_ARGNAMEDUP, /* duplicate argument name */ HCL_SYNERR_ARGNAMEDUP, /* duplicate argument name */
@ -159,6 +157,7 @@ enum hcl_synerrnum_t
HCL_SYNERR_BANNEDARGNAME, /* disallowed argument name */ HCL_SYNERR_BANNEDARGNAME, /* disallowed argument name */
HCL_SYNERR_BANNED, /* prohibited */ HCL_SYNERR_BANNED, /* prohibited */
HCL_SYNERR_CLASS, /* invalid class definition */
HCL_SYNERR_FUN, /* invalid function definition */ HCL_SYNERR_FUN, /* invalid function definition */
HCL_SYNERR_ELIF, /* elif without if */ HCL_SYNERR_ELIF, /* elif without if */
HCL_SYNERR_ELSE, /* else without if */ HCL_SYNERR_ELSE, /* else without if */

View File

@ -893,7 +893,8 @@ static HCL_INLINE int can_colon_list (hcl_t* hcl)
if (rstl->count <= 0) return 0; /* not allowed at the list beginning */ if (rstl->count <= 0) return 0; /* not allowed at the list beginning */
/* mark the state that a colon has appeared in the list */ /* mark the state that a colon has appeared in the list */
if (HCL_CNODE_IS_TYPED(HCL_CNODE_CONS_CAR(rstl->head), HCL_CNODE_CLASS)) /*if (HCL_CNODE_IS_TYPED(HCL_CNODE_CONS_CAR(rstl->head), HCL_CNODE_CLASS))*/
if (HCL_CNODE_IS_FOR_LANG(HCL_CNODE_CONS_CAR(rstl->head)))
{ {
/* class :superclassame ... /* class :superclassame ...
* class name:superclassname ... */ * class name:superclassname ... */
@ -903,6 +904,9 @@ static HCL_INLINE int can_colon_list (hcl_t* hcl)
if (rstl->count == 1) rstl->flagv |= JSON; /* mark that the first key is colon-delimited */ if (rstl->count == 1) rstl->flagv |= JSON; /* mark that the first key is colon-delimited */
else if (!(rstl->flagv & JSON)) else if (!(rstl->flagv & JSON))
{ {
#if 0
/* this strict check is not needed as it returns 2 above if the first element is a language keyword element */
/* handling of a colon sign in out-of-class instance method definition. /* handling of a colon sign in out-of-class instance method definition.
* e.g. fun String:length() { return (str.length self). } * e.g. fun String:length() { return (str.length self). }
* TODO: inject a symbol ':' to differentiate form '::' or ':*' methods. * TODO: inject a symbol ':' to differentiate form '::' or ':*' methods.
@ -933,6 +937,7 @@ static HCL_INLINE int can_colon_list (hcl_t* hcl)
} }
} }
} }
#endif
return 0; /* the first key is not colon-delimited. so not allowed to colon-delimit other keys */ return 0; /* the first key is not colon-delimited. so not allowed to colon-delimit other keys */
} }

View File

@ -1,8 +1,8 @@
class ##ERROR: syntax error - no class body class ##ERROR: syntax error - incomplete defintion of unnamed class for 'class'
--- ---
class B ##ERROR: syntax error - no class body class B ##ERROR: syntax error - incomplete definition of 'B' for 'class'
--- ---