#include "parse.h"
#include "builtins/builtins.h"
using namespace empathy;
using namespace empathy::parse;
optional< Value > Parser::parse( uint32_t precedence )
{
auto next = m_resolver->lookAhead();
if( !next )
return nullopt;
auto leftVal = parsePrefix( *next, precedence );
if( !leftVal )
return nullopt;
push( leftVal );
while( next = m_resolver->lookAhead() )
{
auto prec = getPrecedence( *next );
if( !prec || precedence > *prec )
return result();
auto val = parseInfix( *next, *prec );
if( !val )
return result();
push( *val );
}
return result();
}
optional< 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&& content )
{
return getPrecedence( t, content );
}, t.content() );
}
optional< Value > Parser::parsePrefix( const Term& t, uint32_t precedence )
{
return visit( [&]( auto&& content )
{
return parsePrefix( content, precedence );
}, t.content() );
}
optional< Value > Parser::parseInfix( const Term& t, uint32_t precedence )
{
return visit( [&]( auto&& content )
{
return parseInfix( content, precedence );
}, t.content() );
}
optional< Value > Parser::parsePrefix( uint64_t intlit, uint32_t )
{
m_resolver->consume();
return ToValue( intlit );
}
optional< Value > Parser::parsePrefix( const string& strlit, uint32_t )
{
m_resolver->consume();
return ToValue( strlit );
}
// Standalone (ie not part of a grammar construct that expects them such as a decl), unresolved identifiers
// end up here.
optional< Value > Parser::parsePrefix( const StringId& strid, uint32_t )
{
m_resolver->consume();
// TODO location, poisoning
cout << "undefined identifier '" << strid.c_str() << "'\n";
return nullopt;
}
optional< uint32_t > Parser::getPrecedence( const Term& t, const pvec& vec )
{
auto val = ValueFromIRExpr( t );
if( !val )
return nullopt;
// If the term is an infix rule value, invoke its getPrecedence() function.
auto rule = FromValue< Rule >( *val );
if( !rule )
return nullopt;
if( !rule->isInfix() )
return nullopt;
return rule->getPrecedence( *this, t );
}
optional< Value > Parser::parsePrefix( const pvec& vec, uint32_t prec )
{
auto t = *m_resolver->consume();
auto val = ValueFromIRExpr( t );
if( !val )
return nullopt;
// If the term is a prefix rule value, invoke its parsePrefix() function.
auto rule = FromValue< Rule >( *val );
if( !rule )
return val;
if( !rule->isPrefix() )
return val;
return rule->parsePrefix( *this, t, prec );
}
optional< Value > Parser::parseInfix( const pvec& vec, uint32_t prec )
{
auto t = *m_resolver->consume();
auto val = ValueFromIRExpr( t );
if( !val )
return nullopt;
// If the term is an infix rule value, invoke its parseInfix() function.
auto rule = FromValue< Rule >( *val );
if( !rule )
return nullopt;
if( !rule->isInfix() )
return nullopt;
return rule->parseInfix( *this, t, prec );
}