Goose  Artifact [b32b670cd2]

Artifact b32b670cd214c5e3ef2e304b42b5593e310360afb7961ca6caf0976fbca9265e:

  • File lib/compile.g0 — part of check-in [45f663093d] at 2021-09-12 13:42:15 on branch trunk — Adopted a new convention for source extensions: .g0 for prelude code (where most language features won't be available), .g1 for user code (user: achavasse size: 2367)
  • File lib/frontend.g — part of check-in [568c366a36] at 2020-06-26 23:34:09 on branch trunk — Cleanup:
    • Removed the poorly thought out "domain" system that was intended to allow for different implementations of functions for runtime and for compilation time, which was adding an absurd amount of crap everywhere and should be unnecessary with the current planned approach for implementing data structures.
    • The using statement doesn't do lazy parsing anymore. Lazy parsing is better left to specific constructs that require them (such as function bodies and later on class/structs). This removes the only case of significant newline character in the language.
    (user: achavasse size: 2367)

// The front-end.

// Its job, as of now, is to take the source file name from the command line,
// and compile it into an executable file of the same name, with the .out suffix.
//
// There is zero goal of portability yet, all of this is linux specific.
//
// It will become more sophisticated later on as library facilities become available
// and allow to implement more intelligence here.

// Create the module
var module = CGModuleCreate( SourceToCompile )

// Setup the target.
if !CGModuleSetupTarget( module )
{
    Print( "Failed to setup llvm target.\n" )
    return 1
}

// Define the exit external function.
using exit = ExternalFunction( void( uint( 32 ) returnCode ), "_exit" )

using main = #CompileFileToFunction( SourceToCompile, uint( 32 ), 0, () )

// The entry point of the binary.
// We have to use "using" and an anonymous function, because otherwise
// it would create an overloadset and CGGenerateFunction wouldn't know
// how to deal with that.
// This is basically the "crt0". Dunno yet if it's a good idea to build it myself
// or just to link to an existing crt0.o. This has the advantage of flexibility
// to add features later on, but may require more compile time conditional magic
// to handle various platforms.
// Right now it has the advantage of avoiding yet another external dependency.
using entryPoint = void()
{
    exit( main() )
}

if !CGGenerateFunction( module, entryPoint, "_start" )
{
    Print( "Frontend: codegen failed.\n" )
    return 1
}

// Run the llvm optimization passes
CGModuleOptimize( module )

// Output the llvm ir and the asm for inspection.
CGModuleEmitLLVMIr( module, strcat( SourceToCompile, ".ll" ) )

if !CGModuleEmitAsm( module, strcat( SourceToCompile, ".s" ) )
{
    Print( strcat( "Failed to write ", strcat( SourceToCompile, ".s\n" ) ) )
    return 1
}

// Output the object file.
if !CGModuleEmitObj( module, strcat( SourceToCompile, ".o" ) )
{
    Print( strcat( "Failed to write ", strcat( SourceToCompile, ".o\n" ) ) )
    return 1
}

// Link it and produce an executable file.
var linkerArgs = (
    strcat( SourceToCompile, ".o" ),
    "-o", strcat( SourceToCompile, ".out" ),
    "-L/lib/x86_64-linux-gnu", "-lc",
    "--dynamic-linker=/lib64/ld-linux-x86-64.so.2"
)

if !CGLinkerELF( linkerArgs )
    return 1

Print( strcat( "Built executable ", strcat( SourceToCompile, ".out\n" ) ) )