#include "parse.h"
using namespace empathy;
using namespace empathy::parse;
optional< ir::Value > Parser::parse( uint32_t precedence )
{
auto next = m_resolver.lookAhead();
if( !next )
return nullopt;
auto leftVal = parsePrefix( *m_resolver.consume(), precedence );
if( !leftVal )
return nullopt;
push( leftVal );
while( next = m_resolver.lookAhead() )
{
auto prec = getPrecedence( *next );
if( !prec || precedence > *prec )
return result();
push( *parseInfix( *m_resolver.consume(), *prec ) );
}
return result();
}
optional< ir::Value > Parser::result() const
{
if( !m_seq )
return m_lastValue;
if( m_seq && m_lastValue )
{
const auto& llr = m_lastValue->llr();
m_seq->emplace_back( move( *llr ) );
return Value( m_lastValue->type(), m_seq );
}
return nullopt;
}
optional< uint32_t > Parser::getPrecedence( const Term& t )
{
return visit( [&]( auto&& t )
{
return getPrecedence( t );
}, t.content() );
}
optional< ir::Value > Parser::parsePrefix( const Term& t, uint32_t precedence )
{
return visit( [&]( auto&& t )
{
return parsePrefix( t, precedence );
}, t.content() );
}
optional< ir::Value > Parser::parseInfix( const Term& t, uint32_t precedence )
{
return visit( [&]( auto&& t )
{
return parseInfix( t, precedence );
}, t.content() );
}
optional< ir::Value > Parser::parsePrefix( uint64_t intlit, uint32_t )
{
static auto type = TSID( integer_literal );
return ir::Value( type, TERM( intlit ) );
}
optional< ir::Value > Parser::parsePrefix( string strlit, uint32_t )
{
static auto type = TSID( string_literal );
return ir::Value( type, TERM( strlit ) );
}