This commit is contained in:
allexanderbergmns
2026-08-25 18:03:03 +02:00
parent 3e1e9bd08a
commit 68b3a3673c
15 changed files with 402 additions and 8 deletions
+53
View File
@@ -0,0 +1,53 @@
// defer_reflection.vr — demonstrates the Batch-A features: `defer` cleanup,
// the `in` membership operator, `type_info()` reflection, and `range()`.
//
// vr run examples/defer_reflection.vr
fn summarize(v) {
// reflection: inspect any value and build a description
let ti = type_info(v)
let kind = ti.kind
if ti.is_number {
return "a number " + str(v)
} else if ti.is_string {
return "a string of length " + str(ti.len) + ": \"" + v + "\""
} else if ti.is_array {
return "an array with " + str(ti.len) + " elements"
} else if ti.is_struct {
return "a record with fields " + str(ti.fields)
} else if ti.is_none {
return "nothing"
}
return "a " + kind
}
fn grep_lines(docs, term) {
// demonstrate `in` on strings + arrays, with deferred cleanup
let matches = []
defer println(" -> searched " + str(len(docs)) + " docs for \"" + term + "\"")
for d in docs {
if term in d { // substring membership
push(matches, d)
}
}
return matches
}
fn main() {
// range + in + type_info
let nums = range(1, 6) // [1, 2, 3, 4, 5]
println("nums = " + str(nums))
println("3 present? " + str(3 in nums))
println("7 present? " + str(7 in nums))
println(summarize(42))
println(summarize("hello"))
println(summarize([1, 2, 3]))
println(summarize({x: 1, y: 2}))
println(summarize(none))
println("---")
let docs = ["Introducing VuurRaaf", "A tiny language", "VuurRaaf: daily driver"]
let hits = grep_lines(docs, "VuurRaaf")
println("hits: " + str(hits))
}
+77
View File
@@ -658,6 +658,83 @@ fn test_flag_parsing() {
assert len(flag_positional()) == 0
}
fn test_defer_cleanup() {
// defer runs on every exit path; its effect is visible to the caller via
// the shared mutable array (arrays are references).
let log = []
let a = defer_probe(log, 1)
assert a == 0
assert len(log) == 2
assert log[0] == "open"
assert log[1] == "close"
}
fn defer_probe(log, mode) {
push(log, "open")
defer push(log, "close")
if mode == 0 { // early return path also runs defer
return 9
}
return 0
}
fn test_defer_lifo() {
// defers run in reverse declaration order (LIFO), all before returning
let logA = []
let r = defer_lifo(logA)
assert r == 0
assert len(logA) == 2
assert logA[0] == "2nd-registered"
assert logA[1] == "1st-registered"
}
fn defer_lifo(log) {
defer push(log, "1st-registered")
defer push(log, "2nd-registered")
return 0
}
fn test_in_operator() {
let arr = [1, 2, 3]
assert 2 in arr
assert 9 in arr == false
let m = {x: 1}
assert "x" in m
assert "zzz" in m == false
let s = "hello world"
assert "world" in s
assert "nope" in s == false
assert not (9 in arr)
}
fn test_range_helper() {
let up = range(0, 4)
assert len(up) == 4
assert up[0] == 0
assert up[3] == 3
let down = range(3, 0)
assert down[0] == 3
assert down[2] == 1
assert len(down) == 3
}
fn test_type_info() {
let ti = type_info(42)
assert ti.kind == "int"
assert ti.is_int == 1
assert ti.is_number == 1
let ts = type_info("xyz")
assert ts.is_string == 1
assert ts.len == 3
let tn = type_info(none)
assert tn.kind == "none"
assert tn.is_none == 1
let to = type_info({a: 1})
assert to.is_struct == 1
assert len(to.fields) == 1
assert to.fields[0] == "a"
}
fn test_failing() {
// this one is meant to fail — shows up in `vr test` output
assert 1 == 2