diff --git a/lib/comp.c b/lib/comp.c index b3e1bae..1f38287 100644 --- a/lib/comp.c +++ b/lib/comp.c @@ -2032,22 +2032,23 @@ static HCL_INLINE int compile_class_p1 (hcl_t* hcl) /* collect information about declared variables */ hcl_cframe_t* cf; hcl_cnode_t* obj; - hcl_oow_t nivars, ncvars, saved_tv_wcount, tv_dup_check_start, cv_dup_check_start; + hcl_oow_t nivars, ncvars, saved_tv_wcount, tv_dup_check_start; + hcl_oow_t ivar_start, ivar_len, cvar_start, cvar_len; cf = GET_TOP_CFRAME(hcl); obj = cf->operand; saved_tv_wcount = hcl->c->tv.wcount; tv_dup_check_start = hcl->c->tv.s.len; - -cv_dup_check_start = hcl->c->tv.s.len; // this is buggy... correct this... + ivar_start = cvar_start = tv_dup_check_start; + ivar_len = cvar_len = 0; nivars = ncvars = 0; /* use the temporary variable collection buffer for convenience when scanning * instance variables and class variables */ while (obj && HCL_CNODE_IS_CONS(obj)) { - hcl_cnode_t* tmp, * tmp2; + hcl_cnode_t* tmp; hcl_oow_t dclcount; /* (defclass X ::: T @@ -2060,10 +2061,12 @@ cv_dup_check_start = hcl->c->tv.s.len; // this is buggy... correct this... ::: | a b c | ; class variables ) */ - tmp2 = obj; tmp = HCL_CNODE_CONS_CAR(obj); if (HCL_CNODE_IS_TRPCOLONS(tmp)) { + /* class variables */ + hcl_oow_t checkpoint; + obj = HCL_CNODE_CONS_CDR(obj); if (!obj || !HCL_CNODE_IS_CONS(obj)) { @@ -2078,27 +2081,49 @@ cv_dup_check_start = hcl->c->tv.s.len; // this is buggy... correct this... return -1; } + checkpoint = hcl->c->tv.s.len; if (collect_vardcl(hcl, obj, &obj, tv_dup_check_start, &dclcount, "class") <= -1) return -1; ncvars += dclcount; + if (cvar_len <= 0) cvar_start = checkpoint; + cvar_len += hcl->c->tv.s.len - checkpoint; } else { + /* instance variables */ + hcl_oow_t checkpoint; if (!HCL_CNODE_IS_CONS_CONCODED(tmp, HCL_CONCODE_VLIST)) break; + checkpoint = hcl->c->tv.s.len; if (collect_vardcl(hcl, obj, &obj, tv_dup_check_start, &dclcount, "instance") <= -1) return -1; nivars += dclcount; + + if (ivar_len <= 0) ivar_start = checkpoint; + ivar_len += hcl->c->tv.s.len - checkpoint; + + if (cvar_len > 0) + { + hcl_rotate_oochars (&hcl->c->tv.s.ptr[cvar_start], hcl->c->tv.s.len - cvar_start, -1, cvar_len); + ivar_start = cvar_start; + cvar_start += hcl->c->tv.s.len - checkpoint; + } } } +//HCL_DEBUG4 (hcl, "AAAAAAAAAAAAAAAAAAAAAAA>>>> [%.*js] [%.*js]\n", ivar_len, &hcl->c->tv.s.ptr[ivar_start], cvar_len, &hcl->c->tv.s.ptr[cvar_start]); + if (nivars > 0) { hcl_oop_t tmp; + int adj; + if (nivars > HCL_SMOOI_MAX) { hcl_setsynerrbfmt (hcl, HCL_SYNERR_VARFLOOD, HCL_CNODE_GET_LOC(cf->operand), HCL_NULL, "too many(%zu) instance variables", nivars); goto oops; } + /* set starting point past the added space (+1 to index, -1 to length) */ - tmp = hcl_makestring(hcl, &hcl->c->tv.s.ptr[tv_dup_check_start + 1], hcl->c->tv.s.len - tv_dup_check_start - 1, 0); + adj = (hcl->c->tv.s.ptr[ivar_start] == ' '); + tmp = hcl_makestring(hcl, &hcl->c->tv.s.ptr[ivar_start + adj], ivar_len - adj, 0); if (HCL_UNLIKELY(!tmp)) goto oops; if (emit_push_literal(hcl, tmp, &cf->u._class.start_loc) <= -1) goto oops; } @@ -2106,6 +2131,8 @@ cv_dup_check_start = hcl->c->tv.s.len; // this is buggy... correct this... if (ncvars > 0) { hcl_oop_t tmp; + int adj; + if (ncvars > HCL_SMOOI_MAX) { /* TOOD: change the error location ?? */ @@ -2113,14 +2140,13 @@ cv_dup_check_start = hcl->c->tv.s.len; // this is buggy... correct this... goto oops; } - tmp = hcl_makestring(hcl, &hcl->c->tv.s.ptr[cv_dup_check_start + 1], hcl->c->tv.s.len - cv_dup_check_start - 1, 0); + adj = (hcl->c->tv.s.ptr[cvar_start] == ' '); + tmp = hcl_makestring(hcl, &hcl->c->tv.s.ptr[cvar_start + adj], cvar_len - adj, 0); if (HCL_UNLIKELY(!tmp)) goto oops; if (emit_push_literal(hcl, tmp, &cf->u._class.start_loc) <= -1) goto oops; } - if (push_clsblk(hcl, &cf->u._class.start_loc, nivars, ncvars, - &hcl->c->tv.s.ptr[tv_dup_check_start + 1], 0, /* TODO: wrong length.... */ - &hcl->c->tv.s.ptr[cv_dup_check_start + 1], hcl->c->tv.s.len - cv_dup_check_start - 1) <= -1) goto oops; + if (push_clsblk(hcl, &cf->u._class.start_loc, nivars, ncvars, &hcl->c->tv.s.ptr[ivar_start], ivar_len, &hcl->c->tv.s.ptr[cvar_start], cvar_len) <= -1) goto oops; /* discard the instance variables and class variables in the temporary variable collection buffer * because they have been pushed to the class block structure */ @@ -2139,7 +2165,6 @@ cv_dup_check_start = hcl->c->tv.s.len; // this is buggy... correct this... hcl->c->clsblk.info[hcl->c->clsblk.depth].class_start_inst_pos = hcl->code.bc.len; SWITCH_TOP_CFRAME (hcl, COP_COMPILE_OBJECT_LIST, obj); - return 0; oops: diff --git a/lib/hcl-utl.h b/lib/hcl-utl.h index 22a0413..51bbc1e 100644 --- a/lib/hcl-utl.h +++ b/lib/hcl-utl.h @@ -548,6 +548,20 @@ HCL_EXPORT hcl_bch_t* hcl_find_bchar_in_bcstr ( hcl_bch_t c ); +HCL_EXPORT hcl_oow_t hcl_rotate_uchars ( + hcl_uch_t* str, + hcl_oow_t len, + int dir, + hcl_oow_t n +); + +HCL_EXPORT hcl_oow_t hcl_rotate_bchars ( + hcl_bch_t* str, + hcl_oow_t len, + int dir, + hcl_oow_t n +); + HCL_EXPORT hcl_oow_t hcl_count_ucstr ( const hcl_uch_t* str ); @@ -576,11 +590,12 @@ HCL_EXPORT hcl_oow_t hcl_count_bcstr ( # define hcl_copy_oocstr(dst,len,src) hcl_copy_ucstr(dst,len,src) # define hcl_copy_oocstr_unlimited(dst,src) hcl_copy_ucstr_unlimited(dst,src) -# define hcl_fill_oochars(dst,ch,len) hcl_fill_uchars(dst,ch,len) -# define hcl_find_oochar(ptr,len,c) hcl_find_uchar(ptr,len,c) -# define hcl_rfind_oochar(ptr,len,c) hcl_rfind_uchar(ptr,len,c) -# define hcl_find_oochar_in_oocstr(ptr,c) hcl_find_uchar_in_ucstr(ptr,c) -# define hcl_count_oocstr(str) hcl_count_ucstr(str) +# define hcl_fill_oochars hcl_fill_uchars +# define hcl_find_oochar hcl_find_uchar +# define hcl_rfind_oochar hcl_rfind_uchar +# define hcl_find_oochar_in_oocstr hcl_find_uchar_in_ucstr +# define hcl_rotate_oochars hcl_rotate_uchars +# define hcl_count_oocstr hcl_count_ucstr #else # define hcl_equal_oochars(str1,str2,len) hcl_equal_bchars(str1,str2,len) # define hcl_comp_oochars(str1,len1,str2,len2) hcl_comp_bchars(str1,len1,str2,len2) @@ -601,11 +616,12 @@ HCL_EXPORT hcl_oow_t hcl_count_bcstr ( # define hcl_copy_oocstr(dst,len,src) hcl_copy_bcstr(dst,len,src) # define hcl_copy_oocstr_unlimited(dst,src) hcl_copy_bcstr_unlimited(dst,src) -# define hcl_fill_oochars(dst,ch,len) hcl_fill_bchars(dst,ch,len) -# define hcl_find_oochar(ptr,len,c) hcl_find_bchar(ptr,len,c) -# define hcl_rfind_oochar(ptr,len,c) hcl_rfind_bchar(ptr,len,c) -# define hcl_find_oochar_in_oocstr(ptr,c) hcl_find_bchar_in_bcstr(ptr,c) -# define hcl_count_oocstr(str) hcl_count_bcstr(str) +# define hcl_fill_oochars hcl_fill_bchars +# define hcl_find_oochar hcl_find_bchar +# define hcl_rfind_oochar hcl_rfind_bchar +# define hcl_find_oochar_in_oocstr hcl_find_bchar_in_bcstr +# define hcl_rotate_oochars hcl_rotate_bchars +# define hcl_count_oocstr hcl_count_bcstr #endif #define HCL_BYTE_TO_BCSTR_RADIXMASK (0xFF) diff --git a/lib/utl.c b/lib/utl.c index e26e575..7a2ef75 100644 --- a/lib/utl.c +++ b/lib/utl.c @@ -418,6 +418,76 @@ hcl_bch_t* hcl_find_bchar_in_bcstr (const hcl_bch_t* ptr, hcl_bch_t c) /* ----------------------------------------------------------------------- */ +hcl_oow_t hcl_rotate_uchars (hcl_uch_t* str, hcl_oow_t len, int dir, hcl_oow_t n) +{ + hcl_oow_t first, last, count, index, nk; + hcl_uch_t c; + + if (dir == 0 || len == 0) return len; + if ((n %= len) == 0) return len; + + if (dir > 0) n = len - n; + first = 0; nk = len - n; count = 0; + + while (count < n) + { + last = first + nk; + index = first; + c = str[first]; + do + { + count++; + while (index < nk) + { + str[index] = str[index + n]; + index += n; + } + if (index == last) break; + str[index] = str[index - nk]; + index -= nk; + } + while (1); + str[last] = c; first++; + } + return len; +} + +hcl_oow_t hcl_rotate_bchars (hcl_bch_t* str, hcl_oow_t len, int dir, hcl_oow_t n) +{ + hcl_oow_t first, last, count, index, nk; + hcl_bch_t c; + + if (dir == 0 || len == 0) return len; + if ((n %= len) == 0) return len; + + if (dir > 0) n = len - n; + first = 0; nk = len - n; count = 0; + + while (count < n) + { + last = first + nk; + index = first; + c = str[first]; + do + { + count++; + while (index < nk) + { + str[index] = str[index + n]; + index += n; + } + if (index == last) break; + str[index] = str[index - nk]; + index -= nk; + } + while (1); + str[last] = c; first++; + } + return len; +} + +/* ----------------------------------------------------------------------- */ + hcl_oow_t hcl_byte_to_bcstr (hcl_uint8_t byte, hcl_bch_t* buf, hcl_oow_t size, int flagged_radix, hcl_bch_t fill) { hcl_bch_t tmp[(HCL_SIZEOF(hcl_uint8_t) * HCL_BITS_PER_BYTE)];