Skip to content

Commit 36dc0dd

Browse files
committed
Make a stab at merging in changes from stepcode#192, needed for select_lookup_enum.exp
1 parent 80e57f2 commit 36dc0dd

5 files changed

Lines changed: 116 additions & 55 deletions

File tree

include/express/resolve.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ extern SCL_EXPRESS_EXPORT Error ERROR_circular_reference;
5757
extern SCL_EXPRESS_EXPORT Error ERROR_ambiguous_attribute;
5858
extern SCL_EXPRESS_EXPORT Error ERROR_ambiguous_group;
5959

60+
extern SCL_EXPRESS_EXPORT Error WARNING_case_skip_label;
61+
extern SCL_EXPRESS_EXPORT Error WARNING_fn_skip_branch;
62+
6063
/* macros */
6164

6265
/* cheaper doing the check here, then inside the function call. Return */

src/clstepcore/STEPcomplex.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ void STEPcomplex::Initialize( const char ** names, const char * schnm ) {
6161
*eptr = ents, *prev = NULL, *enext;
6262
const EntityDescriptor * enDesc;
6363
char nm[BUFSIZ];
64-
int invalid = 0, outOfOrder = 0;
64+
bool invalid = false, outOfOrder = false;
6565

6666
// Splice out the invalid names from our list:
6767
while( eptr ) {
@@ -80,11 +80,11 @@ void STEPcomplex::Initialize( const char ** names, const char * schnm ) {
8080
// support structs only deal with the original names) and have
8181
// ents re-ort eptr properly in the list:
8282
eptr->Name( StrToLower( enDesc->Name(), nm ) );
83-
outOfOrder = 1;
83+
outOfOrder = true;
8484
}
8585
prev = eptr;
8686
} else {
87-
invalid = 1;
87+
invalid = true;
8888
cerr << "ERROR: Invalid entity \"" << eptr->Name()
8989
<< "\" found in complex entity.\n";
9090
if( !prev ) {

src/express/expr.c

Lines changed: 66 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
#include "express/resolve.h"
7676

7777
#include <assert.h>
78+
#include <limits.h>
7879

7980
struct EXPop_entry EXPop_table[OP_LAST];
8081

@@ -181,7 +182,7 @@ void EXPinitialize( void ) {
181182
resolved_all( LITERAL_PI );
182183

183184
LITERAL_INFINITY = EXPcreate_simple( Type_Integer );
184-
LITERAL_INFINITY->u.integer = MAXINT;
185+
LITERAL_INFINITY->u.integer = INT_MAX;
185186
resolved_all( LITERAL_INFINITY );
186187

187188
LITERAL_ZERO = EXPcreate_simple( Type_Integer );
@@ -247,12 +248,19 @@ void EXPcleanup( void ) {
247248
}
248249

249250
/**
251+
* \param selection the Type to look in (i.e. an enum)
252+
* \param ref the Symbol to be found
253+
* \param e set to the Expression found, when an enum is found
254+
* \param v set to the Variable found, when a variable is found
255+
* \param dt set to DICT_type when a match is found (use to determine whether to use e or v)
256+
* \param where used by ENTITYfind_inherited_attribute, not sure of purpose
250257
* \param s_id the search id, a parameter to avoid colliding with ENTITYfind...
251258
* there will be no ambiguities, since we're looking at (and marking)
252259
* only types, and it's marking only entities
253260
*/
254-
static int EXP_resolve_op_dot_fuzzy( Type selection, Symbol ref, Variable * v, char * dt,
255-
struct Symbol_ ** where, int s_id ) {
261+
static int EXP_resolve_op_dot_fuzzy( Type selection, Symbol ref, Expression * e,
262+
Variable * v, char * dt, struct Symbol_ ** where, int s_id ) {
263+
Expression item;
256264
Variable tmp;
257265
int options = 0;
258266
struct Symbol_ *w = NULL;
@@ -278,7 +286,7 @@ static int EXP_resolve_op_dot_fuzzy( Type selection, Symbol ref, Variable * v, c
278286
case select_:
279287
selection->search_id = s_id;
280288
LISTdo( selection->u.type->body->list, t, Type )
281-
if( EXP_resolve_op_dot_fuzzy( t, ref, v, dt, &w, s_id ) ) {
289+
if( EXP_resolve_op_dot_fuzzy( t, ref, e, v, dt, &w, s_id ) ) {
282290
if( w != NULL ) {
283291
*where = w;
284292
}
@@ -294,8 +302,15 @@ static int EXP_resolve_op_dot_fuzzy( Type selection, Symbol ref, Variable * v, c
294302
/* found more than one, so ambiguous */
295303
*v = VARIABLE_NULL;
296304
return 1;
297-
}
298-
default:
305+
}
306+
case enumeration_:
307+
item = ( Expression )DICTlookup( TYPEget_enum_tags( selection ), ref.name );
308+
if( item ) {
309+
*e = item;
310+
*dt = DICT_type;
311+
return 1;
312+
}
313+
default:
299314
return 0;
300315
}
301316
}
@@ -306,6 +321,7 @@ Type EXPresolve_op_dot( Expression expr, Scope scope ) {
306321
Variable v;
307322
Expression item;
308323
Type op1type;
324+
bool all_enums = true; //used by 'case select_'
309325

310326
/* stuff for dealing with select_ */
311327
int options = 0;
@@ -332,34 +348,51 @@ Type EXPresolve_op_dot( Expression expr, Scope scope ) {
332348
/* don't think this actually actually catches anything on the */
333349
/* first go-round, but let's be consistent */
334350
op1type->search_id = __SCOPE_search_id;
335-
LISTdo( op1type->u.type->body->list, t, Type )
336-
if( EXP_resolve_op_dot_fuzzy( t, op2->symbol, &v, &dt, &where,
337-
__SCOPE_search_id ) ) {
338-
++options;
339-
}
340-
LISTod;
341-
351+
LISTdo( op1type->u.type->body->list, t, Type ) {
352+
if( EXP_resolve_op_dot_fuzzy( t, op2->symbol, &item, &v, &dt, &where,
353+
__SCOPE_search_id ) ) {
354+
++options;
355+
}
356+
} LISTod;
342357
switch( options ) {
343358
case 0:
344-
/* no possible resolutions */
345-
ERRORreport_with_symbol( ERROR_undefined_attribute,
346-
&op2->symbol, op2->symbol.name );
359+
LISTdo( op1type->u.type->body->list, t, Type ) {
360+
if( t->u.type->body->type != enumeration_ ) {
361+
all_enums = false;
362+
}
363+
} LISTod;
364+
365+
if( all_enums ) {
366+
ERRORreport_with_symbol( WARNING_case_skip_label, &op2->symbol, op2->symbol.name );
367+
} else {
368+
/* no possible resolutions */
369+
ERRORreport_with_symbol( ERROR_undefined_attribute,
370+
&op2->symbol, op2->symbol.name );
371+
}
347372
resolve_failed( expr );
348373
return( Type_Bad );
349374
case 1:
350375
/* only one possible resolution */
351-
if( dt != OBJ_VARIABLE ) {
376+
if( dt == OBJ_VARIABLE ) {
377+
if( where ) {
378+
ERRORreport_with_symbol( ERROR_implicit_downcast, &op2->symbol,
379+
where->name );
380+
}
381+
382+
op2->u.variable = v;
383+
op2->return_type = v->type;
384+
resolved_all( expr );
385+
return( v->type );
386+
} else if ( dt == OBJ_ENUM ) {
387+
op2->u.expression = item;
388+
op2->return_type = item->type;
389+
resolved_all( expr );
390+
return( item->type );
391+
} else {
352392
printf( "EXPresolved_op_dot: attribute not an attribute?\n" );
353393
ERRORabort( 0 );
354-
} else if( where ) {
355-
ERRORreport_with_symbol( ERROR_implicit_downcast, &op2->symbol,
356-
where->name );
357394
}
358395

359-
op2->u.variable = v;
360-
op2->return_type = v->type;
361-
resolved_all( expr );
362-
return( v->type );
363396
default:
364397
/* compile-time ambiguous */
365398
if( where ) {
@@ -408,12 +441,12 @@ Type EXPresolve_op_dot( Expression expr, Scope scope ) {
408441
resolved_all( expr );
409442
return( op2->return_type );
410443
case enumeration_:
444+
/* enumerations within a select will be handled by `case select_` above,
445+
* which calls EXP_resolve_op_dot_fuzzy(). */
411446
item = ( Expression )DICTlookup( TYPEget_enum_tags( op1type ), op2->symbol.name );
412-
/* item = (Expression )DICTlookup(TYPEget_enum_tags(op1->return_type),op2->symbol.name);*/
413447
if( !item ) {
414448
ERRORreport_with_symbol( ERROR_enum_no_such_item, &op2->symbol,
415449
op1type->symbol.name, op2->symbol.name );
416-
/* ERRORreport_with_symbol(ERROR_enum_no_such_item,&op2->symbol,op1->return_type->symbol.name,op2->symbol.name);*/
417450
resolve_failed( expr );
418451
return( Type_Bad );
419452
}
@@ -781,10 +814,14 @@ Type EXPresolve_op_unary_minus( Expression e, Scope s ) {
781814
return e->e.op1->return_type;
782815
}
783816

784-
/**
817+
/** Initialize one entry in EXPop_table
818+
* This table's function pointers are resolved in \sa EXP_resolve()
819+
* , at approx resolve.c:520
820+
* \sa EXPop_init()
821+
*
822+
* \param token_number operator value, usually in macro form
823+
* \param string human-readable description
785824
* \param resolve_func resolves an expression of this type
786-
* \param type_func returns final type of expression of this type
787-
* avoids resolution if possible
788825
*/
789826
void EXPop_create( int token_number, char * string, Resolve_expr_func * resolve_func ) {
790827
EXPop_table[token_number].token = string;

src/express/resolve.c

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ Error ERROR_unknown_supertype = ERROR_none;
7373
Error ERROR_circular_reference = ERROR_none;
7474
Error ERROR_ambiguous_attribute = ERROR_none;
7575
Error ERROR_ambiguous_group = ERROR_none;
76+
Error WARNING_fn_skip_branch = ERROR_none;
77+
Error WARNING_case_skip_label = ERROR_none;
78+
7679

7780
static void ENTITYresolve_subtypes PROTO( ( Schema ) );
7881
static void ENTITYresolve_supertypes PROTO( ( Entity ) );
@@ -212,9 +215,17 @@ void RESOLVEinitialize( void ) {
212215
ERROR_missing_self = ERRORcreate(
213216
"Domain rule %s must refer to SELF or attribute.", SEVERITY_ERROR );
214217

218+
WARNING_fn_skip_branch = ERRORcreate(
219+
"IF statement condition is always %s. Ignoring branch that is never taken.", SEVERITY_WARNING );
220+
221+
WARNING_case_skip_label = ERRORcreate("CASE label %s cannot be matched. Ignoring its statements.", SEVERITY_WARNING);
222+
223+
215224
ERRORcreate_warning( "circular_subtype", ERROR_subsuper_loop );
216225
ERRORcreate_warning( "circular_select", ERROR_select_loop );
217226
ERRORcreate_warning( "entity_as_type", ERROR_type_is_entity );
227+
ERRORcreate_warning( "invariant_condition", WARNING_fn_skip_branch );
228+
ERRORcreate_warning( "invalid_case", WARNING_case_skip_label );
218229
}
219230

220231
/** Clean up the Fed-X second pass */
@@ -251,6 +262,8 @@ void RESOLVEcleanup( void ) {
251262
ERRORdestroy( ERROR_redecl_no_such_attribute );
252263
ERRORdestroy( ERROR_redecl_no_such_supertype );
253264
ERRORdestroy( ERROR_missing_self );
265+
ERRORdestroy( WARNING_case_skip_label );
266+
ERRORdestroy( WARNING_fn_skip_branch );
254267
}
255268

256269
/**
@@ -818,21 +831,30 @@ void STMTlist_resolve( Linked_List list, Scope scope ) {
818831
}
819832

820833
/**
821-
** \param item case item to resolve
822-
** \param scope scope in which to resolve
823-
**
824-
** Resolve all references in a case item
825-
*/
826-
void CASE_ITresolve( Case_Item item, Scope scope, Type type ) {
827-
LISTdo( item->labels, e, Expression )
828-
EXPresolve( e, scope, type );
829-
LISTod;
830-
STMTresolve( item->action, scope );
834+
* \param item case item to resolve
835+
* \param scope scope in which to resolve
836+
* \param statement the CASE statement (for return type, etc)
837+
*
838+
* Resolve all references in a case item
839+
*/
840+
void CASE_ITresolve( Case_Item item, Scope scope, Statement statement ) {
841+
int validLabels = 0;
842+
LISTdo( item->labels, e, Expression ) {
843+
EXPresolve( e, scope, statement->u.Case->selector->return_type );
844+
if ( e->return_type != Type_Bad ) {
845+
validLabels++;
846+
}
847+
} LISTod;
848+
if( validLabels ) {
849+
STMTresolve( item->action, scope );
850+
}
831851
}
832852

833853
void STMTresolve( Statement statement, Scope scope ) {
834-
Type type;
854+
//scope is always the function/procedure/rule from SCOPEresolve_expressions_statements();
835855
Scope proc;
856+
Logical eval;
857+
bool skipped = false;
836858

837859
if( !statement ) {
838860
return; /* could be null statement */
@@ -853,10 +875,9 @@ void STMTresolve( Statement statement, Scope scope ) {
853875
break;
854876
case STMT_CASE:
855877
EXPresolve( statement->u.Case->selector, scope, Type_Dont_Care );
856-
type = statement->u.Case->selector->return_type;
857-
LISTdo( statement->u.Case->cases, c, Case_Item )
858-
CASE_ITresolve( c, scope, type );
859-
LISTod;
878+
LISTdo( statement->u.Case->cases, c, Case_Item ) {
879+
CASE_ITresolve( c, scope, statement );
880+
} LISTod;
860881
break;
861882
case STMT_COMPOUND:
862883
STMTlist_resolve( statement->u.compound->statements, scope );
@@ -912,7 +933,7 @@ void STMTresolve( Statement statement, Scope scope ) {
912933
break;
913934
case STMT_SKIP:
914935
case STMT_ESCAPE:
915-
/* do nothing */
936+
/* do nothing */ //WARNING should we really *not* do anything for these?
916937
;
917938
}
918939
}
@@ -1048,12 +1069,12 @@ void ENTITYcheck_missing_supertypes( Entity ent ) {
10481069
void ENTITYcalculate_inheritance( Entity e ) {
10491070
e->u.entity->inheritance = 0;
10501071

1051-
LISTdo( e->u.entity->supertypes, super, Entity )
1052-
if( super->u.entity->inheritance == ENTITY_INHERITANCE_UNINITIALIZED ) {
1053-
ENTITYcalculate_inheritance( super );
1054-
}
1055-
e->u.entity->inheritance += ENTITYget_size( super );
1056-
LISTod
1072+
LISTdo( e->u.entity->supertypes, super, Entity ) {
1073+
if( super->u.entity->inheritance == ENTITY_INHERITANCE_UNINITIALIZED ) {
1074+
ENTITYcalculate_inheritance( super );
1075+
}
1076+
e->u.entity->inheritance += ENTITYget_size( super );
1077+
} LISTod
10571078
}
10581079

10591080
/** returns 1 if entity is involved in circularity, else 0 */

src/fedex_plus/selects.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1109,7 +1109,7 @@ TYPEselect_lib_print_part_three( const Type type, FILE * f, Schema schema,
11091109
} else {
11101110
/* types are not the same issue a warning */
11111111
fprintf( stderr,
1112-
"WARNING: in SELECT TYPE %s: \n ambiguous "
1112+
"WARNING: in SELECT TYPE %s: ambiguous "
11131113
"attribute \"%s\" from underlying type \"%s\".\n\n",
11141114
TYPEget_name( type ), attrnm, TYPEget_name( t ) );
11151115
fprintf( f, " // %s\n // attribute access function"

0 commit comments

Comments
 (0)