140 lines
2.6 KiB
Odin
140 lines
2.6 KiB
Odin
package hir
|
|
|
|
import "../source"
|
|
import "../symbol"
|
|
import "../types"
|
|
import "core:mem"
|
|
|
|
INVALID_ID :: -1
|
|
|
|
Calling_Convention :: enum {
|
|
Brolang,
|
|
C,
|
|
}
|
|
|
|
Implementation :: enum {
|
|
Definition,
|
|
Declaration,
|
|
}
|
|
|
|
Linkage :: enum {
|
|
Internal,
|
|
External,
|
|
}
|
|
|
|
Expr_Kind :: enum {
|
|
Invalid,
|
|
Integer,
|
|
Local,
|
|
Global,
|
|
Widen,
|
|
Add,
|
|
Call,
|
|
}
|
|
|
|
Expr :: struct {
|
|
kind: Expr_Kind,
|
|
span: source.Span,
|
|
type: types.Type,
|
|
integer: i64,
|
|
target: int,
|
|
left: int,
|
|
right: int,
|
|
args: []int,
|
|
diagnostic: int,
|
|
}
|
|
|
|
Local :: struct {
|
|
name: symbol.Id,
|
|
type: types.Type,
|
|
mutable: bool,
|
|
parameter: bool,
|
|
}
|
|
|
|
Stmt_Kind :: enum {
|
|
Declaration,
|
|
Assignment,
|
|
Return,
|
|
Expression,
|
|
Sink,
|
|
Trap,
|
|
}
|
|
|
|
Stmt :: struct {
|
|
kind: Stmt_Kind,
|
|
span: source.Span,
|
|
local: int,
|
|
expr: int,
|
|
diagnostic: int,
|
|
}
|
|
|
|
Function :: struct {
|
|
name: symbol.Id,
|
|
link_name: string,
|
|
calling_convention: Calling_Convention,
|
|
implementation: Implementation,
|
|
linkage: Linkage,
|
|
is_main: bool,
|
|
params: []int,
|
|
result: types.Type,
|
|
locals: []Local,
|
|
body: []int,
|
|
direct_global_reads: [dynamic]int,
|
|
calls: []int,
|
|
problematic: bool,
|
|
diagnostic: int,
|
|
}
|
|
|
|
Global :: struct {
|
|
name: symbol.Id,
|
|
type: types.Type,
|
|
expr: int,
|
|
static_value: i64,
|
|
is_static: bool,
|
|
dependencies: [dynamic]int,
|
|
calls: []int,
|
|
direct_problem: bool,
|
|
problematic: bool,
|
|
diagnostic: int,
|
|
}
|
|
|
|
Module :: struct {
|
|
exprs: [dynamic]Expr,
|
|
statements: [dynamic]Stmt,
|
|
functions: [dynamic]Function,
|
|
globals: [dynamic]Global,
|
|
allocator: mem.Allocator,
|
|
}
|
|
|
|
init_module :: proc(allocator := context.allocator) -> Module {
|
|
module: Module
|
|
module.allocator = allocator
|
|
module.exprs.allocator = allocator
|
|
module.statements.allocator = allocator
|
|
module.functions.allocator = allocator
|
|
module.globals.allocator = allocator
|
|
return module
|
|
}
|
|
|
|
destroy_module :: proc(module: ^Module) {
|
|
for expr in module.exprs {
|
|
delete(expr.args, module.allocator)
|
|
}
|
|
for function in module.functions {
|
|
delete(function.link_name, module.allocator)
|
|
delete(function.params, module.allocator)
|
|
delete(function.locals, module.allocator)
|
|
delete(function.body, module.allocator)
|
|
delete(function.direct_global_reads)
|
|
delete(function.calls, module.allocator)
|
|
}
|
|
for global in module.globals {
|
|
delete(global.dependencies)
|
|
delete(global.calls, module.allocator)
|
|
}
|
|
delete(module.exprs)
|
|
delete(module.statements)
|
|
delete(module.functions)
|
|
delete(module.globals)
|
|
}
|