87 lines
2.4 KiB
Odin
87 lines
2.4 KiB
Odin
package compiler
|
|
|
|
import "./backend"
|
|
import "./checker"
|
|
import "./llvm"
|
|
import "./loader"
|
|
import "./lower"
|
|
import "./opt"
|
|
import "./source"
|
|
import "./symbol"
|
|
import "core:fmt"
|
|
import vmem "core:mem/virtual"
|
|
import "core:os"
|
|
import "core:os/os2"
|
|
|
|
compile_package :: proc(input_path, output_path: string) -> int {
|
|
sources := source.init_store()
|
|
defer source.destroy_store(&sources)
|
|
diagnostics := source.init_store_diagnostics(&sources)
|
|
defer source.destroy_diagnostics(&diagnostics)
|
|
symbols := symbol.init_table()
|
|
defer symbol.destroy_table(&symbols)
|
|
|
|
lexer_arena: vmem.Arena
|
|
if err := vmem.arena_init_growing(&lexer_arena); err != nil {
|
|
fmt.eprintln("failed to initialize lexer arena:", err)
|
|
return 2
|
|
}
|
|
defer vmem.arena_destroy(&lexer_arena)
|
|
parser_arena: vmem.Arena
|
|
if err := vmem.arena_init_growing(&parser_arena); err != nil {
|
|
fmt.eprintln("failed to initialize parser arena:", err)
|
|
return 2
|
|
}
|
|
defer vmem.arena_destroy(&parser_arena)
|
|
checker_arena: vmem.Arena
|
|
if err := vmem.arena_init_growing(&checker_arena); err != nil {
|
|
fmt.eprintln("failed to initialize checker arena:", err)
|
|
return 2
|
|
}
|
|
defer vmem.arena_destroy(&checker_arena)
|
|
lower_arena: vmem.Arena
|
|
if err := vmem.arena_init_growing(&lower_arena); err != nil {
|
|
fmt.eprintln("failed to initialize lowering arena:", err)
|
|
return 2
|
|
}
|
|
defer vmem.arena_destroy(&lower_arena)
|
|
|
|
ast_module, loaded := loader.load(
|
|
input_path,
|
|
&sources,
|
|
&diagnostics,
|
|
&symbols,
|
|
vmem.arena_allocator(&lexer_arena),
|
|
vmem.arena_allocator(&parser_arena),
|
|
)
|
|
if !loaded {
|
|
fmt.eprintln("failed to load root package directory:", input_path)
|
|
return 2
|
|
}
|
|
vmem.arena_free_all(&lexer_arena)
|
|
hir_module := checker.check(&ast_module, &diagnostics, &symbols, vmem.arena_allocator(&checker_arena))
|
|
vmem.arena_free_all(&parser_arena)
|
|
ir_module := lower.lower(&hir_module, vmem.arena_allocator(&lower_arena))
|
|
vmem.arena_free_all(&checker_arena)
|
|
opt.run(&ir_module)
|
|
|
|
llvm_text := llvm.emit(&ir_module, &diagnostics, &symbols)
|
|
defer delete(llvm_text)
|
|
vmem.arena_free_all(&lower_arena)
|
|
llvm_path := fmt.tprintf("%s.brolang-%d.ll", output_path, os2.get_pid())
|
|
defer _ = os.remove(llvm_path)
|
|
if err := os.write_entire_file_or_err(llvm_path, transmute([]byte)llvm_text); err != nil {
|
|
fmt.eprintln("failed to write temporary LLVM IR:", err)
|
|
return 2
|
|
}
|
|
|
|
source.print_all(&diagnostics)
|
|
if !backend.compile(llvm_path, output_path) {
|
|
return 2
|
|
}
|
|
if len(diagnostics.items) > 0 {
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|