Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1d719c6a42 | |||
| 77696e19c9 | |||
| 979a8e5f07 |
+1
-1
@@ -3,7 +3,7 @@ import "@std/io"
|
|||||||
|
|
||||||
print func($format []u8, $Args type, args Args) void {
|
print func($format []u8, $Args type, args Args) void {
|
||||||
writer io.Writer :: io.Writer{
|
writer io.Writer :: io.Writer{
|
||||||
context = none,
|
context = null,
|
||||||
handle = io.Handle{ file_desc = c_int(io.Stream.stderr) },
|
handle = io.Handle{ file_desc = c_int(io.Stream.stderr) },
|
||||||
write = write,
|
write = write,
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -12,7 +12,7 @@ EnumMap func($E, $V type) type {
|
|||||||
|
|
||||||
init func(
|
init func(
|
||||||
$E, $V type,
|
$E, $V type,
|
||||||
values meta.EnumFieldStruct(E, ?V, some!(none)),
|
values meta.EnumFieldStruct(E, ?V, some!(null)),
|
||||||
) EnumMap(E, V) {
|
) EnumMap(E, V) {
|
||||||
map EnumMap(E, V) = undefined
|
map EnumMap(E, V) = undefined
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ get func($E, $V type, map @EnumMap(E, V), key E) ?V {
|
|||||||
.enum |info|: expand for info.fields |field, i| {
|
.enum |info|: expand for info.fields |field, i| {
|
||||||
if key == field!(E, field.name) {
|
if key == field!(E, field.name) {
|
||||||
if (map.present[i]) return map.values[i]
|
if (map.present[i]) return map.values[i]
|
||||||
return none
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else: compile_error!("EnumMap key must be an enum")
|
else: compile_error!("EnumMap key must be an enum")
|
||||||
|
|||||||
@@ -21,5 +21,5 @@ handles_sparse_enum_get test {
|
|||||||
eof :: get(&names, TestEnum.eof)
|
eof :: get(&names, TestEnum.eof)
|
||||||
|
|
||||||
try testing.expect_type(?[]u8, eof)
|
try testing.expect_type(?[]u8, eof)
|
||||||
try testing.expect_equal(none, eof)
|
try testing.expect_equal(null, eof)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,14 +56,14 @@ get func(
|
|||||||
map @HashMap(K, V, hash_key, keys_eql),
|
map @HashMap(K, V, hash_key, keys_eql),
|
||||||
key K,
|
key K,
|
||||||
) ?V {
|
) ?V {
|
||||||
if (map.count == 0) return none
|
if (map.count == 0) return null
|
||||||
|
|
||||||
hash :: normalize(hash_key(key))
|
hash :: normalize(hash_key(key))
|
||||||
idx usize = hash & (map.entries.len - 1)
|
idx usize = hash & (map.entries.len - 1)
|
||||||
|
|
||||||
while true {
|
while true {
|
||||||
entry :: map.entries[idx]
|
entry :: map.entries[idx]
|
||||||
if (entry.hash == 0) return none
|
if (entry.hash == 0) return null
|
||||||
|
|
||||||
if (entry.hash == hash and keys_eql(entry.key, key)) {
|
if (entry.hash == hash and keys_eql(entry.key, key)) {
|
||||||
return entry.value
|
return entry.value
|
||||||
|
|||||||
+1
-1
@@ -138,7 +138,7 @@ hide system_vtable IoVTable :: IoVTable {
|
|||||||
|
|
||||||
hide system func() Io {
|
hide system func() Io {
|
||||||
return Io {
|
return Io {
|
||||||
context = none,
|
context = null,
|
||||||
vtable = &system_vtable,
|
vtable = &system_vtable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-49
@@ -28,29 +28,20 @@ raw_free func(allocator Allocator, memory ?*mut u8, size usize, alignment usize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
eql func($T type, left, right []T) bool {
|
eql func($T type, left, right []T) bool {
|
||||||
if left.len != right.len {
|
if (left.len != right.len) return false
|
||||||
return false
|
for (0..left.len) |i| if (left[i] != right[i]) {
|
||||||
}
|
return false
|
||||||
|
|
||||||
i usize = 0
|
|
||||||
while i < left.len : i += 1 {
|
|
||||||
if left[i] != right[i] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
# allocate memory for a slice of type `T` with `count` elements.
|
# allocate memory for a slice of type `T` with `count` elements.
|
||||||
alloc func($T type, allocator Allocator, count usize) []mut T ! AllocError {
|
alloc func($T type, allocator Allocator, count usize) []mut T ! AllocError {
|
||||||
if count == 0 {
|
if (count == 0) return empty_slice(T, 0)
|
||||||
return empty_slice(T, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
element_size usize :: sizeof!(T)
|
element_size usize :: sizeof!(T)
|
||||||
if element_size == 0 {
|
if (element_size == 0) return empty_slice(T, count)
|
||||||
return empty_slice(T, count)
|
|
||||||
}
|
|
||||||
if count > divtrunc!(maxval!(usize), element_size) {
|
if count > divtrunc!(maxval!(usize), element_size) {
|
||||||
return .out_of_memory
|
return .out_of_memory
|
||||||
}
|
}
|
||||||
@@ -84,7 +75,7 @@ realloc func($T type, allocator Allocator, memory []mut T, new_count usize) []mu
|
|||||||
return .out_of_memory
|
return .out_of_memory
|
||||||
}
|
}
|
||||||
|
|
||||||
old_memory ?*mut u8 = none
|
old_memory ?*mut u8 = null
|
||||||
old_size usize = 0
|
old_size usize = 0
|
||||||
if memory.len != 0 {
|
if memory.len != 0 {
|
||||||
old_memory = ptrcast!(u8, memory.ptr)
|
old_memory = ptrcast!(u8, memory.ptr)
|
||||||
@@ -107,10 +98,14 @@ realloc func($T type, allocator Allocator, memory []mut T, new_count usize) []mu
|
|||||||
|
|
||||||
# free memory allocated for a slice of type `T`.
|
# free memory allocated for a slice of type `T`.
|
||||||
# note: memory must be freed with the same allocator that was used to allocate it.
|
# note: memory must be freed with the same allocator that was used to allocate it.
|
||||||
free func($T type, allocator Allocator, memory []mut T) void {
|
free func($T type, allocator Allocator, memory []T) void {
|
||||||
if memory.len != 0 and sizeof!(T) != 0 {
|
if (memory.len == 0 or sizeof!(T) == 0) return
|
||||||
raw_free(allocator, ptrcast!(u8, memory.ptr), memory.len * sizeof!(T), alignof!(T))
|
raw_free(allocator, ptrcast!(
|
||||||
}
|
u8,
|
||||||
|
constcast!(memory).ptr),
|
||||||
|
memory.len * sizeof!(T),
|
||||||
|
alignof!(T),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
# get an empty slice of type `T` with `count` elements.
|
# get an empty slice of type `T` with `count` elements.
|
||||||
@@ -129,48 +124,36 @@ hide empty_storage [1]mut u64 = [0]
|
|||||||
hide malloc_alignment usize :: 16 # ponytail: aarch64-macos libc malloc alignment assumption.
|
hide malloc_alignment usize :: 16 # ponytail: aarch64-macos libc malloc alignment assumption.
|
||||||
|
|
||||||
hide power_of_two func(value usize) bool {
|
hide power_of_two func(value usize) bool {
|
||||||
if value == 0 {
|
if (value == 0) return false
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
current usize = value
|
current usize = value
|
||||||
while current > 1 {
|
while current > 1 {
|
||||||
half usize = divtrunc!(current, 2)
|
half usize = divtrunc!(current, 2)
|
||||||
if half * 2 != current {
|
if (half * 2 != current) return false
|
||||||
return false
|
|
||||||
}
|
|
||||||
current = half
|
current = half
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
hide c_alloc func(_ ?@mut anyopaque, size usize, alignment usize) ?*mut u8 {
|
hide c_alloc func(_ ?@mut anyopaque, size usize, alignment usize) ?*mut u8 {
|
||||||
if power_of_two(alignment) == false {
|
if (power_of_two(alignment) == false) return null
|
||||||
return none
|
|
||||||
}
|
|
||||||
|
|
||||||
if alignment <= malloc_alignment {
|
if alignment <= malloc_alignment {
|
||||||
return ptrcast!(u8, c.malloc(c_ulong(size)))
|
return ptrcast!(u8, c.malloc(c_ulong(size)))
|
||||||
}
|
}
|
||||||
|
|
||||||
memory [1]mut ?*mut anyopaque = [none]
|
memory [1]mut ?*mut anyopaque = [null]
|
||||||
status c_int = c.posix_memalign((&memory).ptr, c_ulong(alignment), c_ulong(size))
|
status c_int = c.posix_memalign((&memory).ptr, c_ulong(alignment), c_ulong(size))
|
||||||
if status != 0 {
|
if (status != 0) return null
|
||||||
return none
|
|
||||||
}
|
|
||||||
|
|
||||||
return ptrcast!(u8, memory[0])
|
return ptrcast!(u8, memory[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
hide c_realloc func(_ ?@mut anyopaque, memory ?*mut u8, old_size usize, new_size usize, alignment usize) ?*mut u8 {
|
hide c_realloc func(_ ?@mut anyopaque, memory ?*mut u8, old_size usize, new_size usize, alignment usize) ?*mut u8 {
|
||||||
if power_of_two(alignment) == false {
|
if (power_of_two(alignment) == false) return null
|
||||||
return none
|
|
||||||
}
|
|
||||||
|
|
||||||
if new_size == 0 {
|
if new_size == 0 {
|
||||||
c.free(memory)
|
c.free(memory)
|
||||||
return none
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
if memory |old_memory| {
|
if memory |old_memory| {
|
||||||
@@ -178,22 +161,17 @@ hide c_realloc func(_ ?@mut anyopaque, memory ?*mut u8, old_size usize, new_size
|
|||||||
return ptrcast!(u8, c.realloc(old_memory, c_ulong(new_size)))
|
return ptrcast!(u8, c.realloc(old_memory, c_ulong(new_size)))
|
||||||
}
|
}
|
||||||
|
|
||||||
new_memory ?*mut u8 = c_alloc(none, new_size, alignment)
|
new_memory ?*mut u8 = c_alloc(null, new_size, alignment)
|
||||||
if new_memory |new_bytes| {
|
if new_memory |new_bytes| {
|
||||||
copy_size usize = old_size
|
copy_size usize = old_size
|
||||||
if new_size < copy_size {
|
if (new_size < copy_size) copy_size = new_size
|
||||||
copy_size = new_size
|
memcopy!(new_bytes[..copy_size], old_memory[..copy_size])
|
||||||
}
|
|
||||||
i usize = 0
|
|
||||||
while i < copy_size : i += 1 {
|
|
||||||
new_bytes[i] = old_memory[i]
|
|
||||||
}
|
|
||||||
c.free(old_memory)
|
c.free(old_memory)
|
||||||
}
|
}
|
||||||
return new_memory
|
return new_memory
|
||||||
}
|
}
|
||||||
|
|
||||||
return c_alloc(none, new_size, alignment)
|
return c_alloc(null, new_size, alignment)
|
||||||
}
|
}
|
||||||
|
|
||||||
hide c_free func(_ ?@mut anyopaque, memory ?*mut u8, _ usize, _ usize) void {
|
hide c_free func(_ ?@mut anyopaque, memory ?*mut u8, _ usize, _ usize) void {
|
||||||
@@ -207,6 +185,6 @@ hide c_vtable AllocatorVTable :: AllocatorVTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c_allocator Allocator :: Allocator {
|
c_allocator Allocator :: Allocator {
|
||||||
context = none,
|
context = null,
|
||||||
vtable = &c_vtable,
|
vtable = &c_vtable,
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -23,6 +23,7 @@ EnumInfo :: struct {
|
|||||||
TypeInfo :: union(enum) {
|
TypeInfo :: union(enum) {
|
||||||
invalid void
|
invalid void
|
||||||
void void
|
void void
|
||||||
|
noreturn void
|
||||||
anyopaque void
|
anyopaque void
|
||||||
bool void
|
bool void
|
||||||
integer void
|
integer void
|
||||||
@@ -43,9 +44,9 @@ TypeInfo :: union(enum) {
|
|||||||
EnumFieldStruct func($E, $Field type, $default ?Field) type {
|
EnumFieldStruct func($E, $Field type, $default ?Field) type {
|
||||||
match typeinfo!(E) {
|
match typeinfo!(E) {
|
||||||
.enum |info|: {
|
.enum |info|: {
|
||||||
names [field!(typeinfo!(E), "enum").fields.len]mut []u8 = undefined
|
names [info.fields.len]mut []u8 = undefined
|
||||||
field_types [field!(typeinfo!(E), "enum").fields.len]mut type = undefined
|
field_types [info.fields.len]mut type = undefined
|
||||||
defaults [field!(typeinfo!(E), "enum").fields.len]mut ?Field = undefined
|
defaults [info.fields.len]mut ?Field = undefined
|
||||||
expand for info.fields |field, index| {
|
expand for info.fields |field, index| {
|
||||||
names[index] = field.name
|
names[index] = field.name
|
||||||
field_types[index] = Field
|
field_types[index] = Field
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ TestTokenKind :: enum(u8) {
|
|||||||
eof = 21
|
eof = 21
|
||||||
}
|
}
|
||||||
|
|
||||||
TestNames :: alias EnumFieldStruct(TestTokenKind, ?[]u8, some!(none))
|
TestNames :: alias EnumFieldStruct(TestTokenKind, ?[]u8, some!(null))
|
||||||
|
|
||||||
enum_field_struct_defaults test {
|
enum_field_struct_defaults test {
|
||||||
names TestNames = {
|
names TestNames = {
|
||||||
|
|||||||
@@ -26,11 +26,11 @@ expect_equal func($T type, expected, actual T, location SourceLocation) void ! E
|
|||||||
try expect_equal(expected_value, actual_value, location)
|
try expect_equal(expected_value, actual_value, location)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
debug.print("{s}:{d}:{d}: expected an optional value, found none\n", {location.file, location.line, location.column})
|
debug.print("{s}:{d}:{d}: expected an optional value, found null\n", {location.file, location.line, location.column})
|
||||||
return .expectation_failed
|
return .expectation_failed
|
||||||
}
|
}
|
||||||
if actual |_| {
|
if actual |_| {
|
||||||
debug.print("{s}:{d}:{d}: expected none, found an optional value\n", {location.file, location.line, location.column})
|
debug.print("{s}:{d}:{d}: expected null, found an optional value\n", {location.file, location.line, location.column})
|
||||||
return .expectation_failed
|
return .expectation_failed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user