improving pooldic handling - auto-import a nested pooldic in a class

This commit is contained in:
hyunghwan.chung 2019-10-01 09:19:25 +00:00
parent e145c4742e
commit 6931d14432
4 changed files with 83 additions and 43 deletions

View File

@ -94,6 +94,42 @@ class Shader(Object) from 'shader'
} }
``` ```
### Pool dictionary
pooldic MyData
{
A := 20,
B := 30,
C := 40
}
class MyClass
{
import MyData.
method x ()
{
MyData.A dump.
C dump. // if imported, it doesn't require prefixing with MyData.
}
}
class MyClass2
{
pooldic Const
{
A := 20.
B := 30.
}
method x()
{
A dump. // the nested pooldic is auto-imported.
Const.A dump.
self.Const dump.
}
}
### Flow Control ### Flow Control
``` ```
k := if (i < 20) { 30 } else { 40 }. k := if (i < 20) { 30 } else { 40 }.

View File

@ -118,13 +118,13 @@ class MyObject(Object)
'#include error' '#include error'
'wrong pragma name' 'wrong pragma name'
'wrong namespace name' 'wrong namespace name'
'wrong pooldicimport name' 'wrong pooldic import name'
'duplicate pooldicimport name' 'duplicate pooldic import name'
'literal expected' 'literal expected'
'break or continue not within a loop' 'break or continue not within a loop'
'break or continue within a block' 'break or continue within a block'
'while expected' 'while expected'
'invalid goto target' 'invalid goto target'
'label at end' 'label at end'
). ).

View File

@ -3199,17 +3199,15 @@ static int set_class_level_variable_initv (moo_t* moo, var_type_t var_type, moo_
return 0; return 0;
} }
static MOO_INLINE int add_pooldic_import (moo_t* moo, const moo_oocs_t* name, moo_oop_dic_t pooldic_oop) static MOO_INLINE int add_pooldic_import (moo_t* moo, moo_cunit_class_t* cc, const moo_oocs_t* name, moo_oop_dic_t pooldic_oop)
{ {
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
if (cc->pdimp.dcl_count >= cc->pdimp.oops_capa) if (cc->pdimp.dcl_count >= cc->pdimp.oops_capa)
{ {
moo_oow_t new_capa; moo_oow_t new_capa;
moo_oop_dic_t* tmp; moo_oop_dic_t* tmp;
new_capa = MOO_ALIGN(cc->pdimp.oops_capa + 1, POOLDIC_OOP_BUFFER_ALIGN); new_capa = MOO_ALIGN(cc->pdimp.oops_capa + 1, POOLDIC_OOP_BUFFER_ALIGN);
tmp = moo_reallocmem(moo, cc->pdimp.oops, new_capa * MOO_SIZEOF(moo_oop_dic_t)); tmp = (moo_oop_dic_t*)moo_reallocmem(moo, cc->pdimp.oops, new_capa * MOO_SIZEOF(moo_oop_dic_t));
if (!tmp) return -1; if (!tmp) return -1;
cc->pdimp.oops_capa = new_capa; cc->pdimp.oops_capa = new_capa;
@ -3682,9 +3680,8 @@ wrong_name:
return -1; return -1;
} }
static int import_pool_dictionary (moo_t* moo, moo_oop_nsdic_t ns_oop, const moo_oocs_t* tok_lastseg, const moo_oocs_t* tok_name, const moo_ioloc_t* tok_loc) static int import_pooldic (moo_t* moo, moo_cunit_class_t* cc, moo_oop_nsdic_t ns_oop, const moo_oocs_t* tok_lastseg, const moo_oocs_t* tok_name, const moo_ioloc_t* tok_loc)
{ {
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
moo_oop_association_t ass; moo_oop_association_t ass;
moo_oow_t i; moo_oow_t i;
@ -3706,7 +3703,7 @@ static int import_pool_dictionary (moo_t* moo, moo_oop_nsdic_t ns_oop, const moo
} }
} }
if (add_pooldic_import(moo, tok_name, (moo_oop_dic_t)ass->value) <= -1) return -1; if (add_pooldic_import(moo, cc, tok_name, (moo_oop_dic_t)ass->value) <= -1) return -1;
if (copy_string_to(moo, tok_name, &cc->pdimp.dcl, &cc->pdimp.dcl_capa, 1, ' ') <= -1) if (copy_string_to(moo, tok_name, &cc->pdimp.dcl, &cc->pdimp.dcl_capa, 1, ' ') <= -1)
{ {
cc->pdimp.dcl_count--; /* roll back add_pool_dictionary() */ cc->pdimp.dcl_count--; /* roll back add_pool_dictionary() */
@ -4048,7 +4045,7 @@ static int compile_class_level_imports (moo_t* moo)
break; break;
} }
if (import_pool_dictionary(moo, ns_oop, &last, TOKEN_NAME(moo), TOKEN_LOC(moo)) <= -1) return -1; if (import_pooldic(moo, cc, ns_oop, &last, TOKEN_NAME(moo), TOKEN_LOC(moo)) <= -1) return -1;
GET_TOKEN (moo); GET_TOKEN (moo);
if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED || TOKEN_TYPE(moo) == MOO_IOTOK_IDENT) if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED || TOKEN_TYPE(moo) == MOO_IOTOK_IDENT)
@ -8317,7 +8314,7 @@ static int make_defined_class (moo_t* moo)
if (!tmp) return -1; if (!tmp) return -1;
just_made = 1; just_made = 1;
cc->self_oop = (moo_oop_class_t)tmp; MOO_STORE_OOP (moo, (moo_oop_t*)&cc->self_oop, tmp);
MOO_ASSERT (moo, MOO_CLASSOF(moo, cc->self_oop) == moo->_class); MOO_ASSERT (moo, MOO_CLASSOF(moo, cc->self_oop) == moo->_class);
@ -8331,7 +8328,7 @@ static int make_defined_class (moo_t* moo)
*/ */
MOO_OBJ_SET_FLAGS_KERNEL (cc->self_oop, MOO_OBJ_FLAGS_KERNEL_MATURE); MOO_OBJ_SET_FLAGS_KERNEL (cc->self_oop, MOO_OBJ_FLAGS_KERNEL_MATURE);
cc->self_oop->superclass = cc->super_oop; MOO_STORE_OOP (moo, &cc->self_oop->superclass, cc->super_oop);
if (just_made) if (just_made)
{ {
@ -8340,7 +8337,7 @@ static int make_defined_class (moo_t* moo)
* during ignition phase. See ignite_3() */ * during ignition phase. See ignite_3() */
tmp = moo_makesymbol(moo, cc->name.ptr, cc->name.len); tmp = moo_makesymbol(moo, cc->name.ptr, cc->name.len);
if (!tmp) return -1; if (!tmp) return -1;
cc->self_oop->name = (moo_oop_char_t)tmp; MOO_STORE_OOP (moo, (moo_oop_t*)&cc->self_oop->name, tmp);
} }
MOO_ASSERT (moo, (moo_oop_t)cc->self_oop->name != moo->_nil); MOO_ASSERT (moo, (moo_oop_t)cc->self_oop->name != moo->_nil);
@ -8349,34 +8346,32 @@ static int make_defined_class (moo_t* moo)
{ {
tmp = moo_makesymbol(moo, cc->modname.ptr, cc->modname.len); tmp = moo_makesymbol(moo, cc->modname.ptr, cc->modname.len);
if (!tmp) return -1; if (!tmp) return -1;
cc->self_oop->modname = tmp; MOO_STORE_OOP (moo, (moo_oop_t*)&cc->self_oop->modname, tmp);
} }
tmp = moo_makestring(moo, cc->var[VAR_INSTANCE].str.ptr, cc->var[VAR_INSTANCE].str.len); tmp = moo_makestring(moo, cc->var[VAR_INSTANCE].str.ptr, cc->var[VAR_INSTANCE].str.len);
if (!tmp) return -1; if (!tmp) return -1;
cc->self_oop->instvars = (moo_oop_char_t)tmp; MOO_STORE_OOP (moo, (moo_oop_t*)&cc->self_oop->instvars, tmp);
tmp = moo_makestring(moo, cc->var[VAR_CLASS].str.ptr, cc->var[VAR_CLASS].str.len); tmp = moo_makestring(moo, cc->var[VAR_CLASS].str.ptr, cc->var[VAR_CLASS].str.len);
if (!tmp) return -1; if (!tmp) return -1;
cc->self_oop->classvars = (moo_oop_char_t)tmp; MOO_STORE_OOP (moo, (moo_oop_t*)&cc->self_oop->classvars, tmp);
tmp = moo_makestring(moo, cc->var[VAR_CLASSINST].str.ptr, cc->var[VAR_CLASSINST].str.len); tmp = moo_makestring(moo, cc->var[VAR_CLASSINST].str.ptr, cc->var[VAR_CLASSINST].str.len);
if (!tmp) return -1; if (!tmp) return -1;
cc->self_oop->classinstvars = (moo_oop_char_t)tmp; MOO_STORE_OOP (moo, (moo_oop_t*)&cc->self_oop->classinstvars, tmp);
tmp = moo_makestring(moo, cc->pdimp.dcl.ptr, cc->pdimp.dcl.len); tmp = moo_makestring(moo, cc->pdimp.dcl.ptr, cc->pdimp.dcl.len);
if (!tmp) return -1; if (!tmp) return -1;
cc->self_oop->pooldics = (moo_oop_char_t)tmp; MOO_STORE_OOP (moo, (moo_oop_t*)&cc->self_oop->pooldics, tmp);
/* TOOD: good dictionary size */
tmp = (moo_oop_t)moo_makedic(moo, moo->_method_dictionary, INSTANCE_METHOD_DICTIONARY_SIZE); tmp = (moo_oop_t)moo_makedic(moo, moo->_method_dictionary, INSTANCE_METHOD_DICTIONARY_SIZE);
if (!tmp) return -1; if (!tmp) return -1;
cc->self_oop->mthdic[MOO_METHOD_INSTANCE] = (moo_oop_dic_t)tmp; MOO_STORE_OOP (moo, (moo_oop_t*)&cc->self_oop->mthdic[MOO_METHOD_INSTANCE], tmp);
/* TOOD: good dictionary size */
tmp = (moo_oop_t)moo_makedic(moo, moo->_method_dictionary, CLASS_METHOD_DICTIONARY_SIZE); tmp = (moo_oop_t)moo_makedic(moo, moo->_method_dictionary, CLASS_METHOD_DICTIONARY_SIZE);
if (!tmp) return -1; if (!tmp) return -1;
cc->self_oop->mthdic[MOO_METHOD_CLASS] = (moo_oop_dic_t)tmp; MOO_STORE_OOP (moo, (moo_oop_t*)&cc->self_oop->mthdic[MOO_METHOD_CLASS], tmp);
/* store the default intial values for instance variables */ /* store the default intial values for instance variables */
if (make_default_initial_values(moo, VAR_INSTANCE) <= -1) return -1; if (make_default_initial_values(moo, VAR_INSTANCE) <= -1) return -1;
@ -8435,7 +8430,7 @@ static int make_defined_class (moo_t* moo)
/* register the class to the system dictionary. kernel classes have /* register the class to the system dictionary. kernel classes have
* been registered at the ignition phase. */ * been registered at the ignition phase. */
if (!moo_putatdic(moo, (moo_oop_dic_t)cc->ns_oop, (moo_oop_t)cc->self_oop->name, (moo_oop_t)cc->self_oop)) return -1; if (!moo_putatdic(moo, (moo_oop_dic_t)cc->ns_oop, (moo_oop_t)cc->self_oop->name, (moo_oop_t)cc->self_oop)) return -1;
cc->self_oop->nsup = cc->ns_oop; MOO_STORE_OOP (moo, (moo_oop_t*)&cc->self_oop->nsup, (moo_oop_t)cc->ns_oop);
} }
return 0; return 0;
@ -8686,7 +8681,7 @@ static int process_class_superclass (moo_t* moo)
* 1(incomplete kernel object), * 1(incomplete kernel object),
* 2(complete kernel object) */ * 2(complete kernel object) */
cc->super_oop = var.u.gbl->value; MOO_STORE_OOP (moo, &cc->super_oop, var.u.gbl->value);
/* the superclass became known. */ /* the superclass became known. */
if (((moo_oop_class_t)cc->super_oop)->trsize != moo->_nil && if (((moo_oop_class_t)cc->super_oop)->trsize != moo->_nil &&
@ -8984,7 +8979,7 @@ static int __compile_class_definition (moo_t* moo, int class_type)
/* attach a new namespace dictionary to the nsdic field of the class */ /* attach a new namespace dictionary to the nsdic field of the class */
if (!attach_nsdic_to_class(moo, c->self_oop)) return -1; if (!attach_nsdic_to_class(moo, c->self_oop)) return -1;
} }
cc->ns_oop = c->self_oop->nsdic; /* TODO: if c->nsdic is nil, create one? */ MOO_STORE_OOP (moo, (moo_oop_t*)&cc->ns_oop, (moo_oop_t)c->self_oop->nsdic); /* TODO: if c->nsdic is nil, create one? */
} }
else if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED) else if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED)
{ {
@ -9208,7 +9203,7 @@ static int __compile_class_definition (moo_t* moo, int class_type)
ns_oop = cc->ns_oop; ns_oop = cc->ns_oop;
} }
if (import_pool_dictionary(moo, ns_oop, &last, &tok, &loc) <= -1) return -1; if (import_pooldic(moo, cc, ns_oop, &last, &tok, &loc) <= -1) return -1;
} }
while (1); while (1);
} }
@ -9751,7 +9746,7 @@ static moo_oop_t find_element_in_compiling_pooldic (moo_t* moo, const moo_oocs_t
static int __compile_pooldic_definition (moo_t* moo) static int __compile_pooldic_definition (moo_t* moo)
{ {
moo_oop_t lit; moo_oop_t tmp;
moo_ooi_t tally; moo_ooi_t tally;
moo_oow_t i; moo_oow_t i;
moo_oow_t saved_arlit_count; moo_oow_t saved_arlit_count;
@ -9792,13 +9787,14 @@ static int __compile_pooldic_definition (moo_t* moo)
if (pd->cunit_parent && pd->cunit_parent->cunit_type == MOO_CUNIT_CLASS) if (pd->cunit_parent && pd->cunit_parent->cunit_type == MOO_CUNIT_CLASS)
{ {
/* nested inside a class */
moo_cunit_class_t* c = (moo_cunit_class_t*)pd->cunit_parent; moo_cunit_class_t* c = (moo_cunit_class_t*)pd->cunit_parent;
if ((moo_oop_t)c->self_oop->nsdic == moo->_nil) if ((moo_oop_t)c->self_oop->nsdic == moo->_nil)
{ {
/* attach a new namespace dictionary to the nsdic field of the class */ /* attach a new namespace dictionary to the nsdic field of the class */
if (!attach_nsdic_to_class(moo, c->self_oop)) return -1; if (!attach_nsdic_to_class(moo, c->self_oop)) return -1;
} }
pd->ns_oop = c->self_oop->nsdic; /* TODO: if c->nsdic is nil, create one? */ MOO_STORE_OOP (moo, (moo_oop_t*)&pd->ns_oop, (moo_oop_t)c->self_oop->nsdic); /* TODO: if c->nsdic is nil, create one? */
} }
else if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED) else if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED)
{ {
@ -9806,7 +9802,7 @@ static int __compile_pooldic_definition (moo_t* moo)
} }
else else
{ {
pd->ns_oop = moo->sysdic; MOO_STORE_OOP (moo, (moo_oop_t*)&pd->ns_oop, (moo_oop_t)moo->sysdic);
} }
if (moo_lookupdic(moo, (moo_oop_dic_t)pd->ns_oop, &pd->name)) if (moo_lookupdic(moo, (moo_oop_dic_t)pd->ns_oop, &pd->name))
@ -9831,16 +9827,16 @@ static int __compile_pooldic_definition (moo_t* moo)
pd->end = moo->c->arlit.count; pd->end = moo->c->arlit.count;
while (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT) while (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT)
{ {
lit = moo_makesymbol(moo, TOKEN_NAME_PTR(moo), TOKEN_NAME_LEN(moo)); tmp = moo_makesymbol(moo, TOKEN_NAME_PTR(moo), TOKEN_NAME_LEN(moo));
if (!lit) goto oops; if (!tmp) goto oops;
if (find_in_array_literal_buffer(moo, 0, 2, lit, MOO_NULL) >= 0) if (find_in_array_literal_buffer(moo, 0, 2, tmp, MOO_NULL) >= 0)
{ {
moo_setsynerr (moo, MOO_SYNERR_NAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); moo_setsynerr (moo, MOO_SYNERR_NAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo));
goto oops; goto oops;
} }
if (add_to_array_literal_buffer(moo, lit) <= -1) goto oops; if (add_to_array_literal_buffer(moo, tmp) <= -1) goto oops;
GET_TOKEN (moo); GET_TOKEN (moo);
@ -9855,12 +9851,12 @@ static int __compile_pooldic_definition (moo_t* moo)
/* [NOTE] /* [NOTE]
* values assigned to a pool dictinary member are not read-only * values assigned to a pool dictinary member are not read-only
* unlike the default initial values defined in a class */ * unlike the default initial values defined in a class */
lit = token_to_literal(moo, 0); tmp = token_to_literal(moo, 0);
if (!lit) goto oops; if (!tmp) goto oops;
/* for this definition, #pooldic MyPoolDic { a := 10. b := 20 }, /* for this definition, #pooldic MyPoolDic { a := 10. b := 20 },
* arlit_buffer contains (#a 10 #b 20) when the 'while' loop is over. */ * arlit_buffer contains (#a 10 #b 20) when the 'while' loop is over. */
if (add_to_array_literal_buffer(moo, lit) <= -1) goto oops; if (add_to_array_literal_buffer(moo, tmp) <= -1) goto oops;
pd->end = moo->c->arlit.count; pd->end = moo->c->arlit.count;
GET_TOKEN (moo); GET_TOKEN (moo);
@ -9897,8 +9893,10 @@ done:
/*TODO: tally and arlit_count range check */ /*TODO: tally and arlit_count range check */
/*if (!MOO_IN_SMOOI_RANGE(tally)) ERROR??*/ /*if (!MOO_IN_SMOOI_RANGE(tally)) ERROR??*/
pd->pd_oop = moo_makedic(moo, moo->_pool_dictionary, MOO_ALIGN(tally + 10, POOL_DICTIONARY_SIZE_ALIGN)); tmp = (moo_oop_t)moo_makedic(moo, moo->_pool_dictionary, MOO_ALIGN(tally + 10, POOL_DICTIONARY_SIZE_ALIGN));
if (!pd->pd_oop) goto oops; if (!tmp) goto oops;
MOO_STORE_OOP (moo, (moo_oop_t*)&pd->pd_oop, tmp);
for (i = saved_arlit_count; i < moo->c->arlit.count; i += 2) for (i = saved_arlit_count; i < moo->c->arlit.count; i += 2)
{ {
/* TODO: handle duplicate keys? */ /* TODO: handle duplicate keys? */
@ -9907,8 +9905,14 @@ done:
/* eveything seems ok. register the pool dictionary to the main /* eveything seems ok. register the pool dictionary to the main
* system dictionary or to the name space it belongs to */ * system dictionary or to the name space it belongs to */
lit = moo_makesymbol(moo, pd->name.ptr, pd->name.len); tmp = moo_makesymbol(moo, pd->name.ptr, pd->name.len);
if (!lit || !moo_putatdic(moo, (moo_oop_dic_t)pd->ns_oop, lit, (moo_oop_t)pd->pd_oop)) goto oops; if (!tmp || !moo_putatdic(moo, (moo_oop_dic_t)pd->ns_oop, tmp, (moo_oop_t)pd->pd_oop)) goto oops;
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;
}
moo->c->arlit.count = saved_arlit_count; moo->c->arlit.count = saved_arlit_count;
return 0; return 0;

View File

@ -143,8 +143,8 @@ static moo_ooch_t synerrstr_67[] = {'f','a','i','l','e','d',' ','t','o',' ','i',
static moo_ooch_t synerrstr_68[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'}; static moo_ooch_t synerrstr_68[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'};
static moo_ooch_t synerrstr_69[] = {'w','r','o','n','g',' ','p','r','a','g','m','a',' ','n','a','m','e','\0'}; static moo_ooch_t synerrstr_69[] = {'w','r','o','n','g',' ','p','r','a','g','m','a',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_70[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'}; static moo_ooch_t synerrstr_70[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_71[] = {'w','r','o','n','g',' ','p','o','o','l','d','i','c','i','m','p','o','r','t',' ','n','a','m','e','\0'}; static moo_ooch_t synerrstr_71[] = {'w','r','o','n','g',' ','p','o','o','l','d','i','c',' ','i','m','p','o','r','t',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_72[] = {'d','u','p','l','i','c','a','t','e',' ','p','o','o','l','d','i','c','i','m','p','o','r','t',' ','n','a','m','e','\0'}; static moo_ooch_t synerrstr_72[] = {'d','u','p','l','i','c','a','t','e',' ','p','o','o','l','d','i','c',' ','i','m','p','o','r','t',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_73[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'}; static moo_ooch_t synerrstr_73[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_74[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','n','o','t',' ','w','i','t','h','i','n',' ','a',' ','l','o','o','p','\0'}; static moo_ooch_t synerrstr_74[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','n','o','t',' ','w','i','t','h','i','n',' ','a',' ','l','o','o','p','\0'};
static moo_ooch_t synerrstr_75[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','w','i','t','h','i','n',' ','a',' ','b','l','o','c','k','\0'}; static moo_ooch_t synerrstr_75[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','w','i','t','h','i','n',' ','a',' ','b','l','o','c','k','\0'};