package compiler import "./backend" import "./checker" import "./llvm" import "./linker" import "./loader" import "./lower" import "./opt" import "./source" import "./symbol" import "./target" 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, selected := target.DEFAULT, ) -> 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 { source.print_all(&diagnostics) 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, selected, 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, selected) { return 2 } if len(diagnostics.items) > 0 { return 1 } return 0 }