c interop type foundation

This commit is contained in:
2026-06-12 18:10:52 +02:00
parent d2f0d16795
commit 4e860b033e
27 changed files with 3523 additions and 380 deletions
+88
View File
@@ -5,6 +5,7 @@ import "../lexer"
import "../parser"
import "../source"
import "../symbol"
import "../types"
import "core:mem"
import "core:os"
import "core:path/filepath"
@@ -253,6 +254,92 @@ validate_imports :: proc(state: ^State) {
}
}
find_type_import :: proc(module: ^ast.Module, file: ast.File_Id, alias: symbol.Id) -> ast.Import_Id {
for import_item, index in module.imports {
if import_item.file == file && import_item.alias == alias {
return ast.import_id(index)
}
}
return ast.INVALID_IMPORT
}
canonical_type :: proc(
module: ^ast.Module,
value: types.Type,
mapping: []types.Type,
visiting: []bool,
) -> types.Type {
if value < types.DYNAMIC_START {
return value
}
index := int(value-types.DYNAMIC_START)
if index < 0 || index >= len(mapping) {
return value
}
if types.is_valid(mapping[index]) {
return mapping[index]
}
if visiting[index] {
return value
}
visiting[index] = true
defer visiting[index] = false
item := module.type_store.nodes[index]
if item.kind == .Named {
if item.qualifier != 0 {
import_id := find_type_import(module, ast.File_Id(item.file), symbol.Id(item.qualifier))
if import_id != ast.INVALID_IMPORT {
module.imports[import_id].used = true
import_item := module.imports[import_id]
resolved := types.find_named(&module.type_store, u32(import_item.target), item.name)
if types.is_valid(resolved) {
mapping[index] = resolved
return resolved
}
}
}
mapping[index] = value
return value
}
if item.kind == .Struct {
mapping[index] = value
fields := types.fields_for(&module.type_store, value)
for &field in fields {
field.type = canonical_type(module, field.type, mapping, visiting)
}
return value
}
if types.is_valid(item.child) {
item.child = canonical_type(module, item.child, mapping, visiting)
}
resolved := types.intern(&module.type_store, item)
mapping[index] = resolved
return resolved
}
canonicalize_types :: proc(module: ^ast.Module, allocator: mem.Allocator) {
original_count := len(module.type_store.nodes)
mapping := make([]types.Type, original_count, allocator)
visiting := make([]bool, original_count, allocator)
defer delete(mapping, allocator)
defer delete(visiting, allocator)
for &function in module.functions {
for &param in function.params {
param.type = canonical_type(module, param.type, mapping, visiting)
}
function.result = canonical_type(module, function.result, mapping, visiting)
}
for &global in module.globals {
global.type = canonical_type(module, global.type, mapping, visiting)
}
for &statement in module.statements {
statement.type = canonical_type(module, statement.type, mapping, visiting)
}
for index := 0; index < original_count; index += 1 {
_ = canonical_type(module, types.DYNAMIC_START+types.Type(index), mapping, visiting)
}
}
load :: proc(
root_path: string,
sources: ^source.Store,
@@ -275,5 +362,6 @@ load :: proc(
state.root_failed = true
}
validate_imports(&state)
canonicalize_types(&module, allocator)
return module, !state.root_failed
}