Files
brolang/examples/programs/comptime_v1/main.bro
T

321 lines
6.0 KiB
Plaintext

State :: enum {
idle
ready
failed
}
Point :: struct {
x i32
y i32
}
Callback_Config :: struct {
call func(value i32) i32
}
Callback_Choice :: union(enum) {
call func(value i32) i32
empty void
}
Box :: union(enum) {
point Point
empty void
}
Error :: enum {
bad
}
make_point func() Point {
return Point { x = 3, y = 4 }
}
sum_loop func(limit i32) i32 {
total i32 = 0
i i32 = 0
while i < limit {
i += 1
if i == 2 {
continue
}
total += i
}
return total
}
sum_for func() i32 {
total i32 = 0
values [_]i32 = [1, 2, 3]
for values |value, index| {
total += value + index
}
return total
}
defer_value func() i32 {
value i32 = 1
{
defer value += 10
value += 1
}
return value
}
describe func(box Box) i32 {
return match box {
.point |p|: p.x + p.y
.empty: 0
}
}
maybe func(flag bool) ?i32 {
if flag {
return 9
}
return null
}
may_fail func(flag bool) i32 ! Error {
if flag {
return .bad
}
return 7
}
increment func(value i32) i32 {
return value + 1
}
double func(value i32) i32 {
return value * 2
}
decrement_c c_func(value i32) i32 {
return value - 1
}
apply_comptime func($callback func(value i32) i32, value i32) i32 {
return callback(value)
}
apply_comptime_c func($callback c_func(value i32) i32, value i32) i32 {
return callback(value)
}
apply_comptime_config func($config Callback_Config, value i32) i32 {
return config.call(value)
}
apply_comptime_array func($callbacks [2]func(value i32) i32, value i32) i32 {
return callbacks[0](value) + callbacks[1](value)
}
apply_comptime_optional func($callback ?func(value i32) i32, value i32) i32 {
return callback?(value)
}
apply_comptime_choice func($choice Callback_Choice, value i32) i32 {
return match choice {
.call |callback|: callback(value)
.empty: value
}
}
call_native func(callback @func(value i32) i32, value i32) i32 {
return callback(value)
}
materialize_callback func($callback func(value i32) i32, value i32) i32 {
return call_native(callback, value)
}
call_fallible func(callback @func(flag bool) i32 ! Error, flag bool) i32 ! Error {
return try callback(flag)
}
use_try func() i32 ! Error {
value :: try may_fail(false)
return value + 1
}
ct_errdefer func(fail bool) i32 ! Error {
trace i32 = 0
defer trace = trace * 10 + 1
errdefer |err| {
if (err == .bad) trace = trace * 10 + 2
}
defer trace = trace * 10 + 3
if (fail) return .bad
return 7
}
ct_try_errdefer func() i32 ! Error {
trace i32 = 0
defer trace = trace * 10 + 4
errdefer |err| {
if (err == .bad) trace = trace * 10 + 5
}
return try may_fail(true)
}
ct_errdefer_check func() i32 {
ok i32 :: ct_errdefer(false) catch 0
if (ok != 7) return 1
explicit_error i32 :: ct_errdefer(true) catch 9
if (explicit_error != 9) return 2
try_error i32 :: ct_try_errdefer() catch 9
if (try_error != 9) return 3
return 42
}
recover func() i32 {
return may_fail(true) catch |e| match e {
.bad: 5
}
}
bump_ptr func(value @mut i32) void {
value^ += 1
}
alias_add func(left @mut i32, right @mut i32) void {
left^ += 2
right^ += 3
}
storage_mutation func() i32 {
values [3]mut i32 = [1, 2, 3]
values[0] += 1
bump_ptr(&values[1])
view []mut i32 = values[..]
for view |@item| {
item^ += 1
}
pointer *mut i32 = view.ptr
pointer[2] += 1
alias_add(&values[0], &view[0])
box Box = Box { point = Point { x = 2, y = 3 } }
match box {
.point |@p|: p.x += values[1]
.empty: values[0] = values[0]
}
if view.len != 3 {
return 0
}
return values[0] + view[1] + pointer[2] + box.point.x
}
GLOBAL :: $sum_loop(4)
ERRDEFER :: $ct_errdefer_check()
main func() i32 {
point Point :: $make_point()
numbers [_]i32 :: $[4, 5, 6]
box Box :: $Box { point = Point { x = 8, y = 1 } }
state State :: $State.ready
name :: $"bro"
value i32 :: $sum_for()
deferred i32 :: $defer_value()
optional i32 :: $maybe(true)?
tried i32 :: $use_try() catch 0
recovered i32 :: $recover()
storage i32 :: $storage_mutation()
called i32 :: $call_native(increment, 11)
comptime_callback i32 :: $apply_comptime(increment, 12)
comptime_literal i32 :: $apply_comptime(func(value i32) i32 { return value + 2 }, 12)
comptime_c_callback i32 :: $apply_comptime_c(decrement_c, 15)
comptime_config i32 :: $apply_comptime_config(Callback_Config {call = increment}, 15)
comptime_array i32 :: $apply_comptime_array([increment, double], 3)
comptime_optional i32 :: $apply_comptime_optional(increment, 16)
comptime_choice i32 :: $apply_comptime_choice(Callback_Choice {call = double}, 9)
fallible_ok i32 :: $call_fallible(may_fail, false) catch 0
fallible_err i32 :: $call_fallible(may_fail, true) catch |e| {
result i32 :: match e {
.bad: 13
}
yield result
}
if point.x + point.y != 7 {
return 1
}
if numbers.len != 3 or numbers[2] != 6 {
return 2
}
if describe(box) != 9 {
return 3
}
if state != State.ready {
return 4
}
if name.len != 3 {
return 5
}
if value != 9 {
return 6
}
if deferred != 12 {
return 7
}
if optional != 9 {
return 8
}
if tried != 8 {
return 9
}
if recovered != 5 {
return 10
}
if GLOBAL != 8 {
return 11
}
if storage != 23 {
return 12
}
if called != 12 {
return 13
}
if call_native(increment, 20) != 21 {
return 14
}
if fallible_ok != 7 {
return 15
}
if fallible_err != 13 {
return 16
}
if ERRDEFER != 42 {
return 17
}
if comptime_callback != 13 or comptime_literal != 14 or
comptime_c_callback != 14 or comptime_config != 16 or
comptime_array != 10 or comptime_optional != 17 or comptime_choice != 18 {
return 18
}
if apply_comptime(increment, 20) != 21 or apply_comptime(increment, 21) != 22 or
apply_comptime(double, 20) != 40 {
return 19
}
if apply_comptime(func(value i32) i32 { return value + 3 }, 20) != 23 {
return 20
}
if apply_comptime_c(decrement_c, 20) != 19 or
apply_comptime_config(Callback_Config {call = increment}, 20) != 21 {
return 21
}
if apply_comptime_array([increment, double], 4) != 13 or
apply_comptime_optional(increment, 4) != 5 or
apply_comptime_choice(Callback_Choice {call = double}, 4) != 8 {
return 22
}
if materialize_callback(increment, 30) != 31 {
return 23
}
return 0
}