parse const decls

This commit is contained in:
2026-07-25 00:26:47 +02:00
parent c7f527e3c3
commit 90c7195d4b
28 changed files with 1452 additions and 1134 deletions
+42 -42
View File
@@ -1,61 +1,61 @@
Layout :: enum { auto, c }
ArrayInfo :: struct {
child type
len usize
child type
len usize
}
FieldInfo :: struct {
name []u8
type type
index usize
name []u8
type type
index usize
}
RecordInfo :: struct {
name ?[]u8
fields []FieldInfo
is_tuple bool
layout Layout
name ?[]u8
fields []FieldInfo
is_tuple bool
layout Layout
}
EnumInfo :: struct {
fields []FieldInfo
fields []FieldInfo
}
TypeInfo :: union(enum) {
invalid void
void void
noreturn void
anyopaque void
bool void
integer void
float void
array ArrayInfo
pointer void
slice void
range void
optional void
function void
enum EnumInfo
record RecordInfo
union void
fallible void
distinct void
invalid void
void void
noreturn void
anyopaque void
bool void
integer void
float void
array ArrayInfo
pointer void
slice void
range void
optional void
function void
enum EnumInfo
record RecordInfo
union void
fallible void
distinct type
}
EnumFieldStruct proc($E, $Field type, $default ?Field) type {
match typeinfo!(E) {
.enum |info|: {
names [info.fields.len]mut []u8 = undefined
field_types [info.fields.len]mut type = undefined
defaults [info.fields.len]mut ?Field = undefined
expand for info.fields |field, index| {
names[index] = field.name
field_types[index] = Field
defaults[index] = default
}
return struct_type!(.auto, names, field_types, defaults)
}
else: compile_error!("EnumFieldStruct key must be an enum")
}
match typeinfo!(E) {
.enum |info|: {
names [info.fields.len]mut []u8 = undefined
field_types [info.fields.len]mut type = undefined
defaults [info.fields.len]mut ?Field = undefined
expand for info.fields |field, index| {
names[index] = field.name
field_types[index] = Field
defaults[index] = default
}
return struct_type!(.auto, names, field_types, defaults)
}
else: compile_error!("EnumFieldStruct key must be an enum")
}
}
+50 -33
View File
@@ -1,50 +1,67 @@
testing :: import "@std/testing"
TestTokenKind :: enum(u8) {
ident = 3
int = 8
eof = 21
ident = 3
int = 8
eof = 21
}
TestNames :: alias EnumFieldStruct(TestTokenKind, ?[]u8, some!(null))
TestArrayAlias :: alias [3]u16
TestInner :: distinct u16
TestOuter :: distinct TestInner
TestOuterAlias :: alias TestOuter
hide array_info_matches proc($Array, $Child type, $len usize) bool {
match typeinfo!(Array) {
.array |info|: return info.child == Child and info.len == len
else: return false
}
match typeinfo!(Array) {
.array |info|: return info.child == Child and info.len == len
else: return false
}
}
hide distinct_info_matches proc($Distinct, $Backing type) bool {
match typeinfo!(Distinct) {
.distinct |backing|: return backing == Backing
else: return false
}
}
array_reflection_exposes_child_and_logical_length test {
try testing.expect($(array_info_matches([4]i32, i32, 4)))
try testing.expect($(array_info_matches([0]bool, bool, 0)))
try testing.expect($(array_info_matches(TestArrayAlias, u16, 3)))
try testing.expect($(array_info_matches([2]mut i64, i64, 2)))
try testing.expect($(array_info_matches([2;0]u8, u8, 2)))
try testing.expect($(array_info_matches([4]i32, i32, 4)))
try testing.expect($(array_info_matches([0]bool, bool, 0)))
try testing.expect($(array_info_matches(TestArrayAlias, u16, 3)))
try testing.expect($(array_info_matches([2]mut i64, i64, 2)))
try testing.expect($(array_info_matches([2;0]u8, u8, 2)))
}
distinct_reflection_exposes_immediate_backing test {
try testing.expect($(distinct_info_matches(TestInner, u16)))
try testing.expect($(distinct_info_matches(TestOuter, TestInner)))
try testing.expect($(distinct_info_matches(TestOuterAlias, TestInner)))
}
enum_field_struct_defaults test {
names TestNames = {
ident = "identifier",
int = "integer",
}
if field!(names, "ident") |value| {
try testing.expect(value.len == 10)
} else {
try testing.expect(false)
}
if field!(names, "int") |value| {
try testing.expect(value.len == 7)
} else {
try testing.expect(false)
}
if field!(names, "eof") |_| {
try testing.expect(false)
}
names TestNames = {
ident = "identifier",
int = "integer",
}
if field!(names, "ident") |value| {
try testing.expect(value.len == 10)
} else {
try testing.expect(false)
}
if field!(names, "int") |value| {
try testing.expect(value.len == 7)
} else {
try testing.expect(false)
}
if field!(names, "eof") |_| {
try testing.expect(false)
}
empty TestNames = {}
if field!(empty, "ident") |_| {
try testing.expect(false)
}
empty TestNames = {}
if field!(empty, "ident") |_| {
try testing.expect(false)
}
}