put enums in separate table

This commit is contained in:
Mark Pictor
2012-01-17 20:38:31 -05:00
parent 064a2b41b5
commit c415e49894
4 changed files with 71 additions and 44 deletions
+1 -1
View File
@@ -90,7 +90,7 @@ struct Scope_ {
char type; /* see above */
ClientData clientData; /* user may use this for any purpose */
int search_id; /* key to avoid searching this scope twice */
Dictionary symbol_table;
Dictionary symbol_table,enum_table;
struct Scope_ * superscope;
union {
/* struct Constant *constant;*/
+16 -14
View File
@@ -776,22 +776,24 @@ enumeration_type : TOK_ENUMERATION TOK_OF nested_id_list
CURRENT_SCOPE->u.type->body = tb;
tb->list = $3;
if (!CURRENT_SCOPE->symbol_table) {
CURRENT_SCOPE->symbol_table = DICTcreate(25);
CURRENT_SCOPE->symbol_table = DICTcreate(25);
}
LISTdo_links($3, id)
tmp = (Symbol *)id->data;
id->data = (Generic)(x = EXPcreate(CURRENT_SCOPE));
x->symbol = *(tmp);
x->u.integer = ++value;
/* define both in enum scope and scope of */
/* 1st visibility */
DICT_define(CURRENT_SCOPE->symbol_table,
x->symbol.name,
(Generic)x,&x->symbol,OBJ_EXPRESSION);
DICTdefine(PREVIOUS_SCOPE->symbol_table,x->symbol.name,
(Generic)x,&x->symbol,OBJ_EXPRESSION);
if (!PREVIOUS_SCOPE->enum_table) {
PREVIOUS_SCOPE->enum_table = DICTcreate(25);
}
LISTdo_links($3, id) {
tmp = (Symbol *)id->data;
id->data = (Generic)(x = EXPcreate(CURRENT_SCOPE));
x->symbol = *(tmp);
x->u.integer = ++value;
/* define both in enum scope and scope of */
/* 1st visibility */
DICT_define(CURRENT_SCOPE->symbol_table, x->symbol.name,
(Generic)x,&x->symbol,OBJ_EXPRESSION);
DICTdefine(PREVIOUS_SCOPE->enum_table,x->symbol.name,
(Generic)x,&x->symbol,OBJ_EXPRESSION);
SYMBOL_destroy(tmp);
LISTod;
} LISTod;
}
;
+24 -10
View File
@@ -403,21 +403,35 @@ EXP_resolve( Expression expr, Scope scope, Type typecheck ) {
break;
case identifier_:
/* if this must match an enumeration, try first looking */
/* in the enumeration tag scope */
x = 0;
#ifdef permissive_checks
if( typecheck->u.type->body->type == enumeration_ ) {
x = DICTlookup( TYPEget_enum_tags( typecheck ), expr->symbol.name );
}
#endif
/* if not an enumeration tag, assume it's a variable/attribute */
/* assume it's a variable/attribute */
if( !x ) {
x = ( Generic )VARfind( scope, expr->symbol.name, 0 );
}
/* if not found as a variable, try as function, etc ... */
if( !x ) x = SCOPEfind( scope, expr->symbol.name,
SCOPE_FIND_ANYTHING );
if( !x ) {
x = SCOPEfind( scope, expr->symbol.name,
SCOPE_FIND_ANYTHING );
}
/* Not all enums have `typecheck->u.type->body->type` == `enumeration_` - ?! */
if( !x ) {
Scope enumscope = scope;
while( 1 ) {
// look up locally, then go through the superscopes
x = DICTlookup( enumscope->enum_table, expr->symbol.name );
if( x ) {
break;
}
if( enumscope->type == OBJ_SCHEMA ) {
//if we get here, this means that we've looked through all scopes
x = 0;
break;
}
enumscope = enumscope->superscope;
}
}
if( !x ) {
if( typecheck == Type_Unknown ) {
return;
+30 -19
View File
@@ -201,23 +201,29 @@ void SCOPEPrint( Scope scope, FILES * files, Schema schema, Express model,
/* and print the enumerations */
fprintf( files -> inc, "\n/* ************** TYPES */\n" );
fprintf( files -> lib, "\n/* ************** TYPES */\n" );
SCOPEdo_types( scope, t, de )
// First check for one exception: Say enumeration type B is defined
// to be a rename of enum A. If A is in this schema but has not been
// processed yet, we must wait till it's processed first. The reason
// is because B will basically be defined with a couple of typedefs to
// the classes which represent A. (To simplify, we wait even if A is
// in another schema, so long as it's been processed.)
if( ( t->search_id == CANPROCESS )
&& ( TYPEis_enumeration( t ) )
&& ( ( i = TYPEget_ancestor( t ) ) != NULL )
&& ( i->search_id >= CANPROCESS ) ) {
redefs = 1;
/* The following was `SCOPEdo_types( scope, t, de ) ... SCOPEod;`
* Modified Jan 2012 by MAP - moving enums to own dictionary */
HASHlistinit_by_type(scope->enum_table,&de,OBJ_TYPE);{
Type t;
while ( 0 != ( t = (Type) DICTdo( &de ) ) ) {
// First check for one exception: Say enumeration type B is defined
// to be a rename of enum A. If A is in this schema but has not been
// processed yet, we must wait till it's processed first. The reason
// is because B will basically be defined with a couple of typedefs to
// the classes which represent A. (To simplify, we wait even if A is
// in another schema, so long as it's been processed.)
if( ( t->search_id == CANPROCESS )
&& ( TYPEis_enumeration( t ) )
&& ( ( i = TYPEget_ancestor( t ) ) != NULL )
&& ( i->search_id >= CANPROCESS ) ) {
redefs = 1;
}
}
}
SCOPEod
SCOPEdo_types( scope, t, de )
// Do the non-redefined enumerations:
/* NOTE the following comment seems to contradict the logic below it (... && !( TYPEis_enumeration( t ) && ...)
// Do the non-redefined enumerations:*/
if( ( t->search_id == CANPROCESS )
&& !( TYPEis_enumeration( t ) && TYPEget_head( t ) ) ) {
TYPEprint_descriptions( t, files, schema );
@@ -231,12 +237,17 @@ void SCOPEPrint( Scope scope, FILES * files, Schema schema, Express model,
if( redefs ) {
// Here we process redefined enumerations. See note, 2 loops ago.
fprintf( files->inc, "// ***** Redefined Enumerations:\n" );
SCOPEdo_types( scope, t, de )
if( t->search_id == CANPROCESS && TYPEis_enumeration( t ) ) {
TYPEprint_descriptions( t, files, schema );
t->search_id = PROCESSED;
/* The following was `SCOPEdo_types( scope, t, de ) ... SCOPEod;`
* Modified Jan 2012 by MAP - moving enums to own dictionary */
HASHlistinit_by_type(scope->enum_table,&de,OBJ_TYPE);{
Type t;
while ( 0 != ( t = (Type) DICTdo( &de ) ) ) {
if( t->search_id == CANPROCESS && TYPEis_enumeration( t ) ) {
TYPEprint_descriptions( t, files, schema );
t->search_id = PROCESSED;
}
}
}
SCOPEod;
}
/* do the select definitions next, since they depend on the others */