From 20aea4f809ad894d67d09e76ccc2881438981dde Mon Sep 17 00:00:00 2001
From: Philipp Paulweber
Date: Sat, 29 Apr 2017 02:32:06 +0200
Subject: [PATCH] Symbol Resolver
* changed and fixed stack-frame variable handling
- related to ref casm-lang/casm#22
---
src/analyze/SymbolResolverPass.cpp | 63 ++++++++++++++++++------------
1 file changed, 39 insertions(+), 24 deletions(-)
diff --git a/src/analyze/SymbolResolverPass.cpp b/src/analyze/SymbolResolverPass.cpp
index 3f6d77553..ecaa969e9 100644
--- a/src/analyze/SymbolResolverPass.cpp
+++ b/src/analyze/SymbolResolverPass.cpp
@@ -173,7 +173,7 @@ class SymbolResolveVisitor final : public RecursiveVisitor
private:
void push( VariableDefinition& identifier );
- void pop( const VariableDefinition& identifier );
+ void pop( VariableDefinition& identifier );
Logger& m_log;
u64 m_err;
@@ -182,13 +182,19 @@ class SymbolResolveVisitor final : public RecursiveVisitor
class Variable
{
public:
- Variable(
- const std::size_t localIndex, const VariableDefinition& definition )
- : m_localIndex( localIndex )
+ Variable( const std::string& name, const std::size_t localIndex,
+ const VariableDefinition& definition )
+ : m_name( name )
+ , m_localIndex( localIndex )
, m_definition( static_cast< const TypedNode& >( definition ) )
{
}
+ std::string name( void ) const
+ {
+ return m_name;
+ }
+
std::size_t localIndex( void ) const
{
return m_localIndex;
@@ -200,11 +206,12 @@ class SymbolResolveVisitor final : public RecursiveVisitor
}
private:
+ std::string m_name;
std::size_t m_localIndex;
const TypedNode& m_definition;
};
- std::unordered_map< std::string, Variable > m_variables;
+ std::vector< Variable > m_variables;
std::size_t m_maxNumberOfLocals; /**< Used to calculate the minimum number
of frame slots required for derived
functions and rules during execution */
@@ -230,9 +237,11 @@ void SymbolResolveVisitor::visit( DerivedDefinition& node )
RecursiveVisitor::visit( node );
- for( const auto& argument : *node.arguments() )
+ for( auto it = ( *node.arguments() ).rbegin();
+ it != ( *node.arguments() ).rend();
+ it++ )
{
- pop( *argument );
+ pop( **it );
}
node.setMaximumNumberOfLocals( m_maxNumberOfLocals );
@@ -249,9 +258,11 @@ void SymbolResolveVisitor::visit( RuleDefinition& node )
RecursiveVisitor::visit( node );
- for( const auto& argument : *node.arguments() )
+ for( auto it = ( *node.arguments() ).rbegin();
+ it != ( *node.arguments() ).rend();
+ it++ )
{
- pop( *argument );
+ pop( **it );
}
node.setMaximumNumberOfLocals( m_maxNumberOfLocals );
@@ -335,13 +346,16 @@ void SymbolResolveVisitor::visit( DirectCallExpression& node )
}
else
{
- auto variable = m_variables.find( name );
+ const auto variable = std::find_if( m_variables.rbegin(),
+ m_variables.rend(), [&name]( const Variable& v ) {
+ return v.name().compare( name ) == 0;
+ } );
- if( variable != m_variables.end() )
+ if( variable != m_variables.rend() )
{
node.setTargetType( CallExpression::TargetType::VARIABLE );
node.setTargetDefinition(
- variable->second.definition().ptr< TypedNode >() );
+ variable->definition().ptr< TypedNode >() );
}
else
{
@@ -391,28 +405,29 @@ void SymbolResolveVisitor::push( VariableDefinition& node )
{
const auto& name = node.identifier()->name();
- const std::size_t localIndex = m_variables.size(); // used during execution
- node.setLocalIndex( localIndex );
- const auto result
- = m_variables.emplace( name, Variable{ localIndex, node } );
- if( not result.second )
+ auto variable = std::find_if(
+ m_variables.rbegin(), m_variables.rend(), [&name]( const Variable& v ) {
+ return v.name().compare( name ) == 0;
+ } );
+
+ if( variable != m_variables.rend() )
{
m_err++;
m_log.error( { node.sourceLocation() },
"symbol '" + name + "' already defined" );
}
+ const std::size_t localIndex = m_variables.size(); // used during execution
+ m_variables.emplace_back( Variable{ name, localIndex, node } );
+
+ node.setLocalIndex( localIndex );
m_maxNumberOfLocals = std::max( m_maxNumberOfLocals, m_variables.size() );
}
-void SymbolResolveVisitor::pop( const VariableDefinition& node )
+void SymbolResolveVisitor::pop( VariableDefinition& node )
{
- const auto& name = node.identifier()->name();
-
- if( m_variables.erase( name ) != 1 )
- {
- assert( !" internal error! " );
- }
+ assert( &m_variables.back().definition() == &node );
+ m_variables.pop_back();
}
u64 SymbolResolveVisitor::errors( void ) const