7575#include "express/resolve.h"
7676
7777#include <assert.h>
78+ #include <limits.h>
7879
7980struct 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 */
789826void EXPop_create ( int token_number , char * string , Resolve_expr_func * resolve_func ) {
790827 EXPop_table [token_number ].token = string ;
0 commit comments