Compare commits
1 commit
master
...
mp/impossi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
142b75ce64 |
3 changed files with 36 additions and 3 deletions
|
|
@ -65,6 +65,14 @@ GLOBAL SCL_EXPRESS_EXPORT Error ERROR_circular_reference INITIALLY( ERROR_
|
|||
GLOBAL SCL_EXPRESS_EXPORT Error ERROR_ambiguous_attribute INITIALLY( ERROR_none );
|
||||
GLOBAL SCL_EXPRESS_EXPORT Error ERROR_ambiguous_group INITIALLY( ERROR_none );
|
||||
|
||||
/** If we're inside a conditional statement (within a function, procedure, etc)
|
||||
* then this variable points to that statement. Currently the only use is to
|
||||
* suppress errors when the test in an IF...ENDIF always evaluates one way.
|
||||
* Set within STMTresolve().
|
||||
* \sa STMTresolve
|
||||
*/
|
||||
GLOBAL SCL_EXPRESS_EXPORT Statement currCondStmt INITIALLY(0);
|
||||
|
||||
#undef GLOBAL
|
||||
#undef INITIALLY
|
||||
|
||||
|
|
|
|||
|
|
@ -286,6 +286,17 @@ static int EXP_resolve_op_dot_fuzzy( Type selection, Symbol ref, Variable * v, c
|
|||
}
|
||||
}
|
||||
|
||||
/// evaluate the test for the conditional statement that we're currently in
|
||||
/// if its value can be determined, return LTrue/LFalse, otherwise LUnknown
|
||||
Logical EXP_eval_conditional() {
|
||||
Expression t = currCondStmt->u.cond->test;
|
||||
//go through t, looking for tautologies
|
||||
//if found, store and print warning when execution is done (per Tom T)
|
||||
FIXME //FIXME incomplete
|
||||
|
||||
return Lunknown;
|
||||
}
|
||||
|
||||
Type EXPresolve_op_dot( Expression expr, Scope scope ) {
|
||||
Expression op1 = expr->e.op1;
|
||||
Expression op2 = expr->e.op2;
|
||||
|
|
@ -328,10 +339,14 @@ Type EXPresolve_op_dot( Expression expr, Scope scope ) {
|
|||
switch( options ) {
|
||||
case 0:
|
||||
/* no possible resolutions */
|
||||
ERRORreport_with_symbol( ERROR_undefined_attribute,
|
||||
if( ( currCondStmt != 0 ) && ( EXP_eval_conditional() != Lunknown) ) {
|
||||
return( Type_Runtime );
|
||||
} else {
|
||||
ERRORreport_with_symbol( ERROR_undefined_attribute,
|
||||
&op2->symbol, op2->symbol.name );
|
||||
resolve_failed( expr );
|
||||
return( Type_Bad );
|
||||
resolve_failed( expr );
|
||||
return( Type_Bad );
|
||||
}
|
||||
case 1:
|
||||
/* only one possible resolution */
|
||||
if( dt != OBJ_VARIABLE ) {
|
||||
|
|
|
|||
|
|
@ -842,6 +842,7 @@ void CASE_ITresolve( Case_Item item, Scope scope, Type type ) {
|
|||
void STMTresolve( Statement statement, Scope scope ) {
|
||||
Type type;
|
||||
Scope proc;
|
||||
Statement lastCondStmt = 0; ///< used to store the previous value of currCondStmt
|
||||
|
||||
if( !statement ) {
|
||||
return; /* could be null statement */
|
||||
|
|
@ -871,11 +872,20 @@ void STMTresolve( Statement statement, Scope scope ) {
|
|||
STMTlist_resolve( statement->u.compound->statements, scope );
|
||||
break;
|
||||
case STMT_COND:
|
||||
if( currCondStmt ) {
|
||||
lastCondStmt = currCondStmt;
|
||||
}
|
||||
currCondStmt = statement;
|
||||
EXPresolve( statement->u.cond->test, scope, Type_Dont_Care );
|
||||
STMTlist_resolve( statement->u.cond->code, scope );
|
||||
if( statement->u.cond->otherwise ) {
|
||||
STMTlist_resolve( statement->u.cond->otherwise, scope );
|
||||
}
|
||||
if( lastCondStmt ) {
|
||||
currCondStmt = lastCondStmt;
|
||||
} else {
|
||||
currCondStmt = 0;
|
||||
}
|
||||
break;
|
||||
case STMT_PCALL:
|
||||
#define proc_name statement->symbol.name
|
||||
|
|
|
|||
Loading…
Reference in a new issue