added support for pool dictionary import

This commit is contained in:
hyunghwan.chung 2015-07-26 14:38:34 +00:00
parent ce8a86e082
commit 5449e89292
5 changed files with 148 additions and 12 deletions

View File

@ -84,7 +84,7 @@
#class(#pointer) Class(Apex) #class(#pointer) Class(Apex)
{ {
#dcl spec selfspec superclass subclasses name instvars classvars classinstvars instmthdic classmthdic. #dcl spec selfspec superclass subclasses name instvars classvars classinstvars pooldics instmthdic classmthdic.
} }

View File

@ -33,6 +33,7 @@
#define BALIT_BUFFER_ALIGN 8 /* 256 */ #define BALIT_BUFFER_ALIGN 8 /* 256 */
#define ARLIT_BUFFER_ALIGN 8 /* 256 */ #define ARLIT_BUFFER_ALIGN 8 /* 256 */
#define BLK_TMPRCNT_BUFFER_ALIGN 8 #define BLK_TMPRCNT_BUFFER_ALIGN 8
#define POOLDIC_OOP_BUFFER_ALIGN 8
/* initial method dictionary size */ /* initial method dictionary size */
#define INSTANCE_METHOD_DICTIONARY_SIZE 256 /* TODO: choose the right size */ #define INSTANCE_METHOD_DICTIONARY_SIZE 256 /* TODO: choose the right size */
@ -1861,6 +1862,42 @@ static STIX_INLINE int add_class_level_variable (stix_t* stix, var_type_t index,
return n; return n;
} }
static STIX_INLINE int add_pool_dictionary (stix_t* stix, const stix_ucs_t* name, stix_oop_set_t pooldic_oop)
{
int n;
stix_size_t saved_len;
saved_len = stix->c->cls.pooldic.len;
n = copy_string_to (stix, name, &stix->c->cls.pooldic, &stix->c->cls.pooldic_capa, 1, ' ');
if (n >= 0)
{
if (stix->c->cls.pooldic_count >= stix->c->cls.pooldic_oop_capa)
{
stix_size_t new_capa;
stix_oop_set_t* tmp;
new_capa = STIX_ALIGN(stix->c->cls.pooldic_oop_capa + 1, POOLDIC_OOP_BUFFER_ALIGN);
tmp = stix_reallocmem (stix, stix->c->cls.pooldic_oops, new_capa * STIX_SIZEOF(stix_oop_set_t));
if (!tmp)
{
stix->c->cls.pooldic.len = saved_len;
return -1;
}
stix->c->cls.pooldic_oop_capa = new_capa;
stix->c->cls.pooldic_oops = tmp;
}
stix->c->cls.pooldic_oops[stix->c->cls.pooldic_count] = pooldic_oop;
stix->c->cls.pooldic_count++;
/* TODO: check if pooldic_count overflows */
}
return n;
}
static stix_ssize_t find_class_level_variable (stix_t* stix, stix_oop_class_t self, const stix_ucs_t* name, var_info_t* var) static stix_ssize_t find_class_level_variable (stix_t* stix, stix_oop_class_t self, const stix_ucs_t* name, var_info_t* var)
{ {
stix_size_t pos; stix_size_t pos;
@ -2231,9 +2268,12 @@ static int compile_class_level_variables (stix_t* stix)
if (dcl_type == VAR_GLOBAL) if (dcl_type == VAR_GLOBAL)
{ {
/* pool dictionary import declaration
* #dcl(#pooldic) ... */
stix_ucs_t last; stix_ucs_t last;
stix_oop_set_t ns_oop; stix_oop_set_t ns_oop;
stix_oop_association_t ass; stix_oop_association_t ass;
stix_size_t i;
do do
{ {
@ -2244,10 +2284,12 @@ static int compile_class_level_variables (stix_t* stix)
else if (stix->c->tok.type == STIX_IOTOK_IDENT) else if (stix->c->tok.type == STIX_IOTOK_IDENT)
{ {
last = stix->c->tok.name; last = stix->c->tok.name;
ns_oop = stix->sysdic; /* it falls back to the name space of the class */
ns_oop = stix->c->cls.ns_oop;
} }
else break; else break;
/* check if the name refers to a pool dictionary */
ass = stix_lookupdic (stix, ns_oop, &last); ass = stix_lookupdic (stix, ns_oop, &last);
if (!ass || STIX_CLASSOF(stix, ass->value) != stix->_pool_dictionary) if (!ass || STIX_CLASSOF(stix, ass->value) != stix->_pool_dictionary)
{ {
@ -2255,15 +2297,24 @@ static int compile_class_level_variables (stix_t* stix)
return -1; return -1;
} }
/* TODO: */ /* check if the same dictionary pool has been declared for import */
/*if (add_pool_dictionary(stix, &stix->c->tok.name) <= -1) return -1;*/ for (i = 0; i < stix->c->cls.pooldic_count; i++)
{
if ((stix_oop_set_t)ass->value == stix->c->cls.pooldic_oops[i])
{
set_syntax_error (stix, STIX_SYNERR_POOLDICDUP, &stix->c->tok.loc, &stix->c->tok.name);
return -1;
}
}
if (add_pool_dictionary(stix, &stix->c->tok.name, (stix_oop_set_t)ass->value) <= -1) return -1;
GET_TOKEN (stix); GET_TOKEN (stix);
} }
while (1); while (1);
} }
else else
{ {
/* variable declaration */
do do
{ {
if (stix->c->tok.type == STIX_IOTOK_IDENT) if (stix->c->tok.type == STIX_IOTOK_IDENT)
@ -2557,8 +2608,36 @@ static int get_variable_info (stix_t* stix, const stix_ucs_t* name, const stix_i
stix_ucs_t last; stix_ucs_t last;
stix_oop_set_t ns_oop; stix_oop_set_t ns_oop;
stix_oop_association_t ass; stix_oop_association_t ass;
const stix_uch_t* dot;
dot = stix_findchar (name->ptr, name->len, '.');
STIX_ASSERT (dot != STIX_NULL);
if (dot - name->ptr == 4 && stix_equalchars(name->ptr, vocas[VOCA_SELF].str, 4))
{
/* the dotted name begins with self. */
dot = stix_findchar (dot + 1, name->len - 5, '.');
if (!dot)
{
/* the dotted name is composed of 2 segments only */
last.ptr = name->ptr + 5;
last.len = name->len - 5;
if (!is_reserved_word(&last))
{
if (find_class_level_variable(stix, stix->c->cls.self_oop, &last, var) >= 0)
{
goto class_level_variable;
}
else
{
/* undeclared identifier */
set_syntax_error (stix, STIX_SYNERR_VARUNDCL, name_loc, name);
return -1;
}
}
}
}
/*TODO: handle self.XXX ---------- */
if (preprocess_dotted_name (stix, 1, 1, name, name_loc, &last, &ns_oop) <= -1) return -1; if (preprocess_dotted_name (stix, 1, 1, name, name_loc, &last, &ns_oop) <= -1) return -1;
printf ("checking variable "); printf ("checking variable ");
@ -2587,8 +2666,10 @@ printf ("\n");
} }
else else
{ {
if (find_class_level_variable(stix, stix->c->cls.self_oop, name, var) >= 0) if (find_class_level_variable(stix, stix->c->cls.self_oop, name, var) >= 0)
{ {
class_level_variable:
switch (var->type) switch (var->type)
{ {
case VAR_INSTANCE: case VAR_INSTANCE:
@ -2639,13 +2720,39 @@ printf ("\n");
ass = stix_lookupdic (stix, stix->c->cls.ns_oop, name); ass = stix_lookupdic (stix, stix->c->cls.ns_oop, name);
if (!ass && stix->c->cls.ns_oop != stix->sysdic) if (!ass && stix->c->cls.ns_oop != stix->sysdic)
ass = stix_lookupdic (stix, stix->sysdic, name); ass = stix_lookupdic (stix, stix->sysdic, name);
/* TODO: search in the pool dictionary */
if (ass) if (ass)
{ {
var->type = VAR_GLOBAL; var->type = VAR_GLOBAL;
var->gbl = ass; var->gbl = ass;
} }
else else
{
stix_size_t i;
stix_oop_association_t ass2 = STIX_NULL;
/* attempt to find the variable in pool dictionaries */
for (i = 0; i < stix->c->cls.pooldic_count; i++)
{
ass = stix_lookupdic (stix, stix->c->cls.pooldic_oops[i], name);
if (ass)
{
if (ass2)
{
/* the variable name has been found at least in 2 dictionaries */
set_syntax_error (stix, STIX_SYNERR_VARAMBIG, name_loc, name);
return -1;
}
ass2 = ass;
}
}
if (ass2)
{
var->type = VAR_GLOBAL;
var->gbl = ass2;
}
else
{ {
/* undeclared identifier */ /* undeclared identifier */
set_syntax_error (stix, STIX_SYNERR_VARUNDCL, name_loc, name); set_syntax_error (stix, STIX_SYNERR_VARUNDCL, name_loc, name);
@ -2653,6 +2760,7 @@ printf ("\n");
} }
} }
} }
}
if (var->pos > MAX_CODE_INDEX) if (var->pos > MAX_CODE_INDEX)
{ {
@ -4239,6 +4347,10 @@ printf (" CONFLICTING CLASS DEFINITION %lu %lu %lu %lu\n",
if (!tmp) return -1; if (!tmp) return -1;
stix->c->cls.self_oop->classinstvars = (stix_oop_char_t)tmp; stix->c->cls.self_oop->classinstvars = (stix_oop_char_t)tmp;
tmp = stix_makestring (stix, stix->c->cls.pooldic.ptr, stix->c->cls.pooldic.len);
if (!tmp) return -1;
stix->c->cls.self_oop->pooldics = (stix_oop_char_t)tmp;
/* TOOD: good dictionary size */ /* TOOD: good dictionary size */
tmp = (stix_oop_t)stix_makedic (stix, stix->_method_dictionary, INSTANCE_METHOD_DICTIONARY_SIZE); tmp = (stix_oop_t)stix_makedic (stix, stix->_method_dictionary, INSTANCE_METHOD_DICTIONARY_SIZE);
if (!tmp) return -1; if (!tmp) return -1;
@ -4580,6 +4692,9 @@ static int compile_class_definition (stix_t* stix, int extend)
stix->c->cls.vars[i].len = 0; stix->c->cls.vars[i].len = 0;
} }
stix->c->cls.pooldic_count = 0;
stix->c->cls.pooldic.len = 0;
stix->c->cls.self_oop = STIX_NULL; stix->c->cls.self_oop = STIX_NULL;
stix->c->cls.super_oop = STIX_NULL; stix->c->cls.super_oop = STIX_NULL;
stix->c->cls.mthdic_oop[MTH_INSTANCE] = STIX_NULL; stix->c->cls.mthdic_oop[MTH_INSTANCE] = STIX_NULL;
@ -4604,6 +4719,8 @@ static int compile_class_definition (stix_t* stix, int extend)
stix->c->mth.balit_count = 0; stix->c->mth.balit_count = 0;
stix->c->mth.arlit_count = 0; stix->c->mth.arlit_count = 0;
stix->c->cls.pooldic_count = 0;
return n; return n;
} }
@ -4888,6 +5005,11 @@ static void gc_compiler (stix_t* stix)
if (stix->c->cls.superns_oop) if (stix->c->cls.superns_oop)
stix->c->cls.superns_oop = (stix_oop_set_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.superns_oop); stix->c->cls.superns_oop = (stix_oop_set_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.superns_oop);
for (i = 0; i < stix->c->cls.pooldic_count; i++)
{
stix->c->cls.pooldic_oops[i] = (stix_oop_set_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.pooldic_oops[i]);
}
for (i = 0; i < stix->c->mth.literal_count; i++) for (i = 0; i < stix->c->mth.literal_count; i++)
{ {
stix->c->mth.literals[i] = stix_moveoop (stix, stix->c->mth.literals[i]); stix->c->mth.literals[i] = stix_moveoop (stix, stix->c->mth.literals[i]);
@ -4918,6 +5040,9 @@ static void fini_compiler (stix_t* stix)
if (stix->c->cls.vars[i].ptr) stix_freemem (stix, stix->c->cls.vars[i].ptr); if (stix->c->cls.vars[i].ptr) stix_freemem (stix, stix->c->cls.vars[i].ptr);
} }
if (stix->c->cls.pooldic.ptr) stix_freemem (stix, stix->c->cls.pooldic.ptr);
if (stix->c->cls.pooldic_oops) stix_freemem (stix, stix->c->cls.pooldic_oops);
if (stix->c->mth.text.ptr) stix_freemem (stix, stix->c->mth.text.ptr); if (stix->c->mth.text.ptr) stix_freemem (stix, stix->c->mth.text.ptr);
if (stix->c->mth.assignees.ptr) stix_freemem (stix, stix->c->mth.assignees.ptr); if (stix->c->mth.assignees.ptr) stix_freemem (stix, stix->c->mth.assignees.ptr);
if (stix->c->mth.binsels.ptr) stix_freemem (stix, stix->c->mth.binsels.ptr); if (stix->c->mth.binsels.ptr) stix_freemem (stix, stix->c->mth.binsels.ptr);

View File

@ -208,6 +208,7 @@ static char* syntax_error_msg[] =
"undeclared variable", "undeclared variable",
"unusable variable in compiled code", "unusable variable in compiled code",
"inaccessible variable", "inaccessible variable",
"ambiguous variable",
"wrong expression primary", "wrong expression primary",
"too many temporaries", "too many temporaries",
"too many arguments", "too many arguments",

View File

@ -322,6 +322,7 @@ enum stix_synerrnum_t
STIX_SYNERR_VARUNDCL, /* undeclared variable */ STIX_SYNERR_VARUNDCL, /* undeclared variable */
STIX_SYNERR_VARUNUSE, /* unsuable variable in compiled code */ STIX_SYNERR_VARUNUSE, /* unsuable variable in compiled code */
STIX_SYNERR_VARINACC, /* inaccessible variable - e.g. accessing an instance variable from a class method is not allowed. */ STIX_SYNERR_VARINACC, /* inaccessible variable - e.g. accessing an instance variable from a class method is not allowed. */
STIX_SYNERR_VARAMBIG, /* ambiguious variable - e.g. the variable is found in multiple pool dictionaries imported */
STIX_SYNERR_PRIMARY, /* wrong expression primary */ STIX_SYNERR_PRIMARY, /* wrong expression primary */
STIX_SYNERR_TMPRFLOOD, /* too many temporaries */ STIX_SYNERR_TMPRFLOOD, /* too many temporaries */
STIX_SYNERR_ARGFLOOD, /* too many arguments */ STIX_SYNERR_ARGFLOOD, /* too many arguments */
@ -423,6 +424,13 @@ struct stix_compiler_t
* var_count[1] - number of class variables * var_count[1] - number of class variables
* var_count[2] - number of class instance variables */ * var_count[2] - number of class instance variables */
stix_size_t var_count[3]; stix_size_t var_count[3];
stix_ucs_t pooldic;
stix_size_t pooldic_capa;
stix_size_t pooldic_count;
stix_oop_set_t* pooldic_oops;
stix_size_t pooldic_oop_capa;
} cls; } cls;
/* information about a function being comipled */ /* information about a function being comipled */

View File

@ -540,7 +540,7 @@ struct stix_set_t
stix_oop_oop_t bucket; /* Array */ stix_oop_oop_t bucket; /* Array */
}; };
#define STIX_CLASS_NAMED_INSTVARS 10 #define STIX_CLASS_NAMED_INSTVARS 11
typedef struct stix_class_t stix_class_t; typedef struct stix_class_t stix_class_t;
typedef struct stix_class_t* stix_oop_class_t; typedef struct stix_class_t* stix_oop_class_t;
struct stix_class_t struct stix_class_t
@ -561,6 +561,8 @@ struct stix_class_t
stix_oop_char_t classinstvars; /* String */ stix_oop_char_t classinstvars; /* String */
/* == NEVER CHANGE THE ORDER OF 3 ITEMS ABOVE == */ /* == NEVER CHANGE THE ORDER OF 3 ITEMS ABOVE == */
stix_oop_char_t pooldics; /* String */
/* [0] - instance methods, MethodDictionary /* [0] - instance methods, MethodDictionary
* [1] - class methods, MethodDictionary */ * [1] - class methods, MethodDictionary */
stix_oop_set_t mthdic[2]; stix_oop_set_t mthdic[2];