diff --git a/lib/comp.c b/lib/comp.c index 8e724ad..20db97b 100644 --- a/lib/comp.c +++ b/lib/comp.c @@ -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 [ x y ] ## instance variables @@ -2495,29 +2621,42 @@ static int compile_class (hcl_t* hcl, hcl_cnode_t* src) { hcl_cframe_t* cf; hcl_cnode_t* cmd, * obj, * tmp; + hcl_cnode_t* attr_list; hcl_cnode_t* class_name, * superclass; int nsuperclasses; + unsigned int indexed_type; cmd = HCL_CNODE_CONS_CAR(src); obj = HCL_CNODE_CONS_CDR(src); + attr_list = HCL_NULL; class_name = HCL_NULL; + indexed_type = HCL_OBJ_TYPE_OOP; HCL_ASSERT (hcl, HCL_CNODE_IS_TYPED(cmd, HCL_CNODE_CLASS)); -/* TODO: attribute lsit */ - - if (obj /*&& HCL_CNODE_IS_CONS(obj)*/) + if (obj) { HCL_ASSERT (hcl, HCL_CNODE_IS_CONS(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_SYMBOL_IDENT(tmp)) { 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'", HCL_CNODE_GET_TOKLEN(tmp), HCL_CNODE_GET_TOKPTR(tmp), 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) { hcl_setsynerrbfmt ( - hcl, HCL_SYNERR_BLOCK, HCL_CNODE_GET_LOC(src), HCL_NULL, - "no class body defined for '%.*js'", - HCL_CNODE_GET_TOKLEN(class_name), HCL_CNODE_GET_TOKPTR(class_name)); + hcl, HCL_SYNERR_CLASS, HCL_CNODE_GET_LOC(src), HCL_NULL, + "incomplete definition of '%.*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_BLOCK, HCL_CNODE_GET_LOC(src), HCL_NULL, - "no class body defined for unnamed class"); + hcl, HCL_SYNERR_CLASS, HCL_CNODE_GET_LOC(src), HCL_NULL, + "incomplete defintion of unnamed class for '%.*js'", + HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); } 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); 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)) { 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", HCL_CNODE_GET_TOKLEN(marker), HCL_CNODE_GET_TOKPTR(marker)); 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)) { 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'", HCL_CNODE_GET_TOKLEN(superclass), HCL_CNODE_GET_TOKPTR(superclass), 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 { 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'", HCL_CNODE_GET_TOKLEN(marker), HCL_CNODE_GET_TOKPTR(marker), 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 */ cf = GET_TOP_CFRAME(hcl); 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.cmd_cnode = cmd; PUSH_CFRAME (hcl, COP_COMPILE_CLASS_P1, obj); /* 2 - variables declaraions and actual body */ cf = GET_TOP_CFRAME(hcl); 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.cmd_cnode = cmd; @@ -2723,6 +2868,7 @@ static HCL_INLINE int compile_class_p1 (hcl_t* hcl) /* 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_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, vardcl.nivars) <= -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 ( - 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) +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) { unsigned int ft; - ft = 0; + ft = FUN_IM; HCL_ASSERT (hcl, attr_list != HCL_NULL); 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 || hcl_comp_oochars_bcstr(tokptr, toklen, "c") == 0) { - if (ft != 0) + if (ft != FUN_IM) { conflicting: hcl_setsynerrbfmt ( @@ -2879,7 +3023,7 @@ static int check_fun_attr_list ( else if (hcl_comp_oochars_bcstr(tokptr, toklen, "classinst") == 0 || hcl_comp_oochars_bcstr(tokptr, toklen, "ci") == 0) { - if (ft != 0) goto conflicting; + if (ft != FUN_IM) goto conflicting; ft = FUN_CIM; } else @@ -3150,7 +3294,6 @@ static int compile_fun (hcl_t* hcl, hcl_cnode_t* src) * class X { * 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 (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) { - fun_type = FUN_IM; + fun_type = FUN_IM; if (class_name) fun_type |= 0x100; } } @@ -5163,13 +5306,7 @@ redo: goto redo; 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: - 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_COLON: case HCL_CNODE_COLONLT: diff --git a/lib/decode.c b/lib/decode.c index e8bbb3d..e137689 100644 --- a/lib/decode.c +++ b/lib/decode.c @@ -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: { - 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, b2); 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; } diff --git a/lib/err.c b/lib/err.c index e375201..63bdba3 100644 --- a/lib/err.c +++ b/lib/err.c @@ -110,7 +110,6 @@ static const char* synerrstr[] = "invalid radix for a numeric literal", "sudden end of input", - "sudden end of expression", "( expected", ") expected", "] expected", @@ -139,7 +138,6 @@ static const char* synerrstr[] = "if body too big", "block too big", "block too deep", - "name expected", "argument name list expected", "argument name expected", "duplicate argument name", @@ -155,6 +153,7 @@ static const char* synerrstr[] = "disallowed argument name", "disallowed", + "invalid class definition", "invalid function definition", "elif without if", "else without if", diff --git a/lib/exec.c b/lib/exec.c index 1f165bd..fc6b40d 100644 --- a/lib/exec.c +++ b/lib/exec.c @@ -4032,18 +4032,19 @@ static int execute (hcl_t* hcl) push superclass (only if nsuperclassses > 0) push ivars_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 v; 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, b2); /* nivars */ 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) { @@ -4073,7 +4074,6 @@ static int execute (hcl_t* hcl) HCL_STACK_POP_TO(hcl, v); -////////////// if (HCL_IS_CONS(hcl, v)) { /* 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 */ hcl_ooi_t spec, selfspec, nivars_super, nivars_super_real; + hcl_obj_type_t indexed_type; spec = HCL_OOP_TO_SMOOI(class_obj->spec); selfspec = HCL_OOP_TO_SMOOI(class_obj->selfspec); 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); +//if (HCL_CLASS_SPEC_IS_INDEXED(spec)) +//indexed_type = (hcl_obj_type_t)HCL_CLASS_SPEC_INDEXED_TYPE(spec); #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)); #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)); 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); 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 */ 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); #if 1 /* 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) */ hcl->code.bc.ptr[hcl->code.bc.len - 1] = HCL_CODE_RETURN_FROM_BLOCK; #else diff --git a/lib/hcl-prv.h b/lib/hcl-prv.h index abb1df6..d6f80da 100644 --- a/lib/hcl-prv.h +++ b/lib/hcl-prv.h @@ -677,6 +677,7 @@ struct hcl_cframe_t struct { hcl_ooi_t nsuperclasses; + unsigned int indexed_type; hcl_loc_t start_loc; hcl_cnode_t* cmd_cnode; } _class; diff --git a/lib/hcl.h b/lib/hcl.h index 6d3ab3e..587fe16 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -114,7 +114,6 @@ enum hcl_synerrnum_t HCL_SYNERR_RADIX, /* invalid radix for a numeric literal */ HCL_SYNERR_EOF, /* sudden end of input */ - HCL_SYNERR_EOX, /* sudden end of expression */ HCL_SYNERR_LPAREN, /* ( expected */ HCL_SYNERR_RPAREN, /* ) expected */ HCL_SYNERR_RBRACK, /* ] expected */ @@ -143,7 +142,6 @@ enum hcl_synerrnum_t HCL_SYNERR_IFFLOOD, /* if body too big */ HCL_SYNERR_BLKFLOOD, /* block too big */ HCL_SYNERR_BLKDEPTH, /* block too deep */ - HCL_SYNERR_NAME, /* name expected */ HCL_SYNERR_ARGNAMELIST, /* argument name list expected */ HCL_SYNERR_ARGNAME, /* argument name expected */ HCL_SYNERR_ARGNAMEDUP, /* duplicate argument name */ @@ -159,6 +157,7 @@ enum hcl_synerrnum_t HCL_SYNERR_BANNEDARGNAME, /* disallowed argument name */ HCL_SYNERR_BANNED, /* prohibited */ + HCL_SYNERR_CLASS, /* invalid class definition */ HCL_SYNERR_FUN, /* invalid function definition */ HCL_SYNERR_ELIF, /* elif without if */ HCL_SYNERR_ELSE, /* else without if */ diff --git a/lib/read.c b/lib/read.c index 51c5085..06a8173 100644 --- a/lib/read.c +++ b/lib/read.c @@ -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 */ /* 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 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 */ 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. * e.g. fun String:length() { return (str.length self). } * 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 */ } diff --git a/t/class-5001.err b/t/class-5001.err index 5e3bc6c..7976aa5 100644 --- a/t/class-5001.err +++ b/t/class-5001.err @@ -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' ---