From 8324f64deaf7c10a9d289d8f809185d643e57822 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Tue, 16 May 2017 15:01:31 +0000 Subject: [PATCH] refactored array and byte array processing code in the compiler --- moo/lib/comp.c | 618 ++++++++++++++++++++++++++-------------------- moo/lib/debug.c | 2 +- moo/lib/moo-prv.h | 70 ++++-- 3 files changed, 401 insertions(+), 289 deletions(-) diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 63c0f5d..ec7bee9 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -688,8 +688,11 @@ static int add_to_oow_pool (moo_t* moo, moo_oow_pool_t* pool, moo_oow_t v) #define GET_TOKEN(moo) \ do { if (get_token(moo) <= -1) return -1; } while (0) -#define GET_TOKEN_WITH_ERRRET(moo, v_ret) \ - do { if (get_token(moo) <= -1) return v_ret; } while (0) +#define GET_TOKEN_RETURN(moo,fail_ret) \ + do { if (get_token(moo) <= -1) return fail_ret; } while (0) + +#define GET_TOKEN_GOTO(moo,fail_label) \ + do { if (get_token(moo) <= -1) goto fail_label; } while (0) #define ADD_TOKEN_STR(moo,s,l) \ do { if (add_token_str(moo, s, l) <= -1) return -1; } while (0) @@ -2476,35 +2479,35 @@ static int add_literal (moo_t* moo, moo_oop_t lit, moo_oow_t* index) { moo_oow_t i; - for (i = 0; i < moo->c->mth.literal_count; i++) + for (i = 0; i < moo->c->mth.literals.count; i++) { /* * this removes redundancy of symbols, characters, and small integers. * more complex redundacy check may be done somewhere else like * in add_string_literal(). */ - if (moo->c->mth.literals[i] == lit) + if (moo->c->mth.literals.ptr[i] == lit) { *index = i; return i; } } - if (moo->c->mth.literal_count >= moo->c->mth.literal_capa) + if (moo->c->mth.literals.count >= moo->c->mth.literals.capa) { moo_oop_t* tmp; moo_oow_t new_capa; - new_capa = MOO_ALIGN (moo->c->mth.literal_count + 1, LITERAL_BUFFER_ALIGN); - tmp = (moo_oop_t*)moo_reallocmem (moo, moo->c->mth.literals, new_capa * MOO_SIZEOF(*tmp)); + new_capa = MOO_ALIGN (moo->c->mth.literals.count + 1, LITERAL_BUFFER_ALIGN); + tmp = (moo_oop_t*)moo_reallocmem (moo, moo->c->mth.literals.ptr, new_capa * MOO_SIZEOF(*tmp)); if (!tmp) return -1; - moo->c->mth.literal_capa = new_capa; - moo->c->mth.literals = tmp; + moo->c->mth.literals.capa = new_capa; + moo->c->mth.literals.ptr = tmp; } - *index = moo->c->mth.literal_count; - moo->c->mth.literals[moo->c->mth.literal_count++] = lit; + *index = moo->c->mth.literals.count; + moo->c->mth.literals.ptr[moo->c->mth.literals.count++] = lit; return 0; } @@ -2513,9 +2516,9 @@ static int add_string_literal (moo_t* moo, const moo_oocs_t* str, moo_oow_t* ind moo_oop_t lit; moo_oow_t i; - for (i = 0; i < moo->c->mth.literal_count; i++) + for (i = 0; i < moo->c->mth.literals.count; i++) { - lit = moo->c->mth.literals[i]; + lit = moo->c->mth.literals.ptr[i]; if (MOO_CLASSOF(moo, lit) == moo->_string && MOO_OBJ_GET_SIZE(lit) == str->len && @@ -2562,6 +2565,13 @@ static MOO_INLINE int set_class_modname (moo_t* moo, const moo_oocs_t* name) return 0; } +static MOO_INLINE int set_pooldic_fqn (moo_t* moo, moo_pooldic_t* pd, const moo_oocs_t* name) +{ + if (copy_string_to (moo, name, &pd->fqn, &pd->fqn_capa, 0, '\0') <= -1) return -1; + pd->name = pd->fqn; + return 0; +} + static MOO_INLINE int add_class_level_variable (moo_t* moo, var_type_t var_type, const moo_oocs_t* name) { int n; @@ -2611,23 +2621,23 @@ static int set_class_level_variable_initv (moo_t* moo, var_type_t var_type, moo_ return 0; } -static MOO_INLINE int add_pool_dictionary (moo_t* moo, const moo_oocs_t* name, moo_oop_set_t pooldic_oop) +static MOO_INLINE int add_pooldic_import (moo_t* moo, const moo_oocs_t* name, moo_oop_set_t pooldic_oop) { - if (moo->c->cls.pooldic_count >= moo->c->cls.pooldic_imp_oops_capa) + if (moo->c->cls.pooldic_imp.dcl_count >= moo->c->cls.pooldic_imp.oops_capa) { moo_oow_t new_capa; moo_oop_set_t* tmp; - new_capa = MOO_ALIGN(moo->c->cls.pooldic_imp_oops_capa + 1, POOLDIC_OOP_BUFFER_ALIGN); - tmp = moo_reallocmem (moo, moo->c->cls.pooldic_imp_oops, new_capa * MOO_SIZEOF(moo_oop_set_t)); + new_capa = MOO_ALIGN(moo->c->cls.pooldic_imp.oops_capa + 1, POOLDIC_OOP_BUFFER_ALIGN); + tmp = moo_reallocmem (moo, moo->c->cls.pooldic_imp.oops, new_capa * MOO_SIZEOF(moo_oop_set_t)); if (!tmp) return -1; - moo->c->cls.pooldic_imp_oops_capa = new_capa; - moo->c->cls.pooldic_imp_oops = tmp; + moo->c->cls.pooldic_imp.oops_capa = new_capa; + moo->c->cls.pooldic_imp.oops = tmp; } - moo->c->cls.pooldic_imp_oops[moo->c->cls.pooldic_count] = pooldic_oop; - moo->c->cls.pooldic_count++; + moo->c->cls.pooldic_imp.oops[moo->c->cls.pooldic_imp.dcl_count] = pooldic_oop; + moo->c->cls.pooldic_imp.dcl_count++; /* TODO: check if pooldic_count overflows */ return 0; @@ -3055,9 +3065,9 @@ static int resolve_pooldic (moo_t* moo, int dotted, const moo_oocs_t* name) } /* check if the same dictionary pool has been declared for import */ - for (i = 0; i < moo->c->cls.pooldic_count; i++) + for (i = 0; i < moo->c->cls.pooldic_imp.dcl_count; i++) { - if ((moo_oop_set_t)ass->value == moo->c->cls.pooldic_imp_oops[i]) + if ((moo_oop_set_t)ass->value == moo->c->cls.pooldic_imp.oops[i]) { set_syntax_error (moo, MOO_SYNERR_POOLDICDUPL, TOKEN_LOC(moo), name); return -1; @@ -3081,19 +3091,19 @@ static int import_pool_dictionary (moo_t* moo, moo_oop_set_t ns_oop, const moo_o } /* check if the same dictionary pool has been declared for import */ - for (i = 0; i < moo->c->cls.pooldic_count; i++) + for (i = 0; i < moo->c->cls.pooldic_imp.dcl_count; i++) { - if ((moo_oop_set_t)ass->value == moo->c->cls.pooldic_imp_oops[i]) + if ((moo_oop_set_t)ass->value == moo->c->cls.pooldic_imp.oops[i]) { set_syntax_error (moo, MOO_SYNERR_POOLDICDUPL, tok_loc, tok_name); return -1; } } - if (add_pool_dictionary(moo, tok_name, (moo_oop_set_t)ass->value) <= -1) return -1; - if (copy_string_to (moo, tok_name, &moo->c->cls.pooldic, &moo->c->cls.pooldic_capa, 1, ' ') <= -1) + if (add_pooldic_import(moo, tok_name, (moo_oop_set_t)ass->value) <= -1) return -1; + if (copy_string_to (moo, tok_name, &moo->c->cls.pooldic_imp.dcl, &moo->c->cls.pooldic_imp.dcl_capa, 1, ' ') <= -1) { - moo->c->cls.pooldic_count--; /* roll back add_pool_dictionary() */ + moo->c->cls.pooldic_imp.dcl_count--; /* roll back add_pool_dictionary() */ return -1; } @@ -3876,9 +3886,9 @@ static int find_ident_in_nsdic_and_sysdic (moo_t* moo, const moo_oocs_t* name, c moo_oop_association_t ass2 = MOO_NULL; /* attempt to find the variable in pool dictionaries */ - for (i = 0; i < moo->c->cls.pooldic_count; i++) + for (i = 0; i < moo->c->cls.pooldic_imp.dcl_count; i++) { - ass = moo_lookupdic (moo, moo->c->cls.pooldic_imp_oops[i], name); + ass = moo_lookupdic (moo, moo->c->cls.pooldic_imp.oops[i], name); if (ass) { if (ass2) @@ -4217,50 +4227,52 @@ static int compile_block_expression (moo_t* moo) static int add_to_byte_array_literal_buffer (moo_t* moo, moo_oob_t b) { - if (moo->c->mth.balit_count >= moo->c->mth.balit_capa) + if (moo->c->balit.count >= moo->c->balit.capa) { moo_oob_t* tmp; moo_oow_t new_capa; - new_capa = MOO_ALIGN (moo->c->mth.balit_count + 1, BALIT_BUFFER_ALIGN); - tmp = (moo_oob_t*)moo_reallocmem (moo, moo->c->mth.balit, new_capa * MOO_SIZEOF(*tmp)); + new_capa = MOO_ALIGN (moo->c->balit.count + 1, BALIT_BUFFER_ALIGN); + tmp = (moo_oob_t*)moo_reallocmem (moo, moo->c->balit.ptr, new_capa * MOO_SIZEOF(*tmp)); if (!tmp) return -1; - moo->c->mth.balit_capa = new_capa; - moo->c->mth.balit = tmp; + moo->c->balit.capa = new_capa; + moo->c->balit.ptr = tmp; } -/* TODO: overflow check of moo->c->mth.balit_count itself */ - moo->c->mth.balit[moo->c->mth.balit_count++] = b; +/* TODO: overflow check of moo->c->balit.count itself */ + moo->c->balit.ptr[moo->c->balit.count++] = b; return 0; } static int add_to_array_literal_buffer (moo_t* moo, moo_oop_t item) { - if (moo->c->mth.arlit_count >= moo->c->mth.arlit_capa) + if (moo->c->arlit.count >= moo->c->arlit.capa) { moo_oop_t* tmp; moo_oow_t new_capa; - new_capa = MOO_ALIGN (moo->c->mth.arlit_count + 1, ARLIT_BUFFER_ALIGN); - tmp = (moo_oop_t*)moo_reallocmem (moo, moo->c->mth.arlit, new_capa * MOO_SIZEOF(*tmp)); + new_capa = MOO_ALIGN (moo->c->arlit.count + 1, ARLIT_BUFFER_ALIGN); + tmp = (moo_oop_t*)moo_reallocmem (moo, moo->c->arlit.ptr, new_capa * MOO_SIZEOF(*tmp)); if (!tmp) return -1; - moo->c->mth.arlit_capa = new_capa; - moo->c->mth.arlit = tmp; + moo->c->arlit.capa = new_capa; + moo->c->arlit.ptr = tmp; } -/* TODO: overflow check of moo->c->mth.arlit_count itself */ - moo->c->mth.arlit[moo->c->mth.arlit_count++] = item; +/* TODO: overflow check of moo->c->arlit.count itself */ + moo->c->arlit.ptr[moo->c->arlit.count++] = item; return 0; } -static int __read_byte_array_literal (moo_t* moo, moo_oop_t* xlit) +static int read_byte_array_literal (moo_t* moo, moo_oop_t* xlit) { moo_ooi_t tmp; moo_oop_t ba; - moo->c->mth.balit_count = 0; + moo->c->balit.count = 0; + + GET_TOKEN (moo); /* skip #[ and read the next token */ while (TOKEN_TYPE(moo) == MOO_IOTOK_NUMLIT || TOKEN_TYPE(moo) == MOO_IOTOK_RADNUMLIT) { @@ -4293,163 +4305,55 @@ static int __read_byte_array_literal (moo_t* moo, moo_oop_t* xlit) return -1; } - ba = moo_instantiate (moo, moo->_byte_array, moo->c->mth.balit, moo->c->mth.balit_count); + ba = moo_instantiate (moo, moo->_byte_array, moo->c->balit.ptr, moo->c->balit.count); if (!ba) return -1; *xlit = ba; return 0; } -struct arlit_info_t -{ - moo_oow_t pos; - moo_oow_t len; -}; -typedef struct arlit_info_t arlit_info_t; - -static int __read_array_literal (moo_t* moo, int rdonly, moo_oop_t* xlit) +static int read_array_literal (moo_t* moo, int rdonly, moo_oop_t* xlit) { moo_oop_t lit, a; - moo_oow_t i, saved_arlit_count; - arlit_info_t info; + moo_oow_t i, j, saved_arlit_count; - info.pos = moo->c->mth.arlit_count; - info.len = 0; + saved_arlit_count = moo->c->arlit.count; + + GET_TOKEN_GOTO (moo, oops); /* skip #( */ do { - /* NOTE: see token_to_literal() for analogous code */ - switch (TOKEN_TYPE(moo)) + if (TOKEN_TYPE(moo) == MOO_IOTOK_EOF) { - case MOO_IOTOK_NIL: - lit = moo->_nil; - break; - - case MOO_IOTOK_TRUE: - lit = moo->_true; - break; - - case MOO_IOTOK_FALSE: - lit = moo->_false; - break; - - case MOO_IOTOK_ERROR: /* error */ - lit = MOO_ERROR_TO_OOP(MOO_EGENERIC); - break; - - case MOO_IOTOK_ERRLIT: /* error(X) */ - lit = string_to_error (moo, TOKEN_NAME(moo)); - break; - - case MOO_IOTOK_CHARLIT: - MOO_ASSERT (moo, TOKEN_NAME_LEN(moo) == 1); - lit = MOO_CHAR_TO_OOP(TOKEN_NAME_PTR(moo)[0]); - break; - -/* TODO: floating pointer number */ - case MOO_IOTOK_NUMLIT: - case MOO_IOTOK_RADNUMLIT: - lit = string_to_num (moo, TOKEN_NAME(moo), TOKEN_TYPE(moo) == MOO_IOTOK_RADNUMLIT); - if (rdonly && lit && MOO_OOP_IS_POINTER(lit)) MOO_OBJ_SET_FLAGS_RDONLY (lit, 1); - break; - - case MOO_IOTOK_SYMLIT: - /* moo_makesymbol() sets RDONLY on a symbol. */ - lit = moo_makesymbol (moo, TOKEN_NAME_PTR(moo) + 1, TOKEN_NAME_LEN(moo) - 1); - break; - - case MOO_IOTOK_STRLIT: - lit = moo_instantiate (moo, moo->_string, TOKEN_NAME_PTR(moo), TOKEN_NAME_LEN(moo)); - if (rdonly && lit) - { - MOO_ASSERT (moo, MOO_OOP_IS_POINTER(lit)); - MOO_OBJ_SET_FLAGS_RDONLY (lit, 1); - } - break; - - case MOO_IOTOK_IDENT: - { - var_info_t var; - if (find_ident_in_nsdic_and_sysdic (moo, TOKEN_NAME(moo), TOKEN_LOC(moo), &var) <= -1) return -1; - MOO_ASSERT (moo, var.type == VAR_GLOBAL); - lit = var.gbl->value; - /* [NOTE] i don't mark RDONLY on an array member resolved via an identifier */ - break; - } - - case MOO_IOTOK_IDENT_DOTTED: - { - var_info_t var; - if (find_dotted_ident (moo, TOKEN_NAME(moo), TOKEN_LOC(moo), &var) <= -1) return -1; - if (var.type != VAR_GLOBAL) - { -/* TODO: XXXXXXXXXXXXXXXXXXXXXXXXxx */ - return -1; - } - - lit = var.gbl->value; - /* [NOTE] i don't mark RDONLY on an array member resolved via an identifier */ - break; - } - - case MOO_IOTOK_BABRACK: /* #[ */ - GET_TOKEN (moo); - if (__read_byte_array_literal (moo, &lit) <= -1) return -1; - if (rdonly) - { - MOO_ASSERT (moo, lit && MOO_OOP_IS_POINTER(lit)); - MOO_OBJ_SET_FLAGS_RDONLY (lit, 1); - } - break; - - case MOO_IOTOK_APAREN: /* #( */ - saved_arlit_count = moo->c->mth.arlit_count; -/* TODO: get rid of recursion?? */ - GET_TOKEN (moo); - if (__read_array_literal (moo, rdonly, &lit) <= -1) return -1; - if (rdonly) - { - MOO_ASSERT (moo, lit && MOO_OOP_IS_POINTER(lit)); - MOO_OBJ_SET_FLAGS_RDONLY (lit, 1); - } - moo->c->mth.arlit_count = saved_arlit_count; - break; - - default: - goto done; + set_syntax_error (moo, MOO_SYNERR_RPAREN, TOKEN_LOC(moo), TOKEN_NAME(moo)); + goto oops; } + else if (TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN) break; - if (!lit || add_to_array_literal_buffer(moo, lit) <= -1) return -1; - info.len++; + lit = token_to_literal (moo, rdonly); + if (!lit || add_to_array_literal_buffer(moo, lit) <= -1) goto oops; - GET_TOKEN (moo); + GET_TOKEN_GOTO (moo, oops); } while (1); -done: - if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN) - { - set_syntax_error (moo, MOO_SYNERR_RPAREN, TOKEN_LOC(moo), TOKEN_NAME(moo)); - return -1; - } + a = moo_instantiate (moo, moo->_array, MOO_NULL, moo->c->arlit.count - saved_arlit_count); + if (!a) goto oops; - a = moo_instantiate (moo, moo->_array, MOO_NULL, info.len); - if (!a) return -1; - - for (i = 0; i < info.len; i++) + for (i = saved_arlit_count, j = 0; i < moo->c->arlit.count; i++, j++) { - ((moo_oop_oop_t)a)->slot[i] = moo->c->mth.arlit[info.pos + i]; + ((moo_oop_oop_t)a)->slot[j] = moo->c->arlit.ptr[i]; } *xlit = a; - return 0; -} -static MOO_INLINE int read_byte_array_literal (moo_t* moo, moo_oop_t* xlit) -{ - GET_TOKEN (moo); /* skip #[ and read the next token */ - return __read_byte_array_literal(moo, xlit); + moo->c->arlit.count = saved_arlit_count; + return 0; + +oops: + moo->c->arlit.count = saved_arlit_count; + return -1; } static int compile_byte_array_literal (moo_t* moo) @@ -4457,6 +4361,8 @@ static int compile_byte_array_literal (moo_t* moo) moo_oop_t lit; moo_oow_t index; + MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_BABRACK); + if (read_byte_array_literal(moo, &lit) <= -1 || add_literal(moo, lit, &index) <= -1 || emit_single_param_instruction(moo, BCODE_PUSH_LITERAL_0, index) <= -1) return -1; @@ -4465,32 +4371,13 @@ static int compile_byte_array_literal (moo_t* moo) return 0; } -static int read_array_literal (moo_t* moo, int rdonly, moo_oop_t* xlit) -{ - int x; - moo_oow_t saved_arlit_count; - - moo->c->in_array = 1; - if (get_token(moo) <= -1) - { - /* skip #( and read the next token */ - moo->c->in_array = 0; - return -1; - } - saved_arlit_count = moo->c->mth.arlit_count; - x = __read_array_literal (moo, rdonly, xlit); - moo->c->mth.arlit_count = saved_arlit_count; - moo->c->in_array = 0; - - return x; -} - static int compile_array_literal (moo_t* moo) { moo_oop_t lit; moo_oow_t index; - MOO_ASSERT (moo, moo->c->mth.arlit_count == 0); + MOO_ASSERT (moo, moo->c->arlit.count == 0); + MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_APAREN); if (read_array_literal(moo, 0, &lit) <= -1 || add_literal(moo, lit, &index) <= -1 || @@ -5905,16 +5792,16 @@ static int add_compiled_method (moo_t* moo) /* The variadic data part passed to moo_instantiate() is not GC-safe. * let's delay initialization of variadic data a bit. */ #if defined(MOO_USE_METHOD_TRAILER) - mth = (moo_oop_method_t)moo_instantiatewithtrailer (moo, moo->_method, moo->c->mth.literal_count, moo->c->mth.code.ptr, moo->c->mth.code.len); + mth = (moo_oop_method_t)moo_instantiatewithtrailer (moo, moo->_method, moo->c->mth.literals.count, moo->c->mth.code.ptr, moo->c->mth.code.len); #else - mth = (moo_oop_method_t)moo_instantiate (moo, moo->_method, MOO_NULL, moo->c->mth.literal_count); + mth = (moo_oop_method_t)moo_instantiate (moo, moo->_method, MOO_NULL, moo->c->mth.literals.count); #endif if (!mth) goto oops; - for (i = 0; i < moo->c->mth.literal_count; i++) + for (i = 0; i < moo->c->mth.literals.count; i++) { /* let's do the variadic data initialization here */ - mth->slot[i] = moo->c->mth.literals[i]; + mth->slot[i] = moo->c->mth.literals.ptr[i]; } moo_pushtmp (moo, (moo_oop_t*)&mth); tmp_count++; @@ -6119,6 +6006,8 @@ oops: static int compile_method_definition (moo_t* moo) { /* clear data required to compile a method */ + MOO_ASSERT (moo, moo->c->arlit.count == 0); + moo->c->mth.type = MOO_METHOD_INSTANCE; moo->c->mth.primitive = 0; moo->c->mth.lenient = 0; @@ -6132,9 +6021,8 @@ static int compile_method_definition (moo_t* moo) moo->c->mth.tmprs.len = 0; moo->c->mth.tmpr_count = 0; moo->c->mth.tmpr_nargs = 0; - moo->c->mth.literal_count = 0; - moo->c->mth.balit_count = 0; - moo->c->mth.arlit_count = 0; + moo->c->mth.literals.count = 0; + moo->c->balit.count = 0; moo->c->mth.pftype = PFTYPE_NONE; moo->c->mth.pfnum = 0; moo->c->mth.blk_depth = 0; @@ -6535,7 +6423,7 @@ static int make_defined_class (moo_t* moo) if (!tmp) return -1; moo->c->cls.self_oop->classinstvars = (moo_oop_char_t)tmp; - tmp = moo_makestring (moo, moo->c->cls.pooldic.ptr, moo->c->cls.pooldic.len); + tmp = moo_makestring (moo, moo->c->cls.pooldic_imp.dcl.ptr, moo->c->cls.pooldic_imp.dcl.len); if (!tmp) return -1; moo->c->cls.self_oop->pooldics = (moo_oop_char_t)tmp; @@ -7156,22 +7044,22 @@ static int compile_class_definition (moo_t* moo, int extend) for (i = 0; i < MOO_COUNTOF(moo->c->cls.var); i++) { moo->c->cls.var[i].str.len = 0; - moo->c->cls.var[i].count = 0; moo->c->cls.var[i].total_count = 0; moo->c->cls.var[i].initv_count = 0; } - moo->c->cls.pooldic_count = 0; - moo->c->cls.pooldic.len = 0; + moo->c->cls.pooldic_imp.dcl_count = 0; + moo->c->cls.pooldic_imp.dcl.len = 0; moo->c->cls.self_oop = MOO_NULL; moo->c->cls.super_oop = MOO_NULL; moo->c->cls.ns_oop = MOO_NULL; moo->c->cls.superns_oop = MOO_NULL; - moo->c->mth.literal_count = 0; - moo->c->mth.balit_count = 0; - moo->c->mth.arlit_count = 0; + moo->c->mth.literals.count = 0; + moo->c->balit.count = 0; + + moo->c->arlit.count = 0; /* do main compilation work */ n = __compile_class_definition (moo, extend); @@ -7182,23 +7070,24 @@ static int compile_class_definition (moo_t* moo, int extend) moo->c->cls.super_oop = MOO_NULL; moo->c->cls.ns_oop = MOO_NULL; moo->c->cls.superns_oop = MOO_NULL; - moo->c->mth.literal_count = 0; - moo->c->mth.balit_count = 0; - moo->c->mth.arlit_count = 0; + moo->c->mth.literals.count = 0; + moo->c->balit.count = 0; for (i = 0; i < MOO_COUNTOF(moo->c->cls.var); i++) { moo->c->cls.var[i].initv_count = 0; } - moo->c->cls.pooldic_count = 0; + moo->c->cls.pooldic_imp.dcl_count = 0; + moo->c->cls.pooldic_imp.dcl.len = 0; + + MOO_ASSERT (moo, n <= -1 || (n >= 0 && moo->c->arlit.count == 0)); + moo->c->arlit.count = 0; return n; } static MOO_INLINE moo_oop_t token_to_literal (moo_t* moo, int rdonly) { - /* NOTE: see __read_array_literal() for analogous code */ - switch (TOKEN_TYPE(moo)) { case MOO_IOTOK_NIL: @@ -7245,6 +7134,38 @@ static MOO_INLINE moo_oop_t token_to_literal (moo_t* moo, int rdonly) return lit; } +#if 0 +/* TODO: if a constant name is specified (constant defined in a class) or + * another variable with the default initialization value + * class { var x := 20, y := x. } */ + case MOO_IOTOK_IDENT: + case MOO_IOTOK_IDENT_DOTTED: +#endif + + case MOO_IOTOK_IDENT: + { + var_info_t var; + if (find_ident_in_nsdic_and_sysdic (moo, TOKEN_NAME(moo), TOKEN_LOC(moo), &var) <= -1) return MOO_NULL; + MOO_ASSERT (moo, var.type == VAR_GLOBAL); + /* [NOTE] i don't mark RDONLY on a value resolved via an identifier */ + return var.gbl->value; + } + + case MOO_IOTOK_IDENT_DOTTED: + { + var_info_t var; + if (find_dotted_ident (moo, TOKEN_NAME(moo), TOKEN_LOC(moo), &var) <= -1) return MOO_NULL; + if (var.type != VAR_GLOBAL) + { +/* TODO: XXXXXXXXXXXXXXXXXXXXXXXXxx */ + set_syntax_error (moo, MOO_SYNERR_VARINACC, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return MOO_NULL; + } + + /* [NOTE] i don't mark RDONLY on a value resolved via an identifier */ + return var.gbl->value; + } + case MOO_IOTOK_BABRACK: /* #[ - byte array literal parenthesis */ { moo_oop_t lit; @@ -7269,14 +7190,6 @@ static MOO_INLINE moo_oop_t token_to_literal (moo_t* moo, int rdonly) return lit; } -#if 0 -/* TODO: if a constant name is specified (constant defined in a class) or - * another variable with the default initialization value - * class { var x := 20, y := x. } */ - case MOO_IOTOK_IDENT: - case MOO_IOTOK_IDENT_DOTTED: -#endif - default: set_syntax_error (moo, MOO_SYNERR_LITERAL, TOKEN_LOC(moo), TOKEN_NAME(moo)); return MOO_NULL; @@ -7288,23 +7201,26 @@ static int __compile_pooldic_definition (moo_t* moo) moo_oop_t lit; moo_ooi_t tally; moo_oow_t i; + moo_oow_t saved_arlit_count; + + saved_arlit_count = moo->c->arlit.count; if (TOKEN_TYPE(moo) != MOO_IOTOK_IDENT && TOKEN_TYPE(moo) != MOO_IOTOK_IDENT_DOTTED) { set_syntax_error (moo, MOO_SYNERR_IDENT, TOKEN_LOC(moo), TOKEN_NAME(moo)); - return -1; + goto oops; } /* [NOTE] * reuse moo->c->cls.fqn and related fields are reused * to store the pool dictionary name */ - if (set_class_fqn(moo, TOKEN_NAME(moo)) <= -1) return -1; + if (set_class_fqn(moo, TOKEN_NAME(moo)) <= -1) goto oops; moo->c->cls.fqn_loc = moo->c->tok.loc; if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED) { - if (preprocess_dotted_name(moo, 0, MOO_NULL, &moo->c->cls.fqn, &moo->c->cls.fqn_loc, &moo->c->cls.name, &moo->c->cls.ns_oop) <= -1) return -1; + if (preprocess_dotted_name(moo, 0, MOO_NULL, &moo->c->cls.fqn, &moo->c->cls.fqn_loc, &moo->c->cls.name, &moo->c->cls.ns_oop) <= -1) goto oops; } else { @@ -7315,84 +7231,90 @@ static int __compile_pooldic_definition (moo_t* moo) { /* a conflicting entry has been found */ set_syntax_error (moo, MOO_SYNERR_POOLDICDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); - return -1; + goto oops; } - GET_TOKEN (moo); + GET_TOKEN_GOTO (moo, oops); if (TOKEN_TYPE(moo) != MOO_IOTOK_LBRACE) { set_syntax_error (moo, MOO_SYNERR_LBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo)); - return -1; + goto oops; } MOO_INFO2 (moo, "Defining a pool dictionary %.*js\n", moo->c->cls.fqn.len, moo->c->cls.fqn.ptr); - GET_TOKEN (moo); + GET_TOKEN_GOTO (moo, oops); while (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT) { lit = moo_makesymbol (moo, TOKEN_NAME_PTR(moo), TOKEN_NAME_LEN(moo)); - if (!lit || add_to_array_literal_buffer (moo, lit) <= -1) return -1; + if (!lit || add_to_array_literal_buffer (moo, lit) <= -1) goto oops; - GET_TOKEN (moo); + GET_TOKEN_GOTO (moo, oops); if (TOKEN_TYPE(moo) != MOO_IOTOK_ASSIGN) { set_syntax_error (moo, MOO_SYNERR_ASSIGN, TOKEN_LOC(moo), TOKEN_NAME(moo)); - return -1; + goto oops; } - GET_TOKEN (moo); + GET_TOKEN_GOTO (moo, oops); /* [NOTE] * values assigned to a pool dictinary member are not read-only * unlike the default initial values defined in a class */ lit = token_to_literal (moo, 0); - if (!lit) return -1; + if (!lit) goto oops; /* for this definition, #pooldic MyPoolDic { a := 10. b := 20 }, * arlit_buffer contains (#a 10 #b 20) when the 'while' loop is over. */ - if (add_to_array_literal_buffer(moo, lit) <= -1) return -1; - GET_TOKEN (moo); + if (add_to_array_literal_buffer(moo, lit) <= -1) goto oops; + GET_TOKEN_GOTO (moo, oops); /*if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE) goto done; else*/ if (TOKEN_TYPE(moo) != MOO_IOTOK_PERIOD) { set_syntax_error (moo, MOO_SYNERR_PERIOD, TOKEN_LOC(moo), TOKEN_NAME(moo)); - return -1; + goto oops; } - GET_TOKEN (moo); + GET_TOKEN_GOTO (moo, oops); } if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACE) { set_syntax_error (moo, MOO_SYNERR_RBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo)); - return -1; + goto oops; } /*done:*/ - GET_TOKEN (moo); + GET_TOKEN_GOTO (moo, oops); - tally = moo->c->mth.arlit_count / 2; + tally = (moo->c->arlit.count - saved_arlit_count) / 2; /*TODO: tally and arlit_count range check */ /*if (!MOO_IN_SMOOI_RANGE(tally)) ERROR??*/ moo->c->cls.pooldic_oop = moo_makedic (moo, moo->_pool_dictionary, MOO_ALIGN(tally + 10, POOL_DICTIONARY_SIZE_ALIGN)); - if (!moo->c->cls.pooldic_oop) return -1; + if (!moo->c->cls.pooldic_oop) goto oops; - for (i = 0; i < moo->c->mth.arlit_count; i += 2) + for (i = saved_arlit_count; i < moo->c->arlit.count; i += 2) { /* TODO: handle duplicate keys? */ - if (!moo_putatdic(moo, moo->c->cls.pooldic_oop, moo->c->mth.arlit[i], moo->c->mth.arlit[i + 1])) return -1; + if (!moo_putatdic(moo, moo->c->cls.pooldic_oop, moo->c->arlit.ptr[i], moo->c->arlit.ptr[i + 1])) goto oops; } /* eveything seems ok. register the pool dictionary to the main * system dictionary or to the name space it belongs to */ lit = moo_makesymbol (moo, moo->c->cls.name.ptr, moo->c->cls.name.len); - if (!lit || !moo_putatdic (moo, moo->c->cls.ns_oop, lit, (moo_oop_t)moo->c->cls.pooldic_oop)) return -1; + if (!lit || !moo_putatdic (moo, moo->c->cls.ns_oop, lit, (moo_oop_t)moo->c->cls.pooldic_oop)) goto oops; + + moo->c->arlit.count = saved_arlit_count; return 0; + +oops: + moo->c->arlit.count = saved_arlit_count; + return -1; } static int compile_pooldic_definition (moo_t* moo) @@ -7405,24 +7327,181 @@ static int compile_pooldic_definition (moo_t* moo) MOO_MEMSET (&moo->c->cls.fqn_loc, 0, MOO_SIZEOF(moo->c->cls.fqn_loc)); moo->c->cls.pooldic_oop = MOO_NULL; moo->c->cls.ns_oop = MOO_NULL; - moo->c->mth.balit_count = 0; - moo->c->mth.arlit_count = 0; + moo->c->balit.count = 0; + moo->c->arlit.count = 0; +#if 0 /* these 2 are pooldic import information. pooldic definition doesn't * have another pooldic import in it */ - moo->c->cls.pooldic_count = 0; - moo->c->cls.pooldic.len = 0; + moo->c->cls.pooldic_imp.dcl_count = 0; + moo->c->cls.pooldic_imp.dcl.len = 0; +#endif n = __compile_pooldic_definition (moo); /* reset these oops plus literal pointers not to confuse gc_compiler() */ moo->c->cls.pooldic_oop = MOO_NULL; moo->c->cls.ns_oop = MOO_NULL; - moo->c->mth.balit_count = 0; - moo->c->mth.arlit_count = 0; - MOO_ASSERT (moo, moo->c->cls.pooldic_count == 0); - MOO_ASSERT (moo, moo->c->cls.pooldic.len == 0); + MOO_ASSERT (moo, n <= -1 || (n >= 0 && moo->c->balit.count == 0)); + moo->c->balit.count = 0; + +MOO_DEBUG2 (moo, "XXXXXXXXXXXXXXX %d %d\n", (int)n, (int)moo->c->arlit.count); + MOO_ASSERT (moo, n <= -1 || (n >= 0 && moo->c->arlit.count == 0)); + moo->c->arlit.count = 0; + +#if 0 + MOO_ASSERT (moo, moo->c->cls.pooldic_imp.dcl_count == 0); + MOO_ASSERT (moo, moo->c->cls.pooldic_imp.dcl.len == 0); +#endif + + return n; +} + +static int __compile_pooldic_definition_in_class (moo_t* moo, moo_pooldic_t* pd) +{ + moo_oop_t lit; + moo_ooi_t tally; + moo_oow_t i; + moo_oow_t saved_arlit_count; + + saved_arlit_count = moo->c->arlit.count; + +/* TODO: if calling from within a class, MOO_IOTOK_IDENT_DOTTED must be disallowed */ + if (TOKEN_TYPE(moo) != MOO_IOTOK_IDENT && + TOKEN_TYPE(moo) != MOO_IOTOK_IDENT_DOTTED) + { + set_syntax_error (moo, MOO_SYNERR_IDENT, TOKEN_LOC(moo), TOKEN_NAME(moo)); + goto oops; + } + + if (set_pooldic_fqn(moo, pd, TOKEN_NAME(moo)) <= -1) goto oops; + pd->fqn_loc = moo->c->tok.loc; + + if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED) + { + if (preprocess_dotted_name(moo, 0, MOO_NULL, &pd->fqn, &pd->fqn_loc, &pd->name, &pd->ns_oop) <= -1) goto oops; + } + else + { + pd->ns_oop = moo->sysdic; + } + + if (moo_lookupdic (moo, pd->ns_oop, &pd->name)) + { + /* a conflicting entry has been found */ + set_syntax_error (moo, MOO_SYNERR_POOLDICDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + goto oops; + } + + GET_TOKEN (moo); + if (TOKEN_TYPE(moo) != MOO_IOTOK_LBRACE) + { + set_syntax_error (moo, MOO_SYNERR_LBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo)); + goto oops; + } + + MOO_INFO2 (moo, "Defining a pool dictionary %.*js\n", pd->fqn.len, pd->fqn.ptr); + + GET_TOKEN (moo); + + while (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT) + { + lit = moo_makesymbol (moo, TOKEN_NAME_PTR(moo), TOKEN_NAME_LEN(moo)); + if (!lit || add_to_array_literal_buffer (moo, lit) <= -1) goto oops; + + GET_TOKEN (moo); + + if (TOKEN_TYPE(moo) != MOO_IOTOK_ASSIGN) + { + set_syntax_error (moo, MOO_SYNERR_ASSIGN, TOKEN_LOC(moo), TOKEN_NAME(moo)); + goto oops; + } + + GET_TOKEN (moo); + + /* [NOTE] + * values assigned to a pool dictinary member are not read-only + * unlike the default initial values defined in a class */ + lit = token_to_literal (moo, 0); + if (!lit) goto oops; + + /* for this definition, #pooldic MyPoolDic { a := 10. b := 20 }, + * arlit_buffer contains (#a 10 #b 20) when the 'while' loop is over. */ + if (add_to_array_literal_buffer(moo, lit) <= -1) goto oops; + GET_TOKEN (moo); + + /*if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE) goto done; + else*/ if (TOKEN_TYPE(moo) != MOO_IOTOK_PERIOD) + { + set_syntax_error (moo, MOO_SYNERR_PERIOD, TOKEN_LOC(moo), TOKEN_NAME(moo)); + goto oops; + } + + GET_TOKEN (moo); + } + + + if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACE) + { + set_syntax_error (moo, MOO_SYNERR_RBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo)); + goto oops; + } + +/*done:*/ + GET_TOKEN (moo); + + tally = (moo->c->arlit.count - saved_arlit_count) / 2; +/*TODO: tally and arlit_count range check */ + /*if (!MOO_IN_SMOOI_RANGE(tally)) ERROR??*/ + + moo->c->cls.pooldic_oop = moo_makedic (moo, moo->_pool_dictionary, MOO_ALIGN(tally + 10, POOL_DICTIONARY_SIZE_ALIGN)); + if (!moo->c->cls.pooldic_oop) goto oops; + + for (i = saved_arlit_count; i < moo->c->arlit.count; i += 2) + { + /* TODO: handle duplicate keys? */ + if (!moo_putatdic(moo, moo->c->cls.pooldic_oop, moo->c->arlit.ptr[i], moo->c->arlit.ptr[i + 1])) goto oops; + } + + /* eveything seems ok. register the pool dictionary to the main + * system dictionary or to the name space it belongs to */ + lit = moo_makesymbol (moo, pd->name.ptr, pd->name.len); + if (!lit || !moo_putatdic (moo, pd->ns_oop, lit, (moo_oop_t)pd->pd_oop)) goto oops; + + moo->c->arlit.count = saved_arlit_count; + return 0; + +oops: + moo->c->arlit.count = saved_arlit_count; + return -1; +} + +static int compile_pooldic_definition_in_class (moo_t* moo, moo_pooldic_t* pd) +{ + int n; + + pd->name.len = 0; + pd->fqn.len = 0; + MOO_MEMSET (&pd->fqn_loc, 0, MOO_SIZEOF(pd->fqn_loc)); + + pd->pd_oop = MOO_NULL; + pd->ns_oop = MOO_NULL; + + moo->c->balit.count = 0; + moo->c->arlit.count = 0; + + n = __compile_pooldic_definition_in_class (moo, pd); + + /* reset these oops plus literal pointers not to confuse gc_compiler() */ + pd->pd_oop = MOO_NULL; + pd->ns_oop = MOO_NULL; + + MOO_ASSERT (moo, n <= -1 || (n >= 0 && moo->c->balit.count == 0)); + moo->c->balit.count = 0; + + MOO_ASSERT (moo, n <= -1 || (n >= 0 && moo->c->arlit.count == 0)); + moo->c->arlit.count = 0; return n; } @@ -7520,20 +7599,20 @@ static void gc_compiler (moo_t* moo) moo->c->cls.superns_oop = (moo_oop_set_t)x; } - for (i = 0; i < moo->c->cls.pooldic_count; i++) + for (i = 0; i < moo->c->cls.pooldic_imp.dcl_count; i++) { - register moo_oop_t x = moo_moveoop (moo, (moo_oop_t)moo->c->cls.pooldic_imp_oops[i]); - moo->c->cls.pooldic_imp_oops[i] = (moo_oop_set_t)x; + register moo_oop_t x = moo_moveoop (moo, (moo_oop_t)moo->c->cls.pooldic_imp.oops[i]); + moo->c->cls.pooldic_imp.oops[i] = (moo_oop_set_t)x; } - for (i = 0; i < moo->c->mth.literal_count; i++) + for (i = 0; i < moo->c->mth.literals.count; i++) { - moo->c->mth.literals[i] = moo_moveoop (moo, moo->c->mth.literals[i]); + moo->c->mth.literals.ptr[i] = moo_moveoop (moo, moo->c->mth.literals.ptr[i]); } - for (i = 0; i < moo->c->mth.arlit_count; i++) + for (i = 0; i < moo->c->arlit.count; i++) { - moo->c->mth.arlit[i] = moo_moveoop (moo, moo->c->mth.arlit[i]); + moo->c->arlit.ptr[i] = moo_moveoop (moo, moo->c->arlit.ptr[i]); } } } @@ -7558,8 +7637,8 @@ static void fini_compiler (moo_t* moo) if (moo->c->cls.var[i].initv) moo_freemem (moo, moo->c->cls.var[i].initv); } - if (moo->c->cls.pooldic.ptr) moo_freemem (moo, moo->c->cls.pooldic.ptr); - if (moo->c->cls.pooldic_imp_oops) moo_freemem (moo, moo->c->cls.pooldic_imp_oops); + if (moo->c->cls.pooldic_imp.dcl.ptr) moo_freemem (moo, moo->c->cls.pooldic_imp.dcl.ptr); + if (moo->c->cls.pooldic_imp.oops) moo_freemem (moo, moo->c->cls.pooldic_imp.oops); if (moo->c->mth.text.ptr) moo_freemem (moo, moo->c->mth.text.ptr); if (moo->c->mth.assignees.ptr) moo_freemem (moo, moo->c->mth.assignees.ptr); @@ -7568,11 +7647,12 @@ static void fini_compiler (moo_t* moo) if (moo->c->mth.name.ptr) moo_freemem (moo, moo->c->mth.name.ptr); if (moo->c->mth.tmprs.ptr) moo_freemem (moo, moo->c->mth.tmprs.ptr); if (moo->c->mth.code.ptr) moo_freemem (moo, moo->c->mth.code.ptr); - if (moo->c->mth.literals) moo_freemem (moo, moo->c->mth.literals); - if (moo->c->mth.balit) moo_freemem (moo, moo->c->mth.balit); - if (moo->c->mth.arlit) moo_freemem (moo, moo->c->mth.arlit); + if (moo->c->mth.literals.ptr) moo_freemem (moo, moo->c->mth.literals.ptr); if (moo->c->mth.blk_tmprcnt) moo_freemem (moo, moo->c->mth.blk_tmprcnt); + if (moo->c->balit.ptr) moo_freemem (moo, moo->c->balit.ptr); + if (moo->c->arlit.ptr) moo_freemem (moo, moo->c->arlit.ptr); + moo_freemem (moo, moo->c); moo->c = MOO_NULL; } diff --git a/moo/lib/debug.c b/moo/lib/debug.c index 866327f..52ef1d4 100644 --- a/moo/lib/debug.c +++ b/moo/lib/debug.c @@ -49,7 +49,7 @@ void moo_dumpsymtab (moo_t* moo) void moo_dumpdic (moo_t* moo, moo_oop_set_t dic, const moo_bch_t* title) { - moo_oow_t i, j; + moo_oow_t i; moo_oop_association_t ass; MOO_DEBUG0 (moo, "--------------------------------------------\n"); diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index 0f2294b..bf29cf5 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -415,6 +415,34 @@ struct moo_loop_t moo_loop_t* next; }; +typedef struct moo_pooldic_t moo_pooldic_t; +struct moo_pooldic_t +{ + moo_oocs_t name; + moo_oocs_t fqn; + moo_oow_t fqn_capa; + moo_ioloc_t fqn_loc; + + moo_oop_set_t pd_oop; + moo_oop_set_t ns_oop; +}; + +typedef struct moo_oopbuf_t moo_oopbuf_t; +struct moo_oopbuf_t +{ + moo_oop_t* ptr; + moo_oow_t count; + moo_oow_t capa; +}; + +typedef struct moo_oobbuf_t moo_oobbuf_t; +struct moo_oobbuf_t +{ + moo_oob_t* ptr; + moo_oow_t count; + moo_oow_t capa; +}; + struct moo_compiler_t { /* input handler */ @@ -440,14 +468,22 @@ struct moo_compiler_t /* the last token read */ moo_iotok_t tok; moo_iolink_t* io_names; +#if 0 int in_array; +#endif moo_synerr_t synerr; - /* temporary space to handle an illegal character */ + /* temporary space used when dealing with an illegal character */ moo_ooch_t ilchr; moo_oocs_t ilchr_ucs; + /* workspace to use when reading byte array elements */ + moo_oobbuf_t balit; + + /* workspace space to use when reading an array */ + moo_oopbuf_t arlit; + /* information about a class being compiled */ struct { @@ -499,13 +535,20 @@ struct moo_compiler_t } var[3]; /* buffer to hold pooldic import declaration */ - moo_oocs_t pooldic; - moo_oow_t pooldic_capa; - moo_oow_t pooldic_count; + struct + { + moo_oocs_t dcl; + moo_oow_t dcl_capa; + moo_oow_t dcl_count; - /* used to hold imported pool dictionarie objects */ - moo_oop_set_t* pooldic_imp_oops; - moo_oow_t pooldic_imp_oops_capa; + /* used to hold imported pool dictionarie objects */ + moo_oop_set_t* oops; + moo_oow_t oops_capa; + } pooldic_imp; + + + /* pooldic declaration inside class */ + moo_pooldic_t pooldic; } cls; /* information about a method being comipled */ @@ -546,19 +589,8 @@ struct moo_compiler_t moo_oow_t tmpr_nargs; /* literals */ - moo_oop_t* literals; - moo_oow_t literal_count; - moo_oow_t literal_capa; + moo_oopbuf_t literals; - /* byte array elements */ - moo_oob_t* balit; - moo_oow_t balit_count; - moo_oow_t balit_capa; - - /* array elements */ - moo_oop_t* arlit; - moo_oow_t arlit_count; - moo_oow_t arlit_capa; /* 0 for no primitive, 1 for a normal primitive, 2 for a named primitive */ int pftype;