diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 6a85d1b..3e7595b 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -3120,6 +3120,15 @@ static MOO_INLINE int set_pooldic_fqn (moo_t* moo, moo_cunit_pooldic_t* pd, cons return 0; } +static MOO_INLINE int prefix_pooldic_fqn (moo_t* moo, moo_cunit_pooldic_t* pd, const moo_oocs_t* prefix) +{ + /* implementaion goes by appending and rotation. inefficient but works. */ + if (copy_string_to(moo, prefix, &pd->fqn, &pd->fqn_capa, 1, '\0') <= -1) return -1; + moo_rotate_oochars (pd->fqn.ptr, pd->fqn.len, 1, prefix->len); + pd->name.ptr += prefix->len; + return 0; +} + static MOO_INLINE int set_interface_fqn (moo_t* moo, moo_cunit_interface_t* ifce, const moo_oocs_t* name) { if (copy_string_to(moo, name, &ifce->fqn, &ifce->fqn_capa, 0, '\0') <= -1) return -1; @@ -8361,9 +8370,12 @@ static int make_defined_class (moo_t* moo) if (!tmp) return -1; MOO_STORE_OOP (moo, (moo_oop_t*)&cc->self_oop->classinstvars, tmp); +/* + * this is done at the end of __compile_class_definition() tmp = moo_makestring(moo, cc->pdimp.dcl.ptr, cc->pdimp.dcl.len); if (!tmp) return -1; MOO_STORE_OOP (moo, (moo_oop_t*)&cc->self_oop->pooldics, tmp); +*/ tmp = (moo_oop_t)moo_makedic(moo, moo->_method_dictionary, INSTANCE_METHOD_DICTIONARY_SIZE); if (!tmp) return -1; @@ -9169,6 +9181,7 @@ static int __compile_class_definition (moo_t* moo, int class_type) ptr = MOO_OBJ_GET_CHAR_SLOT(pds); end = ptr + MOO_OBJ_GET_SIZE(pds); +MOO_DEBUG2 (moo, "import pooldic... [%.*js]\n", end - ptr, ptr); /* this loop handles the pooldic string as if it's a pooldic import. * see compile_class_level_variables() for mostly identical code except token handling */ do @@ -9203,6 +9216,7 @@ static int __compile_class_definition (moo_t* moo, int class_type) ns_oop = cc->ns_oop; } +MOO_DEBUG2 (moo, "import pooldic... %.*js\n", last.len, last.ptr); if (import_pooldic(moo, cc, ns_oop, &last, &tok, &loc) <= -1) return -1; } while (1); @@ -9335,6 +9349,16 @@ static int __compile_class_definition (moo_t* moo, int class_type) if (check_class_interface_conformance(moo) <= -1) return -1; } + if (cc->pdimp.dcl.len > 0) + { + moo_oop_t tmp; + + tmp = moo_makestring(moo, cc->pdimp.dcl.ptr, cc->pdimp.dcl.len); + if (!tmp) return -1; + + MOO_STORE_OOP (moo, (moo_oop_t*)&cc->self_oop->pooldics, tmp); + } + GET_TOKEN (moo); return 0; } @@ -9910,8 +9934,15 @@ done: if (pd->cunit_parent && pd->cunit_parent->cunit_type == MOO_CUNIT_CLASS) { - /* a pool dictionary nested inside a class is auto-imported */ - if (import_pooldic(moo, (moo_cunit_class_t*)pd->cunit_parent, pd->ns_oop, &pd->fqn, &pd->fqn, &pd->fqn_loc) <= -1) goto oops; + /* a pool dictionary nested inside a class is auto-imported. + * change pd->fqn to form a fully qualified name for importing. + * the full name is required for restoration upon 'extend'.*/ + moo_cunit_class_t* cc = (moo_cunit_class_t*)pd->cunit_parent; + static moo_ooch_t str_dot[] = { '.' }; + static const moo_oocs_t oocs_dot = { str_dot, 1 }; + if (prefix_pooldic_fqn (moo, pd, &oocs_dot) <= -1 || + prefix_pooldic_fqn (moo, pd, &cc->fqn) <= -1 || + import_pooldic(moo, cc, pd->ns_oop, &pd->name, &pd->fqn, &pd->fqn_loc) <= -1) goto oops; } moo->c->arlit.count = saved_arlit_count; diff --git a/moo/lib/moo-utl.h b/moo/lib/moo-utl.h index 7a44832..aeb36ff 100644 --- a/moo/lib/moo-utl.h +++ b/moo/lib/moo-utl.h @@ -539,6 +539,20 @@ MOO_EXPORT moo_bch_t* moo_find_bchar_in_bcstr ( moo_bch_t c ); +MOO_EXPORT moo_oow_t moo_rotate_uchars ( + moo_uch_t* str, + moo_oow_t len, + int dir, + moo_oow_t n +); + +MOO_EXPORT moo_oow_t moo_rotate_bchars ( + moo_bch_t* str, + moo_oow_t len, + int dir, + moo_oow_t n +); + MOO_EXPORT moo_oow_t moo_count_ucstr ( const moo_uch_t* str ); @@ -562,6 +576,7 @@ MOO_EXPORT moo_oow_t moo_count_bcstr ( # define moo_find_oochar(ptr,len,c) moo_find_uchar(ptr,len,c) # define moo_rfind_oochar(ptr,len,c) moo_rfind_uchar(ptr,len,c) # define moo_find_oochar_in_oocstr(ptr,c) moo_find_uchar_in_ucstr(ptr,c) +# define moo_rotate_oochars(str,len,dir,n) moo_rotate_uchars(str,len,dir,n) # define moo_count_oocstr(str) moo_count_ucstr(str) #else # define moo_equal_oochars(str1,str2,len) moo_equal_bchars(str1,str2,len) @@ -578,6 +593,7 @@ MOO_EXPORT moo_oow_t moo_count_bcstr ( # define moo_find_oochar(ptr,len,c) moo_find_bchar(ptr,len,c) # define moo_rfind_oochar(ptr,len,c) moo_rfind_bchar(ptr,len,c) # define moo_find_oochar_in_oocstr(ptr,c) moo_find_bchar_in_bcstr(ptr,c) +# define moo_rotate_oochars(str,len,dir,n) moo_rotate_bchars(str,len,dir,n) # define moo_count_oocstr(str) moo_count_bcstr(str) #endif diff --git a/moo/lib/utl.c b/moo/lib/utl.c index c5abd9a..9a988c6 100644 --- a/moo/lib/utl.c +++ b/moo/lib/utl.c @@ -400,6 +400,74 @@ moo_bch_t* moo_find_bchar_in_bcstr (const moo_bch_t* ptr, moo_bch_t c) return MOO_NULL; } +moo_oow_t moo_rotate_bchars (moo_bch_t* str, moo_oow_t len, int dir, moo_oow_t n) +{ + moo_oow_t first, last, count, index, nk; + moo_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; +} + +moo_oow_t moo_rotate_uchars (moo_uch_t* str, moo_oow_t len, int dir, moo_oow_t n) +{ + moo_oow_t first, last, count, index, nk; + moo_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; +} + /* ----------------------------------------------------------------------- */ moo_oow_t moo_byte_to_bcstr (moo_uint8_t byte, moo_bch_t* buf, moo_oow_t size, int flagged_radix, moo_bch_t fill)