88 lines
1.8 KiB
V
88 lines
1.8 KiB
V
module builtin
|
|
|
|
import strings
|
|
|
|
const autostr_type_stack_max_depth = 64
|
|
|
|
__global g_autostr_type_stack = [autostr_type_stack_max_depth]int{}
|
|
__global g_autostr_type_stack_len = 0
|
|
|
|
@[markused]
|
|
fn autostr_type_in_stack(typ int) bool {
|
|
for i := 0; i < g_autostr_type_stack_len; i++ {
|
|
if g_autostr_type_stack[i] == typ {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
@[markused]
|
|
fn autostr_type_push(typ int) {
|
|
if g_autostr_type_stack_len >= autostr_type_stack_max_depth {
|
|
return
|
|
}
|
|
g_autostr_type_stack[g_autostr_type_stack_len] = typ
|
|
g_autostr_type_stack_len++
|
|
}
|
|
|
|
@[markused]
|
|
fn autostr_type_pop() {
|
|
if g_autostr_type_stack_len > 0 {
|
|
g_autostr_type_stack_len--
|
|
}
|
|
}
|
|
|
|
// Address-based circular reference detection.
|
|
// Tracks visited struct addresses to detect actual circular references
|
|
// (same instance reached again) without false positives from same-type
|
|
// different instances.
|
|
|
|
__global g_autostr_addr_stack = [autostr_type_stack_max_depth]voidptr{}
|
|
__global g_autostr_addr_stack_len = 0
|
|
|
|
@[markused]
|
|
fn autostr_addr_in_stack(addr voidptr) bool {
|
|
for i := 0; i < g_autostr_addr_stack_len; i++ {
|
|
if g_autostr_addr_stack[i] == addr {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
@[markused]
|
|
fn autostr_addr_push(addr voidptr) {
|
|
if g_autostr_addr_stack_len >= autostr_type_stack_max_depth {
|
|
return
|
|
}
|
|
g_autostr_addr_stack[g_autostr_addr_stack_len] = addr
|
|
g_autostr_addr_stack_len++
|
|
}
|
|
|
|
@[markused]
|
|
fn autostr_addr_pop() {
|
|
if g_autostr_addr_stack_len > 0 {
|
|
g_autostr_addr_stack_len--
|
|
}
|
|
}
|
|
|
|
@[markused]
|
|
fn autostr_array_circular(len int) string {
|
|
if len <= 0 {
|
|
return '[]'
|
|
}
|
|
mut sb := strings.new_builder(2 + len * 12)
|
|
sb.write_string('[')
|
|
for i in 0 .. len {
|
|
if i > 0 {
|
|
sb.write_string(', ')
|
|
}
|
|
sb.write_string('<circular>')
|
|
}
|
|
sb.write_string(']')
|
|
res := sb.str()
|
|
unsafe { sb.free() }
|
|
return res
|
|
}
|