comptime expandable match statements
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
Kind :: enum {
|
||||
first
|
||||
second
|
||||
third
|
||||
}
|
||||
|
||||
Pair :: struct {
|
||||
left i32
|
||||
right i32
|
||||
}
|
||||
|
||||
Value :: union(enum) {
|
||||
number i32
|
||||
pair Pair
|
||||
empty void
|
||||
}
|
||||
|
||||
enum_score func(kind Kind) i32 {
|
||||
result :: match kind {
|
||||
.first: 1
|
||||
expand |value|: {
|
||||
yield match value {
|
||||
.second: 2
|
||||
.third: 3
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
equal_value func(a, b Value) bool {
|
||||
if (tag!(a) != tag!(b)) return false
|
||||
result :: match a {
|
||||
expand |value, tag|: {
|
||||
yield match tag {
|
||||
.number: value == field!(b, tagname!(tag))
|
||||
.pair: {
|
||||
other :: field!(b, tagname!(tag))
|
||||
yield value.left == other.left and value.right == other.right
|
||||
}
|
||||
.empty: {
|
||||
yield true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
increment func(value @mut Value) void {
|
||||
match value^ {
|
||||
expand |@payload, tag|: match tag {
|
||||
.number: payload^ += 1
|
||||
.pair: payload.left += 1
|
||||
.empty: _ = payload
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main func() i32 {
|
||||
if enum_score(.first) != 1 or enum_score(.second) != 2 or enum_score(.third) != 3 {
|
||||
return 1
|
||||
}
|
||||
|
||||
known :: $tag!(Value{number = 1})
|
||||
known_direct :: tag!(Value{pair = Pair{left = 0, right = 0}})
|
||||
if (known != .number) or (known_direct != .pair) {
|
||||
return 2
|
||||
}
|
||||
|
||||
a Value = .number{41}
|
||||
b Value = .number{41}
|
||||
if !equal_value(a, b) or equal_value(a, .pair{left = 41, right = 0}) {
|
||||
return 3
|
||||
}
|
||||
increment(&a)
|
||||
if a.number != 42 {
|
||||
return 4
|
||||
}
|
||||
|
||||
pair_a Value = .pair{left = 2, right = 3}
|
||||
pair_b Value = .pair{left = 2, right = 3}
|
||||
if !equal_value(pair_a, pair_b) or !equal_value(.empty, .empty) {
|
||||
return 5
|
||||
}
|
||||
increment(&pair_a)
|
||||
if pair_a.pair.left != 3 {
|
||||
return 6
|
||||
}
|
||||
|
||||
empty Value = .empty
|
||||
increment(&empty)
|
||||
return 0
|
||||
}
|
||||
@@ -11,7 +11,7 @@ format func() []u8 {
|
||||
sum func($T type, value T) i32 {
|
||||
total i32 = 0
|
||||
match typeinfo!(T) {
|
||||
.record |record|: inline for record.fields |field| {
|
||||
.record |record|: expand for record.fields |field| {
|
||||
total += i32(field!(value, field.name))
|
||||
}
|
||||
else: compile_error!("sum requires a record")
|
||||
@@ -22,7 +22,7 @@ sum func($T type, value T) i32 {
|
||||
static_control func($T type, value T) i32 {
|
||||
total i32 = 0
|
||||
match typeinfo!(T) {
|
||||
.record |record|: inline for record.fields |field| {
|
||||
.record |record|: expand for record.fields |field| {
|
||||
{
|
||||
if field.index == 1 {
|
||||
continue
|
||||
@@ -50,7 +50,7 @@ row_value func(row Row) i32 {
|
||||
|
||||
static_aggregates func() i32 {
|
||||
total i32 = 0
|
||||
inline for {Row {value = 2}, Row {value = 40}} |row| {
|
||||
expand for {Row {value = 2}, Row {value = 40}} |row| {
|
||||
total += row_value(row)
|
||||
}
|
||||
return total
|
||||
|
||||
Reference in New Issue
Block a user