2020-08-25 00:57:03 -07:00
|
|
|
#include "Variables.h"
|
|
|
|
|
|
2021-02-25 16:53:22 +01:00
|
|
|
#include "bscript/compiler/Report.h"
|
|
|
|
|
#include "bscript/compiler/file/SourceLocation.h"
|
|
|
|
|
#include "bscript/compiler/model/Variable.h"
|
2020-08-25 00:57:03 -07:00
|
|
|
|
|
|
|
|
namespace Pol::Bscript::Compiler
|
|
|
|
|
{
|
|
|
|
|
Variables::Variables( VariableScope scope, Report& report ) : scope( scope ), report( report ) {}
|
|
|
|
|
|
2020-12-01 02:23:03 -08:00
|
|
|
std::shared_ptr<Variable> Variables::create( const std::string& name, BlockDepth block_depth,
|
2020-08-25 00:57:03 -07:00
|
|
|
WarnOn warn_on, const SourceLocation& source_location )
|
|
|
|
|
{
|
|
|
|
|
auto index = names_by_index.size();
|
2024-01-12 06:51:44 +01:00
|
|
|
if ( index > std::numeric_limits<VariableIndex>::max() )
|
|
|
|
|
{
|
|
|
|
|
report.error( source_location, "Too many variables" );
|
2020-12-01 02:23:03 -08:00
|
|
|
}
|
|
|
|
|
auto variable = std::make_shared<Variable>(
|
|
|
|
|
scope, name, block_depth, static_cast<VariableIndex>( index ), warn_on, source_location );
|
2020-08-25 00:57:03 -07:00
|
|
|
variables_by_name[name] = variable;
|
|
|
|
|
names_by_index.push_back( name );
|
|
|
|
|
return variable;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<Variable> Variables::find( const std::string& name ) const
|
|
|
|
|
{
|
|
|
|
|
auto itr = variables_by_name.find( name );
|
|
|
|
|
return ( itr != variables_by_name.end() ) ? ( *itr ).second : std::shared_ptr<Variable>();
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-30 01:32:38 -07:00
|
|
|
void Variables::restore_shadowed( std::shared_ptr<Variable> variable )
|
|
|
|
|
{
|
|
|
|
|
// It's still in names_by_index
|
|
|
|
|
variables_by_name[variable->name] = std::move( variable );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Variables::remove_all_but( unsigned count )
|
|
|
|
|
{
|
|
|
|
|
while ( names_by_index.size() > count )
|
|
|
|
|
{
|
|
|
|
|
std::string last_name = names_by_index.back();
|
|
|
|
|
auto itr = variables_by_name.find( last_name );
|
|
|
|
|
|
2020-09-05 01:19:12 -07:00
|
|
|
if ( itr != variables_by_name.end() )
|
2020-08-30 01:32:38 -07:00
|
|
|
{
|
2020-09-05 01:19:12 -07:00
|
|
|
auto& removing = ( *itr ).second;
|
|
|
|
|
if ( removing->warn_on == WarnOn::IfUsed && removing->was_used() )
|
|
|
|
|
{
|
2024-01-12 06:51:44 +01:00
|
|
|
report.warning( removing->source_location,
|
|
|
|
|
"local variable '{}' declared as unused but used.", last_name );
|
2020-09-05 01:19:12 -07:00
|
|
|
}
|
|
|
|
|
else if ( removing->warn_on == WarnOn::IfNotUsed && !removing->was_used() )
|
|
|
|
|
{
|
2024-01-12 06:51:44 +01:00
|
|
|
report.warning( removing->source_location, "local variable '{}' was not used.", last_name );
|
2020-09-05 01:19:12 -07:00
|
|
|
}
|
|
|
|
|
variables_by_name.erase( itr );
|
2020-08-30 01:32:38 -07:00
|
|
|
}
|
|
|
|
|
names_by_index.pop_back();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-25 00:57:03 -07:00
|
|
|
const std::vector<std::string>& Variables::get_names() const
|
|
|
|
|
{
|
|
|
|
|
return names_by_index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned Variables::count() const
|
|
|
|
|
{
|
2020-12-01 02:23:03 -08:00
|
|
|
return static_cast<unsigned>( names_by_index.size() );
|
2020-08-25 00:57:03 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace Pol::Bscript::Compiler
|