changed find_dotted_ident() and find_undotted_ident()

This commit is contained in:
hyunghwan.chung 2019-10-03 10:30:05 +00:00
parent 209c6bf691
commit e1d71f340e

View File

@ -260,7 +260,6 @@ static int compile_class_definition (moo_t* moo, int class_type);
static int compile_block_statement (moo_t* moo); static int compile_block_statement (moo_t* moo);
static int compile_method_statement (moo_t* moo); static int compile_method_statement (moo_t* moo);
static int compile_method_expression (moo_t* moo, int pop); static int compile_method_expression (moo_t* moo, int pop);
static MOO_INLINE int add_literal (moo_t* moo, moo_oop_t lit, moo_oow_t* index);
static moo_oop_t token_to_literal (moo_t* moo, int rdonly); static moo_oop_t token_to_literal (moo_t* moo, int rdonly);
static moo_oop_t find_element_in_compiling_pooldic (moo_t* moo, const moo_oocs_t* name); static moo_oop_t find_element_in_compiling_pooldic (moo_t* moo, const moo_oocs_t* name);
@ -2432,6 +2431,94 @@ static int end_include (moo_t* moo)
return 1; /* ended the included file successfully */ return 1; /* ended the included file successfully */
} }
/* ---------------------------------------------------------------------
* Literal
* --------------------------------------------------------------------- */
static MOO_INLINE int add_literal (moo_t* moo, moo_oop_t lit, moo_oow_t* index)
{
#if 0
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
moo_oow_t i;
for (i = 0; i < cc->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 (cc->mth.literals.ptr[i] == lit)
{
*index = i;
return 0;
}
}
if (add_oop_to_oopbuf(moo, &cc->mth.literals, lit) <= -1) return -1;
*index = cc->mth.literals.count - 1;
return 0;
#else
/*
* this removes redundancy of symbols, characters, and small integers.
* more complex redundacy check may be done somewhere else like
* in add_string_literal().
*/
return add_oop_to_oopbuf_nodup(moo, &((moo_cunit_class_t*)moo->c->cunit)->mth.literals, lit, index);
#endif
}
static int add_string_literal (moo_t* moo, const moo_oocs_t* str, moo_oow_t* index)
{
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
moo_oop_t lit;
moo_oow_t i;
for (i = 0; i < cc->mth.literals.count; i++)
{
lit = cc->mth.literals.ptr[i];
if (MOO_CLASSOF(moo, lit) == moo->_string &&
MOO_OBJ_GET_SIZE(lit) == str->len &&
moo_equal_oochars(MOO_OBJ_GET_CHAR_SLOT(lit), str->ptr, str->len))
{
*index = i;
return 0;
}
}
lit = moo_instantiate(moo, moo->_string, str->ptr, str->len);
if (!lit) return -1;
MOO_OBJ_SET_FLAGS_RDONLY (lit, 1);
return add_literal(moo, lit, index);
}
static int add_symbol_literal (moo_t* moo, const moo_oocs_t* str, moo_oow_t offset, moo_oow_t* index)
{
moo_oop_t tmp;
tmp = moo_makesymbol(moo, str->ptr + offset, str->len - offset);
if (!tmp) return -1;
MOO_OBJ_SET_FLAGS_RDONLY (tmp, 1);
return add_literal(moo, tmp, index);
}
static int add_byte_array_literal (moo_t* moo, const moo_oocs_t* str, moo_oow_t* index)
{
/* see read_byte_array_literal for comparision */
moo_oop_t tmp;
moo_oow_t i;
tmp = moo_instantiate(moo, moo->_byte_array, MOO_NULL, str->len);
if (!tmp) return -1;
for (i = 0; i < str->len; i++) MOO_OBJ_SET_BYTE_VAL(tmp, i, str->ptr[i]);
MOO_OBJ_SET_FLAGS_RDONLY (tmp, 1);
return add_literal(moo, tmp, index);
}
/* --------------------------------------------------------------------- /* ---------------------------------------------------------------------
* Byte-Code Manipulation Functions * Byte-Code Manipulation Functions
* --------------------------------------------------------------------- */ * --------------------------------------------------------------------- */
@ -3006,90 +3093,6 @@ static void eliminate_instructions (moo_t* moo, moo_oow_t start, moo_oow_t end)
* Compiler * Compiler
* --------------------------------------------------------------------- */ * --------------------------------------------------------------------- */
static MOO_INLINE int add_literal (moo_t* moo, moo_oop_t lit, moo_oow_t* index)
{
#if 0
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
moo_oow_t i;
for (i = 0; i < cc->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 (cc->mth.literals.ptr[i] == lit)
{
*index = i;
return 0;
}
}
if (add_oop_to_oopbuf(moo, &cc->mth.literals, lit) <= -1) return -1;
*index = cc->mth.literals.count - 1;
return 0;
#else
/*
* this removes redundancy of symbols, characters, and small integers.
* more complex redundacy check may be done somewhere else like
* in add_string_literal().
*/
return add_oop_to_oopbuf_nodup(moo, &((moo_cunit_class_t*)moo->c->cunit)->mth.literals, lit, index);
#endif
}
static int add_string_literal (moo_t* moo, const moo_oocs_t* str, moo_oow_t* index)
{
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
moo_oop_t lit;
moo_oow_t i;
for (i = 0; i < cc->mth.literals.count; i++)
{
lit = cc->mth.literals.ptr[i];
if (MOO_CLASSOF(moo, lit) == moo->_string &&
MOO_OBJ_GET_SIZE(lit) == str->len &&
moo_equal_oochars(MOO_OBJ_GET_CHAR_SLOT(lit), str->ptr, str->len))
{
*index = i;
return 0;
}
}
lit = moo_instantiate(moo, moo->_string, str->ptr, str->len);
if (!lit) return -1;
MOO_OBJ_SET_FLAGS_RDONLY (lit, 1);
return add_literal(moo, lit, index);
}
static int add_symbol_literal (moo_t* moo, const moo_oocs_t* str, moo_oow_t offset, moo_oow_t* index)
{
moo_oop_t tmp;
tmp = moo_makesymbol(moo, str->ptr + offset, str->len - offset);
if (!tmp) return -1;
MOO_OBJ_SET_FLAGS_RDONLY (tmp, 1);
return add_literal(moo, tmp, index);
}
static int add_byte_array_literal (moo_t* moo, const moo_oocs_t* str, moo_oow_t* index)
{
/* see read_byte_array_literal for comparision */
moo_oop_t tmp;
moo_oow_t i;
tmp = moo_instantiate(moo, moo->_byte_array, MOO_NULL, str->len);
if (!tmp) return -1;
for (i = 0; i < str->len; i++) MOO_OBJ_SET_BYTE_VAL(tmp, i, str->ptr[i]);
MOO_OBJ_SET_FLAGS_RDONLY (tmp, 1);
return add_literal(moo, tmp, index);
}
static MOO_INLINE int set_class_fqn (moo_t* moo, moo_cunit_class_t* cc, const moo_oocs_t* name) static MOO_INLINE int set_class_fqn (moo_t* moo, moo_cunit_class_t* cc, const moo_oocs_t* name)
{ {
if (copy_string_to(moo, name, &cc->fqn, &cc->fqn_capa, 0, '\0') <= -1) return -1; if (copy_string_to(moo, name, &cc->fqn, &cc->fqn_capa, 0, '\0') <= -1) return -1;
@ -4611,32 +4614,61 @@ static MOO_INLINE int find_dotted_ident (moo_t* moo, const moo_oocs_t* name, con
} }
} }
if (!cc->self_oop) goto varinacc;
top_dic = cc->self_oop->nsdic; /* namespace that the current interface starts */
pxlen++; /* include . into the length */
break; break;
} }
case MOO_CUNIT_INTERFACE: case MOO_CUNIT_INTERFACE:
default: {
/* interface doesn't support inheritance nor does it allow moo_cunit_interface_t* ifce = (moo_cunit_interface_t*)moo->c->cunit;
* method body. let it flow down to the next check to if (!ifce->self_oop) goto varinacc;
* trigger an error(MOO_SYNERR_VARINACC below) */ top_dic = ifce->self_oop->nsdic; /* namespace that the current interface starts */
pxlen++; /* include . into the length */
break; break;
} }
}
if (moo->c->cunit->cunit_type != MOO_CUNIT_CLASS || !((moo_cunit_class_t*)moo->c->cunit)->self_oop) default:
{ varinacc:
/* self is not usable when it's not compiling in a class.
* a pooldic definition cannot contain subdictionaries.
* the pooldic is a terminal point and the items inside
* are final nodes. if self is followed by more than 1
* subsegments, it's an error */
moo_setsynerr (moo, MOO_SYNERR_VARINACC, name_loc, name); moo_setsynerr (moo, MOO_SYNERR_VARINACC, name_loc, name);
return -1; return -1;
} }
}
else
{
/* more than 3 segments. e.g. self.XXX.YYY */
switch (moo->c->cunit->cunit_type)
{
case MOO_CUNIT_POOLDIC:
/* a pooldic definition cannot contain subdictionaries.
* the pooldic is a terminal point and the items inside
* are final nodes. if self is followed by more than 1
* subsegments, it's an error. */
goto varinacc;
/* namespace that the current class starts */ case MOO_CUNIT_CLASS:
top_dic = ((moo_cunit_class_t*)moo->c->cunit)->self_oop->nsdic; {
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
if (!cc->self_oop) goto varinacc;
top_dic = cc->self_oop->nsdic; /* namespace that the current class starts */
pxlen++; /* include . into the length */ pxlen++; /* include . into the length */
break;
}
case MOO_CUNIT_INTERFACE:
{
moo_cunit_interface_t* ifce = (moo_cunit_interface_t*)moo->c->cunit;
if (!ifce->self_oop) goto varinacc;
top_dic = ifce->self_oop->nsdic; /* namespace that the current interface starts */
pxlen++; /* include . into the length */
break;
}
default:
goto varinacc;
}
}
} }
else if ((pxlen = is_dotted_ident_prefixed(name, VOCA_SELFNS)) > 0) else if ((pxlen = is_dotted_ident_prefixed(name, VOCA_SELFNS)) > 0)
{ {
@ -4695,7 +4727,9 @@ static MOO_INLINE int find_undotted_ident (moo_t* moo, const moo_oocs_t* name, c
moo_oow_t index; moo_oow_t index;
moo_oop_association_t ass; moo_oop_association_t ass;
if (moo->c->cunit->cunit_type == MOO_CUNIT_POOLDIC) switch (moo->c->cunit->cunit_type)
{
case MOO_CUNIT_POOLDIC:
{ {
moo_oop_t v; moo_oop_t v;
@ -4712,11 +4746,13 @@ static MOO_INLINE int find_undotted_ident (moo_t* moo, const moo_oocs_t* name, c
var->type = VAR_LITERAL; var->type = VAR_LITERAL;
var->u.lit = v; /* TODO: change this */ var->u.lit = v; /* TODO: change this */
break;
} }
else
case MOO_CUNIT_CLASS:
{ {
moo_cunit_class_t* cc = ((moo_cunit_class_t*)moo->c->cunit); moo_cunit_class_t* cc = ((moo_cunit_class_t*)moo->c->cunit);
MOO_ASSERT (moo, moo->c->cunit->cunit_type == MOO_CUNIT_CLASS);
if (cc->self_oop) if (cc->self_oop)
{ {
@ -4790,6 +4826,52 @@ static MOO_INLINE int find_undotted_ident (moo_t* moo, const moo_oocs_t* name, c
var->type = VAR_GLOBAL; var->type = VAR_GLOBAL;
var->u.gbl = ass; var->u.gbl = ass;
break;
}
case MOO_CUNIT_INTERFACE:
{
/* TODO: */
moo_cunit_interface_t* ifce = ((moo_cunit_interface_t*)moo->c->cunit);
if (ifce->self_oop)
{
/* the current class being compiled has been instantiated.
* look up in the temporary variable list if compiling in a method */
if (ifce->mth.active && find_temporary_variable(moo, &ifce->mth, name, &index) >= 0)
{
var->type = (index < ifce->mth.tmpr_nargs)? VAR_ARGUMENT: VAR_TEMPORARY;
var->pos = index;
return 0;
}
}
if (ifce->ns_oop)
{
ass = moo_lookupdic(moo, (moo_oop_dic_t)ifce->ns_oop, name); /* in the current name space */
if (!ass && ifce->ns_oop != moo->sysdic)
ass = moo_lookupdic(moo, (moo_oop_dic_t)moo->sysdic, name); /* in the top-level system dictionary */
}
else
{
ass = moo_lookupdic(moo, (moo_oop_dic_t)moo->sysdic, name); /* in the top-level system dictionary */
}
if (!ass)
{
moo_setsynerr (moo, MOO_SYNERR_VARUNDCL, name_loc, name);
return -1;
}
var->type = VAR_GLOBAL;
var->u.gbl = ass;
break;
}
default:
/* it must not happen. internal error if it happens */
moo_setsynerr (moo, MOO_SYNERR_VARINACC, name_loc, name);
return -1;
} }
return 0; return 0;