Skip to content

Commit

Permalink
Symbol Resolver
Browse files Browse the repository at this point in the history
* changed and fixed stack-frame variable handling
  - related to ref sealangdotorg/sea#22
  • Loading branch information
ppaulweber committed Apr 29, 2017
1 parent 562ef57 commit 20aea4f
Showing 1 changed file with 39 additions and 24 deletions.
63 changes: 39 additions & 24 deletions src/analyze/SymbolResolverPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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 */
Expand All @@ -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 );
Expand All @@ -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 );
Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 20aea4f

Please sign in to comment.