Goose  Artifact [b301f2e8a5]

Artifact b301f2e8a560d90db21f15e8ea38ecac9ee8371c730fa777243e584b0ccc6376:

  • File bs/compiler.cpp — part of check-in [3c074f1b7d] at 2019-07-30 22:05:49 on branch trunk —
    • Builtin functions are now explicitely marked if they need to be evaluated eagerly.
    • Using errors out if the expression doesn't evaluate to a constant.
    (user: achavasse size: 1994)

#include "compiler.h"
#include "builtins/builtins.h"
#include "builtins/helpers.h"
#include "sema/sema.h"
#include "execute/execute.h"

#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/TargetSelect.h"

using namespace empathy;
using namespace empathy::util;
using namespace empathy::ir;

Compiler::Compiler( int argc, char** argv ) :
    m_pEnv( make_shared< sema::Env >() )
{
    llvm::InitLLVM( argc, argv );

    string cmdArgs;
    for( size_t i = 1; i < static_cast< size_t >( argc ); ++i )
    {
        if( i > 1 )
            cmdArgs = cmdArgs + ' ';
        cmdArgs = cmdArgs + argv[i];
    }

    builtins::SetupBuiltins( *m_pEnv );

    builtins::RegisterBuiltinFunc< builtins::Eager< string > () >( *m_pEnv, "Args"_sid,
        [cmdArgs]()
        {
            return cmdArgs;
        } );

    builtins::RegisterBuiltinFunc< void ( string ) >( *m_pEnv, "Print"_sid,
        []( const string& str )
        {
            cout << str << endl;
        } );

    llvm::InitializeAllTargetInfos();
    llvm::InitializeAllTargets();
    llvm::InitializeAllTargetMCs();
    llvm::InitializeAllAsmParsers();
    llvm::InitializeAllAsmPrinters();
}

uint64_t Compiler::execute( istream& source, const ptr< string >& filename )
{
    sema::Context c( m_pEnv, builtins::RootIdentity(), GetValueType< uint64_t >() );

    auto r = make_shared< parse::Resolver >( make_shared< lex::Lexer >( source, filename ), c );
    parse::Parser p( r );

    auto cfgBuilder = make_shared< sema::CFGBuilder >();
    p.setCFGBuilder( cfgBuilder );
    p.setCurrentBB( cfgBuilder->entryBB() );

    p.parseSequence();

    if( !r->eos() )
    {
        cout << "syntax error.\n";
        return 0;
    }

    if( !cfgBuilder->entryBB()->canBeExecuted() )
    {
        cout << "front end can not be executed.\n";
        return 0;
    }

    execute::VM vm;
    auto result = vm.execute( cfgBuilder->entryBB() );
    if( !result )
        return 1;

    return *FromValue< uint64_t >( *result );
}