#include "builtins/builtins.h"
#include "parse/parse.h"
#include "precedence.h"
using namespace goose;
using namespace goose::eir;
using namespace goose::parse;
namespace goose::builtins
{
void SetupUsingStmt( Env& e )
{
auto handleUsing = []( Parser& p, uint32_t locationId, uint32_t prec )
{
auto& dm = DiagnosticsManager::GetInstance();
auto nameTerm = p.resolver()->consume();
if( !nameTerm )
{
dm.emitSyntaxErrorMessage( p.resolver()->currentLocation(), "expected an identifier.", 0 );
return false;
}
const auto* name = get_if< StringId >( &nameTerm->first );
if( !name )
{
dm.emitSyntaxErrorMessage( nameTerm->second, "expected an identifier.", 0 );
return false;
}
auto& context = p.context();
auto localIdentity = DuplicateVectorTerm( context.identity() );
get< pvec >( localIdentity )->terms().back() = nameTerm->first;
context.env()->addVisibilityRule( context.identity(), localIdentity );
auto eqTerm = p.resolver()->consumeUnresolved();
if( !eqTerm )
{
dm.emitSyntaxErrorMessage( p.resolver()->currentLocation(), "expected '='.", 0 );
context.env()->storeValue( localIdentity, ANYTERM( _ ), ValueToIRExpr( PoisonValue() ) );
return true;
}
const auto* eq = get_if< StringId >( &eqTerm->first );
if( !eq || *eq != "="_sid )
{
dm.emitSyntaxErrorMessage( eqTerm->second, "expected '='.", 0 );
context.env()->storeValue( localIdentity, ANYTERM( _ ), ValueToIRExpr( PoisonValue() ) );
return true;
}
auto np = p.makeNestedParser();
if( !np.parseExpression( precedence::UsingStmt ) )
{
DiagnosticsManager::GetInstance().emitSyntaxErrorMessage( locationId,
"expected an expression.", 0 );
context.env()->storeValue( localIdentity, ANYTERM( _ ), ValueToIRExpr( PoisonValue() ) );
return true;
}
if( !np.peekLastValue() )
{
DiagnosticsManager::GetInstance().emitSyntaxErrorMessage( locationId,
"expected an expression.", 0 );
context.env()->storeValue( localIdentity, ANYTERM( _ ), ValueToIRExpr( PoisonValue() ) );
return true;
}
context.env()->storeValue( localIdentity, ANYTERM( _ ), ValueToIRExpr( *np.popValue() ) );
return true;
};
Rule r( handleUsing );
auto ruleVal = ToValue( move( r ) );
auto ruleTerm = ValueToIRExpr( ruleVal );
e.storeValue( AppendToVectorTerm( RootIdentity(), TSID( using ) ), ANYTERM( _ ), ruleTerm );
}
}