Parser - Errors when using inputs in initialisation
This commit is contained in:
parent
5d3aa32e9d
commit
773efeff54
1 changed files with 61 additions and 59 deletions
120
opparser.cc
120
opparser.cc
|
@ -685,67 +685,69 @@ bool T_ParserImpl_::checkIdentifierExpressions( ) noexcept
|
|||
T_StringBuilder esb;
|
||||
for ( cfi = 0 ; cfi < output->root.nFunctions( ) ; cfi ++ ) {
|
||||
auto& function( output->root.function( cfi ) );
|
||||
visitor.visit( function ,
|
||||
[&]( A_Node& n , const bool exit ) -> bool {
|
||||
if ( exit ) {
|
||||
return true;
|
||||
visitor.visit( function , [&]( A_Node& n , const bool exit ) -> bool {
|
||||
if ( exit ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check get-input expressions
|
||||
if ( n.type( ) == A_Node::EXPR_INPUT ) {
|
||||
auto& e( dynamic_cast< T_InputExprNode& >( n ) );
|
||||
auto const* const t( output->types.get( e.id( ) ) );
|
||||
if ( !t ) {
|
||||
errors.addNew( "no such input" , e.idLocation( ) );
|
||||
} else if ( *t != E_DataType::INPUT ) {
|
||||
esb << "'" << e.id( ) << "' used as input but declared as a "
|
||||
<< *t;
|
||||
errors.addNew( std::move( esb ) , e.idLocation( ) );
|
||||
} else if ( callInfo[ cfi ] & E_InstrRestriction::INIT ) {
|
||||
errors.addNew( "input used in initialisation" ,
|
||||
e.location( ) );
|
||||
}
|
||||
|
||||
// Check get-input expressions
|
||||
if ( n.type( ) == A_Node::EXPR_INPUT ) {
|
||||
auto& e( dynamic_cast< T_InputExprNode& >( n ) );
|
||||
auto const* const t( output->types.get( e.id( ) ) );
|
||||
if ( !t ) {
|
||||
errors.addNew( "no such input" , e.idLocation( ) );
|
||||
} else if ( *t != E_DataType::INPUT ) {
|
||||
esb << "'" << e.id( ) << "' used as input but declared as a "
|
||||
<< *t;
|
||||
errors.addNew( std::move( esb ) , e.idLocation( ) );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( n.type( ) != A_Node::EXPR_ID ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check use of identifiers in expressions
|
||||
auto& e( dynamic_cast< T_IdentifierExprNode& >( n ) );
|
||||
auto const* const gType{ output->types.get( e.id( ) ) };
|
||||
if ( gType ) {
|
||||
// FIXME handle aliases
|
||||
|
||||
// Variables are fine
|
||||
if ( *gType == E_DataType::VARIABLE ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check builtins
|
||||
if ( *gType == E_DataType::BUILTIN ) {
|
||||
if ( ( callInfo[ cfi ] & E_InstrRestriction::INIT )
|
||||
&& e.id( ) == "time" ) {
|
||||
errors.addNew( "'time' built-in used in initialisation" ,
|
||||
e.location( ) );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// We'll allow other types to be used in an expression
|
||||
// in the context of the call instruction.
|
||||
if ( e.parent( ).type( ) == A_Node::OP_CALL ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
esb << "'" << e.id( ) << "' used as a variable but declared as a "
|
||||
<< *gType;
|
||||
errors.addNew( std::move( esb ) , e.location( ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME check locals
|
||||
|
||||
return false;
|
||||
} );
|
||||
}
|
||||
|
||||
if ( n.type( ) != A_Node::EXPR_ID ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check use of identifiers in expressions
|
||||
auto& e( dynamic_cast< T_IdentifierExprNode& >( n ) );
|
||||
auto const* const gType{ output->types.get( e.id( ) ) };
|
||||
if ( gType ) {
|
||||
// FIXME handle aliases
|
||||
|
||||
// Variables are fine
|
||||
if ( *gType == E_DataType::VARIABLE ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check builtins
|
||||
if ( *gType == E_DataType::BUILTIN ) {
|
||||
if ( ( callInfo[ cfi ] & E_InstrRestriction::INIT )
|
||||
&& e.id( ) == "time" ) {
|
||||
errors.addNew( "'time' built-in used in initialisation" ,
|
||||
e.location( ) );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// We'll allow other types to be used in an expression
|
||||
// in the context of the call instruction.
|
||||
if ( e.parent( ).type( ) == A_Node::OP_CALL ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
esb << "'" << e.id( ) << "' used as a variable but declared as a "
|
||||
<< *gType;
|
||||
errors.addNew( std::move( esb ) , e.location( ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME check locals
|
||||
|
||||
return false;
|
||||
} );
|
||||
}
|
||||
return errors.empty( );
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue