Files
brolang/compiler/compiler.odin
T
2026-06-12 18:07:21 +02:00

88 lines
2.5 KiB
Odin

package compiler
import "./backend"
import "./checker"
import "./llvm"
import "./linker"
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, link_arguments: []linker.Argument = nil) -> 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, link_arguments) {
return 2
}
if len(diagnostics.items) > 0 {
return 1
}
return 0
}