#include "builtins/builtins.h"
#include "lex/lex.h"
#include "parse/parse.h"
using namespace empathy::builtins;
using namespace empathy::parse;
namespace empathy::builtins
{
pair< Term, Term > GetFuncSigAndRType( const Value& func )
{
auto funcType = ValueFromIRExpr( func.type() );
assert( funcType );
auto decomp = Decompose( funcType->val(),
Vec(
Lit( "func"_sid ),
SubTerm(), // kind
SubTerm(), // return type
SubTerm(), // param types
SubTerm() // signature
)
);
assert( decomp );
auto&& [kind, rtype, ptypes, sig] = *decomp;
return { sig, rtype };
}
ParamListKind CheckParamListKind( const Value& tup )
{
if( !IsTuple( tup ) )
return ParamListKind::Invalid;
auto result = ParamListKind::Regular;
const auto& vec = *get< pvec >( tup.val().content() );
for( auto&& x : vec.terms() )
{
auto v = ValueFromIRExpr( x );
if( !v )
return ParamListKind::Invalid;
if( IsTDecl( *v ) || IsTNamedDecl( *v ) )
result = ParamListKind::Template;
else if( !IsDecl( *v ) && !v->isConstant() )
return ParamListKind::Invalid;
}
return result;
}
void PerformLazyFuncParsing( const ptr< Env >& env, const Value& func )
{
const auto& content = func.val().content();
const auto& pLLR = get< ptr< void > >( content );
const auto& pFunc = static_pointer_cast< llr::Func >( pLLR );
const auto* pToks = get_if< vector< Term > >( &pFunc->body() );
if( !pToks )
return;
Context localContext( env, pFunc->identity() );
auto tokProvider = make_shared< lex::VectorAdapter >( *pToks );
auto r = make_shared< parse::Resolver >( tokProvider, localContext );
Parser p( r );
if( !p.parseExpression() )
pFunc->body() = llr::Element();
auto result = p.result();
if( !result || result->isConstant() )
pFunc->body() = llr::Element();
else
pFunc->body() = *result->llr();
}
}
namespace empathy::ir
{
const Term& Bridge< FuncType >::Type()
{
static auto type = TSID( type );
return type;
}
Value Bridge< FuncType >::ToValue( const FuncType& ft )
{
return Value( Type(), TVEC( TSID( func ), TSID( regular ),
ft.returnType(), ft.paramTypes(), ft.signature() ) );
}
optional< FuncType > Bridge< FuncType >::FromValue( const Value& v )
{
auto typeVal = ValueFromIRExpr( v.type() );
auto result = Decompose( typeVal->val(),
Vec(
Lit( "func"_sid ),
Lit( "regular"_sid ),
SubTerm(), // return type
SubTerm(), // param types
SubTerm() // signature
)
);
if( !result )
return nullopt;
auto&& [rtype, params, sig] = *result;
return FuncType( move( rtype ), move( params ), move( sig ) );
}
}