#include "builtins/builtins.h"
#include "parse/parse.h"
#include "precedence.h"
#include "builtins/helpers.h"
using namespace goose;
using namespace goose::eir;
using namespace goose::parse;
namespace goose::builtins
{
void SetupBreakStmt( Env& e )
{
auto handleBreak = []( Parser& p, uint32_t locationId, uint32_t prec )
{
auto& dm = DiagnosticsManager::GetInstance();
const auto& cb = p.context().codeBuilder();
if( p.isInParenExpr() || !cb || !cb->breakableScopeLevels() )
{
dm.emitSyntaxErrorMessage( locationId, "the break statement is not allowed here.", 0 );
return false;
}
const auto& cfg = cb->cfg();
if( !cfg->currentBB() || cfg->currentBB()->terminator() )
{
DiagnosticsManager::GetInstance().emitSyntaxErrorMessage(
locationId, "unreachable code.", 0 );
cb->poison();
return true;
}
// Emit cleanups for all live variables in the scopes that we are breaking through.
cb->destroyAllLiveValuesFromBreakScope( p.context(), cb->breakableScopeLevels() );
cfg->currentBB()->setTerminator( cir::Break( cb->breakableScopeLevels() ) );
return true;
};
Rule r( handleBreak );
auto ruleVal = ToValue( move( r ) );
auto ruleTerm = ValueToEIR( ruleVal );
e.storeValue( AppendToVectorTerm( RootIdentity(), TSID( break ) ), ANYTERM( _ ), ruleTerm );
}
}