sentinel pointers and c strings

This commit is contained in:
2026-06-14 19:21:49 +02:00
parent 2d3d0bd266
commit 3b7c3fcbd0
16 changed files with 512 additions and 55 deletions
+93 -5
View File
@@ -488,13 +488,56 @@ is_many_pointer :: proc(value: Type, store: ^Store) -> bool {
return ok && item.kind == .Pointer && item.many
}
array_pointer :: proc(value: Type, store: ^Store) -> (pointer_item, array_item: Node, ok: bool) {
pointer_ok: bool
pointer_item, pointer_ok = node(store, value)
if !pointer_ok || pointer_item.kind != .Pointer || pointer_item.many {
return {}, {}, false
}
array_ok: bool
array_item, array_ok = node(store, pointer_item.child)
if !array_ok || array_item.kind != .Array {
return {}, {}, false
}
return pointer_item, array_item, true
}
container :: proc(value: Type, store: ^Store) -> (Node, bool) {
item, ok := node(store, value)
if !ok {
return {}, false
}
if item.kind == .Array || item.kind == .Slice || (item.kind == .Pointer && item.many) {
return item, true
}
pointer_node, array_node, array_ok := array_pointer(value, store)
if !array_ok {
return {}, false
}
array_node.mutable = pointer_node.mutable && array_node.mutable
return array_node, true
}
is_c_struct :: proc(value: Type, store: ^Store) -> bool {
item, ok := node(store, value)
return ok && item.kind == .Struct && item.c_layout
}
pointer :: proc(store: ^Store, child: Type, mutable, many: bool) -> Type {
return intern(store, Node{kind=.Pointer, child=child, mutable=mutable, many=many})
pointer :: proc(
store: ^Store,
child: Type,
mutable, many: bool,
has_sentinel := false,
sentinel: u64 = 0,
) -> Type {
return intern(store, Node{
kind=.Pointer,
child=child,
mutable=mutable,
many=many,
has_sentinel=has_sentinel,
sentinel=sentinel,
})
}
slice :: proc(store: ^Store, child: Type, mutable: bool, has_sentinel := false, sentinel: u64 = 0) -> Type {
@@ -540,12 +583,57 @@ with_array_count :: proc(store: ^Store, value: Type, count: u64) -> Type {
}
can_weaken_pointer :: proc(from, to: Type, store: ^Store) -> bool {
from_node, from_ok := node(store, from)
to_node, to_ok := node(store, to)
if !from_ok || !to_ok || from_node.kind != .Pointer || to_node.kind != .Pointer ||
from_node.many != to_node.many || (to_node.mutable && !from_node.mutable) {
return false
}
if to_node.has_sentinel &&
(!from_node.has_sentinel || from_node.sentinel != to_node.sentinel) {
return false
}
same_child := from_node.child == to_node.child
c_string := from_node.many && from_node.child == U8 && to_node.child == C_CHAR &&
from_node.has_sentinel && from_node.sentinel == 0 && !to_node.mutable
return same_child || c_string
}
can_weaken_slice :: proc(from, to: Type, store: ^Store) -> bool {
from_node, from_ok := node(store, from)
to_node, to_ok := node(store, to)
return from_ok && to_ok &&
from_node.kind == .Pointer && to_node.kind == .Pointer &&
from_node.child == to_node.child && from_node.many == to_node.many &&
from_node.mutable && !to_node.mutable
from_node.kind == .Slice && to_node.kind == .Slice &&
from_node.child == to_node.child &&
(!to_node.mutable || from_node.mutable) &&
(!to_node.has_sentinel ||
(from_node.has_sentinel && from_node.sentinel == to_node.sentinel))
}
can_decay_array_pointer :: proc(from, to: Type, store: ^Store) -> bool {
from_pointer, array, from_ok := array_pointer(from, store)
to_node, to_ok := node(store, to)
if !from_ok || !to_ok {
return false
}
mutable := from_pointer.mutable && array.mutable
if to_node.mutable && !mutable {
return false
}
if to_node.has_sentinel &&
(!array.has_sentinel || array.sentinel != to_node.sentinel) {
return false
}
if to_node.kind == .Slice {
return array.child == to_node.child
}
if to_node.kind != .Pointer || !to_node.many {
return false
}
same_child := array.child == to_node.child
c_string := array.child == U8 && to_node.child == C_CHAR &&
array.has_sentinel && array.sentinel == 0 && !to_node.mutable
return same_child || c_string
}
is_opaque_struct :: proc(value: Type, store: ^Store) -> bool {