sentinel pointers and c strings
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user