polserver/pol-core/bscript/compiler/astbuilder/SourceFileProcessor.cpp

119 lines
4 KiB
C++
Raw Permalink Normal View History

#include "SourceFileProcessor.h"
2020-08-19 10:43:08 -07:00
#include "clib/fileutil.h"
#include "clib/timer.h"
#include "compiler/Profile.h"
#include "compiler/Report.h"
2020-08-19 10:43:08 -07:00
#include "compiler/ast/Statement.h"
#include "compiler/ast/TopLevelStatements.h"
#include "compiler/astbuilder/BuilderWorkspace.h"
#include "compiler/astbuilder/ModuleProcessor.h"
#include "compiler/file/SourceFile.h"
#include "compiler/file/SourceFileCache.h"
#include "compiler/file/SourceFileIdentifier.h"
#include "compiler/model/CompilerWorkspace.h"
#include "compilercfg.h"
using EscriptGrammar::EscriptParser;
namespace Pol::Bscript::Compiler
{
SourceFileProcessor::SourceFileProcessor( const SourceFileIdentifier& source_file_identifier,
BuilderWorkspace& workspace, bool is_src )
: profile( workspace.profile ),
report( workspace.report ),
source_file_identifier( source_file_identifier ),
workspace( workspace ),
tree_builder( source_file_identifier, workspace ),
is_src( is_src )
{
}
void SourceFileProcessor::use_module( const std::string& module_name,
SourceLocation& including_location,
long long* micros_counted )
{
std::string pathname = compilercfg.ModuleDirectory + module_name + ".em";
if ( workspace.source_files.find( pathname ) != workspace.source_files.end() )
return;
auto ident = std::make_unique<SourceFileIdentifier>(
workspace.compiler_workspace.referenced_source_file_identifiers.size(), pathname );
Pol::Tools::HighPerfTimer load_timer;
auto sf = workspace.em_cache.load( *ident, report );
long long load_elapsed = load_timer.ellapsed().count();
profile.load_em_micros += load_elapsed;
if ( !sf )
{
// This is fatal because if we keep going, we'll likely report a bunch of errors
// that would just be noise, like missing module function declarations or constants.
report.fatal( including_location, "Unable to use module '", module_name, "'.\n" );
}
workspace.source_files[ pathname ] = sf;
ModuleProcessor module_processor( *ident, workspace, module_name );
workspace.compiler_workspace.referenced_source_file_identifiers.push_back( std::move( ident ) );
Pol::Tools::HighPerfTimer get_module_unit_timer;
auto module_unit_context = sf->get_module_unit( report, source_file_identifier );
long long parse_elapsed = get_module_unit_timer.ellapsed().count();
profile.parse_em_micros += parse_elapsed;
profile.parse_em_count++;
Pol::Tools::HighPerfTimer visit_module_unit_timer;
module_unit_context->accept( &module_processor );
long long ast_elapsed = visit_module_unit_timer.ellapsed().count();
profile.ast_em_micros.fetch_add( ast_elapsed );
if ( micros_counted )
*micros_counted = load_elapsed + parse_elapsed + ast_elapsed;
}
2020-08-19 10:43:08 -07:00
void SourceFileProcessor::process_source( SourceFile& sf )
{
Pol::Tools::HighPerfTimer parse_timer;
auto compilation_unit = sf.get_compilation_unit( report, source_file_identifier );
long long parse_us_counted = parse_timer.ellapsed().count();
profile.parse_src_micros.fetch_add( parse_us_counted );
profile.parse_src_count++;
if ( report.error_count() == 0 )
{
Pol::Tools::HighPerfTimer ast_timer;
compilation_unit->accept( this );
long long ast_us_elapsed = ast_timer.ellapsed().count();
profile.ast_src_micros.fetch_add( ast_us_elapsed );
}
}
antlrcpp::Any SourceFileProcessor::visitStatement( EscriptParser::StatementContext* ctx )
{
2020-08-19 10:43:08 -07:00
if ( auto constStatement = ctx->constStatement() )
{
}
else
{
std::vector<std::unique_ptr<Statement>> statements;
tree_builder.add_statements( ctx, statements );
for ( auto& statement : statements )
{
workspace.compiler_workspace.top_level_statements->children.push_back(
std::move( statement ) );
}
}
return antlrcpp::Any();
}
SourceLocation SourceFileProcessor::location_for( antlr4::ParserRuleContext& ctx ) const
{
return { &source_file_identifier, ctx };
}
} // namespace Pol::Bscript::Compiler