enhanced compile_class_attr_list() with data table and binary search
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
86d9a137c8
commit
42009d3cce
158
lib/comp.c
158
lib/comp.c
@ -2469,29 +2469,43 @@ static int check_class_attr_list (hcl_t* hcl, hcl_cnode_t* attr_list, unsigned i
|
|||||||
static struct
|
static struct
|
||||||
{
|
{
|
||||||
const hcl_bch_t* name;
|
const hcl_bch_t* name;
|
||||||
unsigned int flag;
|
int shifts;
|
||||||
} flag_tab[] = {
|
unsigned int mask;
|
||||||
{ "v", HCL_CLASS_SPEC_FLAG_INDEXED },
|
unsigned int value;
|
||||||
{ "var", HCL_CLASS_SPEC_FLAG_INDEXED },
|
} attr_tab[] = {
|
||||||
{ "varying", HCL_CLASS_SPEC_FLAG_INDEXED },
|
/* the value with 0xFF in the mask field takes up the whole byte
|
||||||
{ "immutable", HCL_CLASS_SPEC_FLAG_IMMUTABLE },
|
* the value with 0x00 in the mask field is a bit value.
|
||||||
{ "uncopyable", HCL_CLASS_SPEC_FLAG_UNCOPYABLE },
|
*
|
||||||
};
|
* shifts: 0 for object type, 8 for selfspec bit, 12 for spec bit
|
||||||
|
* mask: 0xFF for object type, 0x00 for spec/selfspec bit.
|
||||||
|
*
|
||||||
|
* keep the table sorted in alphabestical order ascending for
|
||||||
|
* binary search */
|
||||||
|
|
||||||
|
{ "b", 0, 0xFF, HCL_OBJ_TYPE_BYTE },
|
||||||
|
{ "byte", 0, 0xFF, HCL_OBJ_TYPE_BYTE },
|
||||||
|
{ "c", 0, 0xFF, HCL_OBJ_TYPE_CHAR },
|
||||||
|
{ "char", 0, 0xFF, HCL_OBJ_TYPE_CHAR },
|
||||||
|
{ "character", 0, 0xFF, HCL_OBJ_TYPE_CHAR },
|
||||||
|
|
||||||
|
{ "final", 8, 0x00, HCL_CLASS_SELFSPEC_FLAG_FINAL },
|
||||||
|
|
||||||
|
{ "halfword", 0, 0xFF, HCL_OBJ_TYPE_HALFWORD },
|
||||||
|
{ "hw", 0, 0xFF, HCL_OBJ_TYPE_HALFWORD },
|
||||||
|
|
||||||
|
{ "immutable", 12, 0x00, HCL_CLASS_SPEC_FLAG_IMMUTABLE },
|
||||||
|
|
||||||
|
{ "limited", 8, 0x00, HCL_CLASS_SELFSPEC_FLAG_LIMITED },
|
||||||
|
|
||||||
|
{ "uncopyable", 12, 0x00, HCL_CLASS_SPEC_FLAG_UNCOPYABLE },
|
||||||
|
|
||||||
|
{ "v", 12, 0x00, HCL_CLASS_SPEC_FLAG_INDEXED },
|
||||||
|
{ "var", 12, 0x00, HCL_CLASS_SPEC_FLAG_INDEXED },
|
||||||
|
{ "varying", 12, 0x00, HCL_CLASS_SPEC_FLAG_INDEXED },
|
||||||
|
|
||||||
|
{ "w", 0, 0xFF, HCL_OBJ_TYPE_WORD },
|
||||||
|
{ "word", 0, 0xFF, HCL_OBJ_TYPE_WORD }
|
||||||
|
|
||||||
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 */
|
/* TODO: uint32 uint16 .. etc */
|
||||||
};
|
};
|
||||||
hcl_obj_type_t ct;
|
hcl_obj_type_t ct;
|
||||||
@ -2517,7 +2531,7 @@ static int check_class_attr_list (hcl_t* hcl, hcl_cnode_t* attr_list, unsigned i
|
|||||||
{
|
{
|
||||||
hcl_setsynerrbfmt (
|
hcl_setsynerrbfmt (
|
||||||
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(attr_list), HCL_NULL,
|
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(attr_list), HCL_NULL,
|
||||||
"empty attribute list on unamed class for '%.*js'",
|
"empty attribute list on unnamed class for '%.*js'",
|
||||||
HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));
|
HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@ -2525,69 +2539,78 @@ static int check_class_attr_list (hcl_t* hcl, hcl_cnode_t* attr_list, unsigned i
|
|||||||
|
|
||||||
if (HCL_CNODE_IS_CONS_CONCODED(attr_list, HCL_CONCODE_XLIST))
|
if (HCL_CNODE_IS_CONS_CONCODED(attr_list, HCL_CONCODE_XLIST))
|
||||||
{
|
{
|
||||||
hcl_cnode_t* c, * a;
|
hcl_cnode_t* c;
|
||||||
const hcl_ooch_t* tokptr;
|
const hcl_ooch_t* tokptr;
|
||||||
hcl_oow_t toklen, i;
|
hcl_oow_t toklen;
|
||||||
|
|
||||||
c = attr_list;
|
c = attr_list;
|
||||||
while (c)
|
while (c)
|
||||||
{
|
{
|
||||||
a = HCL_CNODE_CONS_CAR(c);
|
/* [NOTE] this algorithm is underflow safe with hcl_oow_t types */
|
||||||
|
hcl_oow_t base, lim;
|
||||||
|
hcl_cnode_t* attr;
|
||||||
|
|
||||||
tokptr = HCL_CNODE_GET_TOKPTR(a);
|
attr = HCL_CNODE_CONS_CAR(c);
|
||||||
toklen = HCL_CNODE_GET_TOKLEN(a);
|
|
||||||
|
|
||||||
if (!HCL_CNODE_IS_TYPED(a, HCL_CNODE_SYMLIT))
|
tokptr = HCL_CNODE_GET_TOKPTR(attr);
|
||||||
|
toklen = HCL_CNODE_GET_TOKLEN(attr);
|
||||||
|
|
||||||
|
if (!HCL_CNODE_IS_TYPED(attr, HCL_CNODE_SYMLIT))
|
||||||
{
|
{
|
||||||
hcl_setsynerrbfmt (
|
hcl_setsynerrbfmt (
|
||||||
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(a), HCL_NULL,
|
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(attr), HCL_NULL,
|
||||||
"invalid class attribute name '%.*js'", toklen, tokptr);
|
"invalid class attribute name '%.*js'", toklen, tokptr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* upper 4 bits: object flags - only 4 bit flags are possible
|
* 4 bits for spec flags (bit 12 .. 15)
|
||||||
* lower 4 bits: object type for indexing/variablilty - 16 different combinations are possible
|
* 4 bits for selfspec flags (bit 8 .. 11)
|
||||||
* these are kept as compact as possbile to make use a single byte in encoding this information
|
* 8 bits for object type for indexing/variablility (bit 0 .. 7)
|
||||||
* for the bytecode instruction CLASS_ENTER
|
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < HCL_COUNTOF(flag_tab); i++)
|
|
||||||
|
for (base = 0, lim = HCL_COUNTOF(attr_tab); lim > 0; lim >>= 1) /* binary search */
|
||||||
{
|
{
|
||||||
if (hcl_comp_oochars_bcstr(tokptr, toklen, flag_tab[i].name) == 0)
|
hcl_oow_t i;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
i = base + (lim >> 1); /* mid-point */
|
||||||
|
n = hcl_comp_oochars_bcstr(tokptr, toklen, attr_tab[i].name);
|
||||||
|
if (n == 0)
|
||||||
{
|
{
|
||||||
if ((ct >> 4) & flag_tab[i].flag)
|
/* this is to derive the real mask: (attr_tab[i].mask | attr_tab[i].value).
|
||||||
|
* roughly speaking, it's similary to
|
||||||
|
* real_mask = attr_tab[i].mask == 0? attr_tab[i].value: attr_tab[i].mask;
|
||||||
|
*
|
||||||
|
* To flag out duplicate or conflicting attribute, we check if
|
||||||
|
* - the same bit is already set for a bit-based item (mask field 0x00).
|
||||||
|
* - a value is non-zero for a byte-based item (mask field 0xFF)
|
||||||
|
*/
|
||||||
|
if (!!((ct >> attr_tab[i].shifts) & (attr_tab[i].mask | attr_tab[i].value)))
|
||||||
{
|
{
|
||||||
conflict:
|
|
||||||
hcl_setsynerrbfmt (
|
hcl_setsynerrbfmt (
|
||||||
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(a), HCL_NULL,
|
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(attr), HCL_NULL,
|
||||||
"conflicting or duplicate class attribute name '%.*js'", toklen, tokptr);
|
"conflicting or duplicate class attribute name '#%.*js'", toklen, tokptr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ct |= (flag_tab[i].flag << 4);
|
|
||||||
break;
|
ct &= ~attr_tab[i].mask;
|
||||||
|
ct |= (attr_tab[i].value << attr_tab[i].shifts);
|
||||||
|
goto found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (n > 0) { base = i + 1; lim--; }
|
||||||
}
|
}
|
||||||
if (i >= HCL_COUNTOF(flag_tab))
|
|
||||||
|
if (lim <= 0)
|
||||||
{
|
{
|
||||||
for (i = 0; i < HCL_COUNTOF(type_tab); i++)
|
hcl_setsynerrbfmt (
|
||||||
{
|
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(attr), HCL_NULL,
|
||||||
if (hcl_comp_oochars_bcstr(tokptr, toklen, type_tab[i].name) == 0)
|
"unrecognized class attribute name '%.*js'", toklen, tokptr);
|
||||||
{
|
return -1;
|
||||||
if (ct & 0x0F) 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
found:
|
||||||
c = HCL_CNODE_CONS_CDR(c);
|
c = HCL_CNODE_CONS_CDR(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2878,10 +2901,11 @@ 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;
|
||||||
|
if (emit_byte_instruction(hcl, (hcl_oob_t)((cf->u._class.indexed_type >> 8) & 0xFF), &cf->u._class.start_loc) <= -1) goto oops;
|
||||||
|
if (emit_byte_instruction(hcl, (hcl_oob_t)(cf->u._class.indexed_type & 0xFF), &cf->u._class.start_loc) <= -1) goto oops;
|
||||||
|
|
||||||
/* remember the first byte code position to be emitted for the body of
|
/* remember the first byte code position to be emitted for the body of
|
||||||
* this class. this posistion is used for empty class body check at the
|
* this class. this posistion is used for empty class body check at the
|
||||||
@ -2989,7 +3013,7 @@ static int check_fun_attr_list (hcl_t* hcl, hcl_cnode_t* attr_list, unsigned int
|
|||||||
{
|
{
|
||||||
hcl_setsynerrbfmt (
|
hcl_setsynerrbfmt (
|
||||||
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(attr_list), HCL_NULL,
|
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(attr_list), HCL_NULL,
|
||||||
"empty attribute list on unamed function for '%.*js'",
|
"empty attribute list on unnamed function for '%.*js'",
|
||||||
HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));
|
HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@ -3025,7 +3049,7 @@ static int check_fun_attr_list (hcl_t* hcl, hcl_cnode_t* attr_list, unsigned int
|
|||||||
conflicting:
|
conflicting:
|
||||||
hcl_setsynerrbfmt (
|
hcl_setsynerrbfmt (
|
||||||
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(a), HCL_NULL,
|
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(a), HCL_NULL,
|
||||||
"conflicting function attribute name '%.*js'", toklen, tokptr);
|
"conflicting function attribute name '#%.*js'", toklen, tokptr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ft = FUN_CM;
|
ft = FUN_CM;
|
||||||
@ -3091,7 +3115,7 @@ static int compile_fun (hcl_t* hcl, hcl_cnode_t* src)
|
|||||||
/* fun (arg..)
|
/* fun (arg..)
|
||||||
* fun name(arg..)
|
* fun name(arg..)
|
||||||
* fun(#attr..) name(arg..) ## valid as class method, not valid as plain function
|
* fun(#attr..) name(arg..) ## valid as class method, not valid as plain function
|
||||||
* fun(#attr..) (arg..) ## not valid. not attribute list for unamed functions
|
* fun(#attr..) (arg..) ## not valid. not attribute list for unnamed functions
|
||||||
* fun(#attr..) class:name(arg..)
|
* fun(#attr..) class:name(arg..)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -3205,7 +3229,7 @@ static int compile_fun (hcl_t* hcl, hcl_cnode_t* src)
|
|||||||
* another hack is to disallow ELIST as attribute list? */
|
* another hack is to disallow ELIST as attribute list? */
|
||||||
hcl_setsynerrbfmt (
|
hcl_setsynerrbfmt (
|
||||||
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(cmd), HCL_NULL,
|
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(cmd), HCL_NULL,
|
||||||
"unamed function not followed by function body for '%.*js'",
|
"unnamed function not followed by function body for '%.*js'",
|
||||||
HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));
|
HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -3230,7 +3254,7 @@ static int compile_fun (hcl_t* hcl, hcl_cnode_t* src)
|
|||||||
{
|
{
|
||||||
hcl_setsynerrbfmt (
|
hcl_setsynerrbfmt (
|
||||||
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(cmd), HCL_NULL,
|
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(cmd), HCL_NULL,
|
||||||
"no function body after attribute list and argument list of unamed function for '%.*js'",
|
"no function body after attribute list and argument list of unnamed function for '%.*js'",
|
||||||
HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));
|
HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -3320,7 +3344,7 @@ static int compile_fun (hcl_t* hcl, hcl_cnode_t* src)
|
|||||||
{
|
{
|
||||||
hcl_setsynerrbfmt (
|
hcl_setsynerrbfmt (
|
||||||
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(attr_list), HCL_NULL,
|
hcl, HCL_SYNERR_FUN, HCL_CNODE_GET_LOC(attr_list), HCL_NULL,
|
||||||
"attribute list prohibited on unamed function for '%.*js'",
|
"attribute list prohibited on unnamed function for '%.*js'",
|
||||||
HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));
|
HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd));
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -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 b0, b3;
|
hcl_oow_t b3, b4, b5;
|
||||||
|
|
||||||
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_4 (hcl, "class_enter %zu %zu %zu %zu", b0, b1, b2, b3);
|
FETCH_BYTE_CODE_TO (hcl, b4); /* spec/selfspec */
|
||||||
|
FETCH_BYTE_CODE_TO (hcl, b5); /* indexed_type */
|
||||||
|
LOG_INST_5 (hcl, "class_enter %zu %zu %zu %#zx %zu", b1, b2, b3, b4, b5);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
lib/exec.c
12
lib/exec.c
@ -4037,14 +4037,15 @@ static int execute (hcl_t* hcl)
|
|||||||
hcl_oop_t superclass, ivars_str, cvars_str, class_name, v;
|
hcl_oop_t superclass, ivars_str, cvars_str, class_name, v;
|
||||||
hcl_ooi_t expected_spec, expected_selfspec;
|
hcl_ooi_t expected_spec, expected_selfspec;
|
||||||
hcl_oop_class_t class_obj;
|
hcl_oop_class_t class_obj;
|
||||||
hcl_oow_t b0, b3;
|
hcl_oow_t b3, b4, b5;
|
||||||
|
|
||||||
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 */
|
||||||
|
FETCH_BYTE_CODE_TO (hcl, b4); /* spec/selfspec */
|
||||||
|
FETCH_BYTE_CODE_TO (hcl, b5); /* indexed_type */
|
||||||
|
|
||||||
LOG_INST_4 (hcl, "class_enter %zu %zu %zu %zu", b0, b1, b2, b3);
|
LOG_INST_5 (hcl, "class_enter %zu %zu %zu %#zx %zu", b1, b2, b3, b4, b5);
|
||||||
|
|
||||||
if (b3 > 0)
|
if (b3 > 0)
|
||||||
{
|
{
|
||||||
@ -4072,8 +4073,8 @@ static int execute (hcl_t* hcl)
|
|||||||
}
|
}
|
||||||
else superclass = hcl->_nil;
|
else superclass = hcl->_nil;
|
||||||
|
|
||||||
expected_spec = HCL_CLASS_SPEC_MAKE(b2, (b0 >> 4), b0 & 0x0F);
|
expected_spec = HCL_CLASS_SPEC_MAKE(b2, ((b4 >> 4) & 0x0F), (b5 & 0xFF));
|
||||||
expected_selfspec = HCL_CLASS_SELFSPEC_MAKE(b3, 0, 0);
|
expected_selfspec = HCL_CLASS_SELFSPEC_MAKE(b3, 0, (b4 & 0x0F));
|
||||||
|
|
||||||
HCL_STACK_POP_TO(hcl, v);
|
HCL_STACK_POP_TO(hcl, v);
|
||||||
if (HCL_IS_CONS(hcl, v))
|
if (HCL_IS_CONS(hcl, v))
|
||||||
@ -4102,6 +4103,7 @@ static int execute (hcl_t* hcl)
|
|||||||
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
|
||||||
|
|
||||||
|
hcl_logbfmt (hcl, HCL_LOG_STDERR, " spec %d %d | selfspec %d %d\n", expected_spec, spec, expected_selfspec, selfspec);
|
||||||
if (class_obj->superclass != superclass ||
|
if (class_obj->superclass != superclass ||
|
||||||
expected_spec != spec ||
|
expected_spec != spec ||
|
||||||
expected_selfspec != selfspec ||
|
expected_selfspec != selfspec ||
|
||||||
|
2
lib/gc.c
2
lib/gc.c
@ -166,7 +166,7 @@ static kernel_class_info_t kernel_classes[__KCI_MAX__] =
|
|||||||
"Class",
|
"Class",
|
||||||
KCI_APEX,
|
KCI_APEX,
|
||||||
HCL_BRAND_CLASS,
|
HCL_BRAND_CLASS,
|
||||||
HCL_CLASS_SELFSPEC_FLAG_LIMITED,
|
HCL_CLASS_SELFSPEC_FLAG_FINAL | HCL_CLASS_SELFSPEC_FLAG_LIMITED,
|
||||||
0, /* ncvars */
|
0, /* ncvars */
|
||||||
HCL_CLASS_NAMED_INSTVARS, /* nivars */
|
HCL_CLASS_NAMED_INSTVARS, /* nivars */
|
||||||
HCL_CLASS_SPEC_FLAG_INDEXED | HCL_CLASS_SPEC_FLAG_UNCOPYABLE,
|
HCL_CLASS_SPEC_FLAG_INDEXED | HCL_CLASS_SPEC_FLAG_UNCOPYABLE,
|
||||||
|
@ -210,6 +210,8 @@
|
|||||||
#define HCL_CLASS_SPEC_INDEXED_TYPE(spec) \
|
#define HCL_CLASS_SPEC_INDEXED_TYPE(spec) \
|
||||||
((((hcl_oow_t)(spec)) >> HCL_CLASS_SPEC_FLAG_BITS) & HCL_LBMASK(hcl_oow_t, HCL_OBJ_FLAGS_TYPE_BITS))
|
((((hcl_oow_t)(spec)) >> HCL_CLASS_SPEC_FLAG_BITS) & HCL_LBMASK(hcl_oow_t, HCL_OBJ_FLAGS_TYPE_BITS))
|
||||||
|
|
||||||
|
/* If you add more than 4 items, you must update code related to CLASS_ENTER instruction
|
||||||
|
* and class attributes as well as HCL_CLASS_SPEC_FLAG_BITS. */
|
||||||
#define HCL_CLASS_SPEC_FLAG_INDEXED (1 << 0)
|
#define HCL_CLASS_SPEC_FLAG_INDEXED (1 << 0)
|
||||||
#define HCL_CLASS_SPEC_FLAG_IMMUTABLE (1 << 1)
|
#define HCL_CLASS_SPEC_FLAG_IMMUTABLE (1 << 1)
|
||||||
#define HCL_CLASS_SPEC_FLAG_UNCOPYABLE (1 << 2)
|
#define HCL_CLASS_SPEC_FLAG_UNCOPYABLE (1 << 2)
|
||||||
@ -260,6 +262,8 @@
|
|||||||
#define HCL_CLASS_SELFSPEC_FLAGS(spec) \
|
#define HCL_CLASS_SELFSPEC_FLAGS(spec) \
|
||||||
(((hcl_oow_t)spec) & HCL_LBMASK(hcl_oow_t, HCL_CLASS_SELFSPEC_FLAG_BITS))
|
(((hcl_oow_t)spec) & HCL_LBMASK(hcl_oow_t, HCL_CLASS_SELFSPEC_FLAG_BITS))
|
||||||
|
|
||||||
|
/* If you add more than 4 items, you must update code related to CLASS_ENTER instruction
|
||||||
|
* and class attributes as well as HCL_CLASS_SELFSPEC_FLAG_BITS. */
|
||||||
#define HCL_CLASS_SELFSPEC_FLAG_FINAL (1 << 0)
|
#define HCL_CLASS_SELFSPEC_FLAG_FINAL (1 << 0)
|
||||||
#define HCL_CLASS_SELFSPEC_FLAG_LIMITED (1 << 1) /* not allowed to instantiate normally */
|
#define HCL_CLASS_SELFSPEC_FLAG_LIMITED (1 << 1) /* not allowed to instantiate normally */
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ class Apex {
|
|||||||
class Object: Apex {
|
class Object: Apex {
|
||||||
}
|
}
|
||||||
|
|
||||||
class(#uncopyable #varying #limited) Class: Apex [
|
class(#uncopyable #varying #limited #final) Class: Apex [
|
||||||
_name
|
_name
|
||||||
_mdic
|
_mdic
|
||||||
_spec
|
_spec
|
||||||
@ -89,9 +89,9 @@ class FixedSizedCollection: IndexedCollection {
|
|||||||
if (self:respondsTo "initValue") { ## TODO: change "initValue" to a symbol once supported
|
if (self:respondsTo "initValue") { ## TODO: change "initValue" to a symbol once supported
|
||||||
i := 0
|
i := 0
|
||||||
iv := (self:initValue)
|
iv := (self:initValue)
|
||||||
while (i < size) {
|
while (< i size) { ## TODO: change to i < size after having implemented these methods on integer/smallintger
|
||||||
core.basicAtPut obj i iv
|
core.basicAtPut obj i iv
|
||||||
i := (i + 1)
|
i := (+ i 1) ## TODO: change to i + 1 ## TODO: change to i < size after having implemented these methods on integer/smallintger
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return obj
|
return obj
|
||||||
@ -102,10 +102,10 @@ class FixedSizedCollection: IndexedCollection {
|
|||||||
##}
|
##}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Array: FixedSizedCollection {
|
class(#varying) Array: FixedSizedCollection {
|
||||||
}
|
}
|
||||||
|
|
||||||
class String: FixedSizedCollection {
|
class(#char #varying) String: FixedSizedCollection {
|
||||||
fun(#class) initValue() {
|
fun(#class) initValue() {
|
||||||
##return '\0'
|
##return '\0'
|
||||||
return ' '
|
return ' '
|
||||||
|
@ -248,3 +248,27 @@ class X11 { ##ERROR: exception not handled - "prohibited redefintion of X11"
|
|||||||
|
|
||||||
class String { ##ERROR: exception not handled - "incompatible redefintion of String"
|
class String { ##ERROR: exception not handled - "incompatible redefintion of String"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
class() { ##ERROR: syntax error - empty attribute list on unnamed class for 'class'
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
class() Kuduro { ##ERROR: syntax error - empty attribute list on 'Kuduro' for 'class'
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
class(#byte #limited #char) Kuduro { ##ERROR: syntax error - conflicting or duplicate class attribute name '#char'
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
class(#byte #limited #final #limited) Kuduro { ##ERROR: syntax error - conflicting or duplicate class attribute name '#limited'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
class(#byte #bytes) Kuduro { ##ERROR: syntax error - unrecognized class attribute name 'bytes'
|
||||||
|
}
|
||||||
|
@ -84,7 +84,7 @@ fun(#ci) fun1() { ##ERROR: syntax error - attribute list prohibited on plain fun
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
fun() () { ##ERROR: syntax error - attribute list prohibited on unamed function for 'fun'
|
fun() () { ##ERROR: syntax error - attribute list prohibited on unnamed function for 'fun'
|
||||||
}
|
}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
Loading…
Reference in New Issue
Block a user