Skip to content

Commit 357bdc3

Browse files
committed
in case labels, handle selects with enum supertypes
1 parent 485cfa8 commit 357bdc3

2 files changed

Lines changed: 76 additions & 37 deletions

File tree

src/express/expr.c

Lines changed: 53 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -234,12 +234,19 @@ void EXPcleanup( void ) {
234234
}
235235

236236
/**
237+
* \param selection the Type to look in (i.e. an enum)
238+
* \param ref the Symbol to be found
239+
* \param e set to the Expression found, when an enum is found
240+
* \param v set to the Variable found, when a variable is found
241+
* \param dt set to DICT_type when a match is found (use to determine whether to use e or v)
242+
* \param where used by ENTITYfind_inherited_attribute, not sure of purpose
237243
* \param s_id the search id, a parameter to avoid colliding with ENTITYfind...
238244
* there will be no ambiguities, since we're looking at (and marking)
239245
* only types, and it's marking only entities
240246
*/
241-
static int EXP_resolve_op_dot_fuzzy( Type selection, Symbol ref, Variable * v, char * dt,
242-
struct Symbol_ ** where, int s_id ) {
247+
static int EXP_resolve_op_dot_fuzzy( Type selection, Symbol ref, Expression * e,
248+
Variable * v, char * dt, struct Symbol_ ** where, int s_id ) {
249+
Expression item;
243250
Variable tmp;
244251
int options = 0;
245252
struct Symbol_ *w = NULL;
@@ -265,7 +272,7 @@ static int EXP_resolve_op_dot_fuzzy( Type selection, Symbol ref, Variable * v, c
265272
case select_:
266273
selection->search_id = s_id;
267274
LISTdo( selection->u.type->body->list, t, Type )
268-
if( EXP_resolve_op_dot_fuzzy( t, ref, v, dt, &w, s_id ) ) {
275+
if( EXP_resolve_op_dot_fuzzy( t, ref, e, v, dt, &w, s_id ) ) {
269276
if( w != NULL ) {
270277
*where = w;
271278
}
@@ -282,6 +289,13 @@ static int EXP_resolve_op_dot_fuzzy( Type selection, Symbol ref, Variable * v, c
282289
*v = VARIABLE_NULL;
283290
return 1;
284291
}
292+
case enumeration_:
293+
item = ( Expression )DICTlookup( TYPEget_enum_tags( selection ), ref.name );
294+
if( item ) {
295+
*e = item;
296+
*dt = DICT_type;
297+
return 1;
298+
}
285299
default:
286300
return 0;
287301
}
@@ -293,6 +307,7 @@ Type EXPresolve_op_dot( Expression expr, Scope scope ) {
293307
Variable v;
294308
Expression item;
295309
Type op1type;
310+
bool all_enums = true; //used by 'case select_'
296311

297312
/* stuff for dealing with select_ */
298313
int options = 0;
@@ -319,34 +334,50 @@ Type EXPresolve_op_dot( Expression expr, Scope scope ) {
319334
/* don't think this actually actually catches anything on the */
320335
/* first go-round, but let's be consistent */
321336
op1type->search_id = __SCOPE_search_id;
322-
LISTdo( op1type->u.type->body->list, t, Type )
323-
if( EXP_resolve_op_dot_fuzzy( t, op2->symbol, &v, &dt, &where,
324-
__SCOPE_search_id ) ) {
325-
++options;
326-
}
327-
LISTod;
328-
337+
LISTdo( op1type->u.type->body->list, t, Type ) {
338+
if( EXP_resolve_op_dot_fuzzy( t, op2->symbol, &item, &v, &dt, &where,
339+
__SCOPE_search_id ) ) {
340+
++options;
341+
}
342+
} LISTod;
329343
switch( options ) {
330344
case 0:
331-
/* no possible resolutions */
332-
ERRORreport_with_symbol( ERROR_undefined_attribute,
333-
&op2->symbol, op2->symbol.name );
345+
LISTdo( op1type->u.type->body->list, t, Type ) {
346+
if( t->u.type->body->type != enumeration_ ) {
347+
all_enums = false;
348+
}
349+
} LISTod;
350+
351+
if( all_enums ) {
352+
ERRORreport_with_symbol( WARNING_case_skip_label, &op2->symbol, op2->symbol.name );
353+
} else {
354+
/* no possible resolutions */
355+
ERRORreport_with_symbol( ERROR_undefined_attribute,
356+
&op2->symbol, op2->symbol.name );
357+
}
334358
resolve_failed( expr );
335359
return( Type_Bad );
336360
case 1:
337361
/* only one possible resolution */
338-
if( dt != OBJ_VARIABLE ) {
362+
if( dt == OBJ_VARIABLE ) {
363+
if( where ) {
364+
ERRORreport_with_symbol( ERROR_implicit_downcast, &op2->symbol,
365+
where->name );
366+
}
367+
368+
op2->u.variable = v;
369+
op2->return_type = v->type;
370+
resolved_all( expr );
371+
return( v->type );
372+
} else if ( dt == OBJ_ENUM ) {
373+
op2->u.expression = item;
374+
op2->return_type = item->type;
375+
resolved_all( expr );
376+
return( item->type );
377+
} else {
339378
printf( "EXPresolved_op_dot: attribute not an attribute?\n" );
340379
ERRORabort( 0 );
341-
} else if( where ) {
342-
ERRORreport_with_symbol( ERROR_implicit_downcast, &op2->symbol,
343-
where->name );
344380
}
345-
346-
op2->u.variable = v;
347-
op2->return_type = v->type;
348-
resolved_all( expr );
349-
return( v->type );
350381
default:
351382
/* compile-time ambiguous */
352383
if( where ) {

src/express/resolve.c

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -836,21 +836,30 @@ void STMTlist_resolve( Linked_List list, Scope scope ) {
836836
}
837837

838838
/**
839-
** \param item case item to resolve
840-
** \param scope scope in which to resolve
841-
**
842-
** Resolve all references in a case item
843-
*/
844-
void CASE_ITresolve( Case_Item item, Scope scope, Type type ) {
845-
LISTdo( item->labels, e, Expression )
846-
EXPresolve( e, scope, type );
847-
LISTod;
848-
STMTresolve( item->action, scope );
839+
* \param item case item to resolve
840+
* \param scope scope in which to resolve
841+
* \param statement the CASE statement (for return type, etc)
842+
*
843+
* Resolve all references in a case item
844+
*/
845+
void CASE_ITresolve( Case_Item item, Scope scope, Statement statement ) {
846+
int validLabels = 0;
847+
LISTdo( item->labels, e, Expression ) {
848+
EXPresolve( e, scope, statement->u.Case->selector->return_type );
849+
if ( e->return_type != Type_Bad ) {
850+
validLabels++;
851+
}
852+
} LISTod;
853+
if( validLabels ) {
854+
STMTresolve( item->action, scope );
855+
}
849856
}
850857

851858
void STMTresolve( Statement statement, Scope scope ) {
852-
Type type;
859+
//scope is always the function/procedure/rule from SCOPEresolve_expressions_statements();
853860
Scope proc;
861+
Logical eval;
862+
bool skipped = false;
854863

855864
if( !statement ) {
856865
return; /* could be null statement */
@@ -871,10 +880,9 @@ void STMTresolve( Statement statement, Scope scope ) {
871880
break;
872881
case STMT_CASE:
873882
EXPresolve( statement->u.Case->selector, scope, Type_Dont_Care );
874-
type = statement->u.Case->selector->return_type;
875-
LISTdo( statement->u.Case->cases, c, Case_Item )
876-
CASE_ITresolve( c, scope, type );
877-
LISTod;
883+
LISTdo( statement->u.Case->cases, c, Case_Item ) {
884+
CASE_ITresolve( c, scope, statement );
885+
} LISTod;
878886
break;
879887
case STMT_COMPOUND:
880888
STMTlist_resolve( statement->u.compound->statements, scope );

0 commit comments

Comments
 (0)