got rid of 'const' handling code attempted.

cleaned up pooldic handling code more.
made a pooldic item value read-only by default
This commit is contained in:
hyunghwan.chung 2019-10-02 09:34:43 +00:00
parent 9ba623d5a0
commit cdd8d7f890
2 changed files with 107 additions and 134 deletions

View File

@ -102,7 +102,7 @@ pooldic MyData
C := 40 C := 40
} }
class MyClass class MyClass(Object)
{ {
import MyData. import MyData.
@ -114,12 +114,12 @@ class MyClass
} }
class MyClass2 class MyClass2(Object)
{ {
pooldic Const pooldic Const
{ {
A := 20. A := 20,
B := 30. B := 30
} }
method x() method x()
@ -130,6 +130,29 @@ class MyClass2
} }
} }
class MyClass3(MyClass2)
{
pooldic Const
{
A := MyClass2.Const.A // pooldic is not inherited. need redefinition for auto-import
B := MyClass2.Const.B
}
}
class MyClass4(MyClass2)
{
import MyClass2.Const. // similar to redefinition inside the class. it won't be available MyClass4.Const as such is not available.
method x
{
MyClass2.Const at: #XXX put: 'QQQQQQQQQQQQQQ'. // you can add a new item dynamically,
(MyClass2.Const at: #XXX) dump. // and can access it.
// the compiler doesn't recognize the dynamically added item as MyClass2.Const.XXX
}
}
### Flow Control ### Flow Control
``` ```
k := if (i < 20) { 30 } else { 40 }. k := if (i < 20) { 30 } else { 40 }.

View File

@ -119,7 +119,6 @@ static struct voca_t
{ 5, { 'c','l','a','s','s' } }, { 5, { 'c','l','a','s','s' } },
{ 6, { '#','c','l','a','s','s' } }, { 6, { '#','c','l','a','s','s' } },
{ 10, { '#','c','l','a','s','s','i','n','s','t' } }, { 10, { '#','c','l','a','s','s','i','n','s','t' } },
{ 5, { 'c','o','n','s','t' } },
{ 8, { 'c','o','n','t','i','n','u','e' } }, { 8, { 'c','o','n','t','i','n','u','e' } },
{ 2, { 'd','o' } }, { 2, { 'd','o' } },
{ 5, { '#','d','u','a','l' } }, { 5, { '#','d','u','a','l' } },
@ -190,7 +189,6 @@ enum voca_id_t
VOCA_CLASS, VOCA_CLASS,
VOCA_CLASS_S, VOCA_CLASS_S,
VOCA_CLASSINST_S, VOCA_CLASSINST_S,
VOCA_CONST,
VOCA_CONTINUE, VOCA_CONTINUE,
VOCA_DO, VOCA_DO,
VOCA_DUAL_S, VOCA_DUAL_S,
@ -435,7 +433,6 @@ static int is_restricted_word (const moo_oocs_t* ucs)
static int rw[] = static int rw[] =
{ {
VOCA_CLASS, VOCA_CLASS,
VOCA_CONST,
VOCA_EXTEND, VOCA_EXTEND,
VOCA_FROM, VOCA_FROM,
VOCA_IMPORT, VOCA_IMPORT,
@ -4077,73 +4074,6 @@ static int compile_class_level_imports (moo_t* moo)
return 0; return 0;
} }
static int compile_class_level_consts (moo_t* moo)
{
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
do
{
if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT)
{
/* TODO: */
#if 0
if (add_class_level_const(moo, TOKEN_NAME(moo), TOKEN_LOC(moo)) <= -1) return -1;
GET_TOKEN (moo);
if (TOKEN_TYPE(moo) == MOO_IOTOK_ASSIGN)
{
moo_oop_t lit;
GET_TOKEN (moo);
/* only a single literal token is allowed as a value for now.
* TODO: extend to support simple constant expression */
lit = token_to_literal(moo, 1);
if (!lit) return -1;
if (set_class_level_const_value(moo, cc->_const.count - 1, lit) <= -1) return -1;
GET_TOKEN (moo);
}
else
{
moo_setsynerr (moo, MOO_SYNERR_ASSIGN, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
#endif
}
else if (TOKEN_TYPE(moo) == MOO_IOTOK_COMMA || TOKEN_TYPE(moo) == MOO_IOTOK_EOF || TOKEN_TYPE(moo) == MOO_IOTOK_PERIOD)
{
/* no constant name is present */
moo_setsynerrbfmt (moo, MOO_SYNERR_IDENT, TOKEN_LOC(moo), TOKEN_NAME(moo), "constant name expected");
return -1;
}
else
{
break;
}
if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT)
{
moo_setsynerr (moo, MOO_SYNERR_COMMA, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
else if (TOKEN_TYPE(moo) != MOO_IOTOK_COMMA) break; /* hopefully . */
GET_TOKEN (moo);
}
while (1);
if (TOKEN_TYPE(moo) != MOO_IOTOK_PERIOD)
{
moo_setsynerr (moo, MOO_SYNERR_PERIOD, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
GET_TOKEN (moo);
return 0;
}
static int compile_unary_method_name (moo_t* moo, moo_method_data_t* mth) static int compile_unary_method_name (moo_t* moo, moo_method_data_t* mth)
{ {
MOO_ASSERT (moo, mth->name.len == 0); MOO_ASSERT (moo, mth->name.len == 0);
@ -4630,53 +4560,66 @@ static MOO_INLINE int find_dotted_ident (moo_t* moo, const moo_oocs_t* name, con
MOO_ASSERT (moo, moo->c->cunit != MOO_NULL); MOO_ASSERT (moo, moo->c->cunit != MOO_NULL);
if (moo->c->cunit->cunit_type == MOO_CUNIT_POOLDIC) switch (moo->c->cunit->cunit_type)
{ {
moo_oop_t v; case MOO_CUNIT_POOLDIC:
/* called inside a pooldic definition */
MOO_ASSERT (moo, ((moo_cunit_pooldic_t*)moo->c->cunit)->ns_oop != MOO_NULL);
MOO_ASSERT (moo, ((moo_cunit_pooldic_t*)moo->c->cunit)->pd_oop == MOO_NULL);
v = find_element_in_compiling_pooldic(moo, &last);
if (!v)
{ {
moo_setsynerr (moo, MOO_SYNERR_VARUNDCL, name_loc, name); moo_oop_t v;
return -1;
}
var->type = VAR_LITERAL; /* called inside a pooldic definition */
var->u.lit = v; /* TODO: change this */ MOO_ASSERT (moo, ((moo_cunit_pooldic_t*)moo->c->cunit)->ns_oop != MOO_NULL);
return 0; MOO_ASSERT (moo, ((moo_cunit_pooldic_t*)moo->c->cunit)->pd_oop == MOO_NULL);
}
else
{
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
MOO_ASSERT (moo, moo->c->cunit->cunit_type == MOO_CUNIT_CLASS); v = find_element_in_compiling_pooldic(moo, &last);
/* called inside a class definition */ if (!v)
if (cc->in_class_body)
{
/* [NOTE]
* cls.ns_oop is set when the class name is enountered.
* cls.super_oop is set when the parent class name is enountered.
* cls.super_oop may still be MOO_NULL even if cls.ns_oop is not.
* on the other hand, cls.ns_oop is not MOO_NULL as long as
* cls.super_oop is not MOO_NULL.
*/
MOO_ASSERT (moo, cc->super_oop != MOO_NULL);
MOO_ASSERT (moo, cc->ns_oop != MOO_NULL);
/* cc->self_oop may still be MOO_NULL if the class has not been instantiated */
if (find_class_level_variable(moo, cc->self_oop, &last, var) >= 0)
{ {
/* if the current class has not been instantiated, moo_setsynerr (moo, MOO_SYNERR_VARUNDCL, name_loc, name);
* no validation nor adjustment of the var->pos field is performed */ return -1;
if (cc->self_oop && validate_class_level_variable(moo, var, name, name_loc) <= -1) return -1;
return 0;
} }
var->type = VAR_LITERAL;
var->u.lit = v; /* TODO: change this */
return 0;
} }
case MOO_CUNIT_CLASS:
{
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
/* called inside a class definition */
MOO_ASSERT (moo, moo->c->cunit->cunit_type == MOO_CUNIT_CLASS);
if (cc->in_class_body)
{
/* [NOTE]
* cls.ns_oop is set when the class name is enountered.
* cls.super_oop is set when the parent class name is enountered.
* cls.super_oop may still be MOO_NULL even if cls.ns_oop is not.
* on the other hand, cls.ns_oop is not MOO_NULL as long as
* cls.super_oop is not MOO_NULL.
*/
MOO_ASSERT (moo, cc->super_oop != MOO_NULL);
MOO_ASSERT (moo, cc->ns_oop != MOO_NULL);
/* cc->self_oop may still be MOO_NULL if the class has not been instantiated */
if (find_class_level_variable(moo, cc->self_oop, &last, var) >= 0)
{
/* if the current class has not been instantiated,
* no validation nor adjustment of the var->pos field is performed */
if (cc->self_oop && validate_class_level_variable(moo, var, name, name_loc) <= -1) return -1;
return 0;
}
}
break;
}
case MOO_CUNIT_INTERFACE:
default:
/* interface doesn't support inheritance nor does it allow
* method body. let it flow down to the next check to
* trigger an error(MOO_SYNERR_VARINACC below) */
break;
} }
} }
@ -4699,17 +4642,29 @@ static MOO_INLINE int find_dotted_ident (moo_t* moo, const moo_oocs_t* name, con
{ {
/* the first segment is selfns which indicates a namespace that /* the first segment is selfns which indicates a namespace that
* the current class belongs to */ * the current class belongs to */
if (moo->c->cunit->cunit_type == MOO_CUNIT_POOLDIC) switch (moo->c->cunit->cunit_type)
{ {
/* compiling in a pooldic definition */ case MOO_CUNIT_POOLDIC:
top_dic = ((moo_cunit_pooldic_t*)moo->c->cunit)->ns_oop; /* compiling in a pooldic definition */
MOO_ASSERT (moo, top_dic != MOO_NULL); top_dic = ((moo_cunit_pooldic_t*)moo->c->cunit)->ns_oop;
} MOO_ASSERT (moo, top_dic != MOO_NULL);
else if (moo->c->cunit->cunit_type == MOO_CUNIT_CLASS) break;
{
/* compiling in a class definition */ case MOO_CUNIT_CLASS:
top_dic = ((moo_cunit_class_t*)moo->c->cunit)->ns_oop; /* compiling in a class definition */
MOO_ASSERT (moo, top_dic != MOO_NULL); top_dic = ((moo_cunit_class_t*)moo->c->cunit)->ns_oop;
MOO_ASSERT (moo, top_dic != MOO_NULL);
break;
case MOO_CUNIT_INTERFACE:
/* compiling in an interface definition */
top_dic = ((moo_cunit_interface_t*)moo->c->cunit)->ns_oop;
MOO_ASSERT (moo, top_dic != MOO_NULL);
break;
default:
moo_setsynerr (moo, MOO_SYNERR_VARINACC, name_loc, name);
return -1;
} }
pxlen++; /* include . into the length */ pxlen++; /* include . into the length */
@ -9259,12 +9214,6 @@ MOO_DEBUG2 (moo, "import pooldic... %.*js\n", last.len, last.ptr);
GET_TOKEN (moo); GET_TOKEN (moo);
if (compile_class_level_imports(moo) <= -1) return -1; if (compile_class_level_imports(moo) <= -1) return -1;
} }
else if (is_token_word(moo, VOCA_CONST))
{
/* constant declaration */
GET_TOKEN (moo);
if (compile_class_level_consts(moo) <= -1) return -1;
}
else break; else break;
} }
while (1); while (1);
@ -9872,10 +9821,7 @@ static int __compile_pooldic_definition (moo_t* moo)
GET_TOKEN (moo); GET_TOKEN (moo);
/* [NOTE] tmp = token_to_literal(moo, 1);
* values assigned to a pool dictinary member are not read-only
* unlike the default initial values defined in a class */
tmp = token_to_literal(moo, 0);
if (!tmp) goto oops; if (!tmp) goto oops;
/* for this definition, #pooldic MyPoolDic { a := 10. b := 20 }, /* for this definition, #pooldic MyPoolDic { a := 10. b := 20 },
@ -10225,6 +10171,10 @@ static void gc_cunit_chain (moo_t* moo)
break; break;
} }
default:
/* nothing to do */
break;
} }
} }
} }