initial draft
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
package compiler
|
||||
|
||||
import "./backend"
|
||||
import "./checker"
|
||||
import "./lexer"
|
||||
import "./llvm"
|
||||
import "./lower"
|
||||
import "./opt"
|
||||
import "./parser"
|
||||
import "./source"
|
||||
import "core:fmt"
|
||||
import vmem "core:mem/virtual"
|
||||
import "core:os"
|
||||
import "core:os/os2"
|
||||
|
||||
compile_file :: proc(input_path, output_path: string) -> int {
|
||||
source_bytes, ok := os.read_entire_file(input_path)
|
||||
if !ok {
|
||||
fmt.eprintln("failed to read input:", input_path)
|
||||
return 2
|
||||
}
|
||||
defer delete(source_bytes)
|
||||
|
||||
source_file := source.Source{path=input_path, text=string(source_bytes)}
|
||||
diagnostics := source.init_diagnostics(&source_file)
|
||||
defer source.destroy_diagnostics(&diagnostics)
|
||||
|
||||
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)
|
||||
|
||||
tokens := lexer.lex(&source_file, &diagnostics, vmem.arena_allocator(&lexer_arena))
|
||||
ast_module := parser.parse(&tokens, &diagnostics, vmem.arena_allocator(&parser_arena))
|
||||
vmem.arena_free_all(&lexer_arena)
|
||||
hir_module := checker.check(&ast_module, &diagnostics, 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)
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user