Skip to content

Commit

Permalink
Symbol Resolver Pass and Namespace
Browse files Browse the repository at this point in the history
* changed content of Namespace implementation from plain
  Ast::CallExpression::TargetType to a internal class 'Symbol', which
  contains besides the target type, the name, the definition and the
  artiy of a symbol
* updated the resolver pass
  - related to ref sealangdotorg/sea#22
* added new API function to the namespace implementation to lookup
  besides call expressions also basic types
  - needed and related to ref sealangdotorg/sea#20
  • Loading branch information
ppaulweber committed Apr 5, 2017
1 parent 881ac07 commit 4334b20
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 49 deletions.
125 changes: 94 additions & 31 deletions src/Namespace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,56 +32,77 @@ using namespace Ast;

static std::string key( const IdentifierNode& node, const std::size_t arity );

Namespace::Namespace( void )
//
// Symbol
//

Namespace::Symbol::Symbol( const Ast::IdentifierNode& identifier,
Ast::Node& definition,
const Ast::CallExpression::TargetType targetType,
const std::size_t arity )
: m_identifier( identifier )
, m_definition( definition )
, m_targetType( targetType )
, m_arity( arity )
{
}

u64 Namespace::registerSymbol( Logger& log, const IdentifierNode& node,
const CallExpression::TargetType targetType, const std::size_t arity )
const Ast::IdentifierNode& Namespace::Symbol::identifier( void ) const
{
const auto _key = key( node, arity );
return m_identifier;
}

auto result = m_symboltable.emplace( _key, targetType );
Ast::Node& Namespace::Symbol::definition( void )
{
return m_definition;
}

if( not result.second )
{
log.error( { node.sourceLocation() },
"symbol '" + result.first->first + "' already defined as '"
+ CallExpression::targetTypeString( result.first->second )
+ "'" );
Ast::CallExpression::TargetType Namespace::Symbol::targetType( void ) const
{
return m_targetType;
}

return 1;
}
std::size_t Namespace::Symbol::arity( void ) const
{
return m_arity;
}

log.debug( "registered new symbol '" + result.first->first + "' as '"
+ CallExpression::targetTypeString( result.first->second )
+ "'" );
//
// Namespace
//

return 0;
Namespace::Namespace( void )
{
}

u64 Namespace::registerSymbol( Logger& log, const DirectCallExpression& node )
{
return registerSymbol( log, *node.identifier(), node,
CallExpression::TargetType::FUNCTION, node.arguments()->size() );
}

u64 Namespace::registerSymbol( Logger& log, const FunctionDefinition& node )
{
return registerSymbol( log, *node.identifier(),
return registerSymbol( log, *node.identifier(), node,
CallExpression::TargetType::FUNCTION, node.argumentTypes()->size() );
}

u64 Namespace::registerSymbol( Logger& log, const DerivedDefinition& node )
{
return registerSymbol( log, *node.identifier(),
return registerSymbol( log, *node.identifier(), node,
CallExpression::TargetType::DERIVED, node.arguments()->size() );
}

u64 Namespace::registerSymbol( Logger& log, const RuleDefinition& node )
{
return registerSymbol( log, *node.identifier(),
return registerSymbol( log, *node.identifier(), node,
CallExpression::TargetType::RULE, node.arguments()->size() );
}

u64 Namespace::registerSymbol( Logger& log, const EnumerationDefinition& node )
{
auto err = registerSymbol(
log, *node.identifier(), CallExpression::TargetType::ENUMERATION );
auto err = registerSymbol( log, *node.identifier(), node,
CallExpression::TargetType::ENUMERATION );

auto enumerationNamespace = libstdhl::make< Namespace >();

Expand All @@ -99,27 +120,41 @@ u64 Namespace::registerSymbol( Logger& log, const EnumerationDefinition& node )
for( auto e : *node.enumerators() )
{
err += enumerationNamespace->registerSymbol(
log, *e, CallExpression::TargetType::CONSTANT );
log, *e, node, CallExpression::TargetType::CONSTANT );
}

return err;
}

CallExpression::TargetType Namespace::find(
const DirectCallExpression& node ) const
Namespace::Symbol Namespace::find( const DirectCallExpression& node ) const
{
const auto arity = node.arguments()->size();
const auto _key = key( *node.identifier(), arity );

auto result = m_symboltable.find( _key );
if( result != m_symboltable.end() )
if( result == m_symboltable.end() )
{
return result->second;
throw std::domain_error( "unable to find " + std::to_string( arity )
+ " symbol '"
+ node.identifier()->identifier()
+ "'" );
}
else

return result->second;
}

Namespace::Symbol Namespace::find( const BasicType& node ) const
{
const auto _key = key( *node.name(), 0 );

auto result = m_symboltable.find( _key );
if( result == m_symboltable.end() )
{
return CallExpression::TargetType::UNKNOWN;
throw std::domain_error(
"unable to find type symbol '" + node.name()->identifier() + "'" );
}

return result->second;
}

std::string Namespace::dump( const std::string& indention ) const
Expand All @@ -135,8 +170,8 @@ std::string Namespace::dump( const std::string& indention ) const
const auto& name = parts[ 1 ];

s << indention << name << " : "
<< CallExpression::targetTypeString( v.second ) << "( " << arity
<< "-ary)\n";
<< CallExpression::targetTypeString( v.second.targetType() ) << "( "
<< arity << "-ary)\n";
}

for( auto v : m_namespaces )
Expand All @@ -150,6 +185,34 @@ std::string Namespace::dump( const std::string& indention ) const
return s.str();
}

u64 Namespace::registerSymbol( Logger& log, const IdentifierNode& node,
const Node& definition, const CallExpression::TargetType targetType,
const std::size_t arity )
{
const auto _key = key( node, arity );

auto result = m_symboltable.emplace( _key,
Symbol{ node, const_cast< Node& >( definition ), targetType, arity } );

if( not result.second )
{
log.error( { node.sourceLocation() },
"symbol '" + result.first->first + "' already defined as '"
+ CallExpression::targetTypeString(
result.first->second.targetType() )
+ "'" );

return 1;
}

log.debug(
"registered new symbol '" + result.first->first + "' as '"
+ CallExpression::targetTypeString( result.first->second.targetType() )
+ "'" );

return 0;
}

static std::string key( const IdentifierNode& node, const std::size_t arity )
{
const auto identifier = node.identifier();
Expand Down
39 changes: 32 additions & 7 deletions src/Namespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,34 @@ namespace libcasm_fe
*/
class Namespace
{
public:
class Symbol
{
public:
Symbol( const Ast::IdentifierNode& identifier,
Ast::Node& definition,
const Ast::CallExpression::TargetType targetType,
const std::size_t arity );

const Ast::IdentifierNode& identifier( void ) const;
Ast::Node& definition( void );
Ast::CallExpression::TargetType targetType( void ) const;
std::size_t arity( void ) const;

private:
const Ast::IdentifierNode& m_identifier;
Ast::Node& m_definition;
Ast::CallExpression::TargetType m_targetType;
std::size_t m_arity;
};

public:
using Ptr = std::shared_ptr< Namespace >;

Namespace( void );

u64 registerSymbol( Logger& log, const Ast::IdentifierNode& node,
const Ast::CallExpression::TargetType targetType,
const std::size_t arity = 0 );
u64 registerSymbol(
Logger& log, const Ast::DirectCallExpression& node );

u64 registerSymbol( Logger& log, const Ast::FunctionDefinition& node );

Expand All @@ -55,14 +75,19 @@ namespace libcasm_fe
u64 registerSymbol(
Logger& log, const Ast::EnumerationDefinition& node );

Ast::CallExpression::TargetType find(
const Ast::DirectCallExpression& node ) const;
Symbol find( const Ast::DirectCallExpression& node ) const;

Symbol find( const Ast::BasicType& node ) const;

std::string dump( const std::string& indention = "" ) const;

private:
std::unordered_map< std::string, Ast::CallExpression::TargetType >
m_symboltable;
u64 registerSymbol( Logger& log, const Ast::IdentifierNode& node,
const Ast::Node& definition,
const Ast::CallExpression::TargetType targetType,
const std::size_t arity = 0 );

std::unordered_map< std::string, Symbol > m_symboltable;

std::unordered_map< std::string, Namespace::Ptr > m_namespaces;
};
Expand Down
17 changes: 6 additions & 11 deletions src/analyze/SymbolResolverPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,23 +151,18 @@ SymbolResolveVisitor::SymbolResolveVisitor(

void SymbolResolveVisitor::visit( DirectCallExpression& node )
{
const auto targetType = m_symboltable.find( node );

const auto name = node.identifier()->identifier();

if( targetType != CallExpression::TargetType::UNKNOWN )
try
{
node.setTargetType( targetType );
const auto symbol = m_symboltable.find( node );
node.setTargetType( symbol.targetType() );
}
else
catch( const std::domain_error& e )
{
const auto arity = node.arguments()->size();

if( libcasm_ir::Builtin::available( name, arity ) )
if( libcasm_ir::Builtin::available( name, node.arguments()->size() ) )
{
m_err += m_symboltable.registerSymbol( m_log, *node.identifier(),
CallExpression::TargetType::BUILTIN, arity );

m_err += m_symboltable.registerSymbol( m_log, node );
node.setTargetType( CallExpression::TargetType::BUILTIN );
}
else if( m_variables.find( name ) != m_variables.end() )
Expand Down

0 comments on commit 4334b20

Please sign in to comment.