Files
bux-lang/examples/macro_unhygienic.bux
dimgigov fe3b1e8b6a
ci / build (ubuntu) (push) Has been cancelled
ci / unit + fmt (push) Has been cancelled
ci / examples (push) Has been cancelled
ci / goldens + tools (push) Has been cancelled
ci / apps (push) Has been cancelled
ci / selfhost smoke (push) Has been cancelled
ci / macos smoke (push) Has been cancelled
ci / windows smoke (push) Has been cancelled
ci / CI gate (push) Has been cancelled
selfhost-loop / bootstrap determinism (push) Has been cancelled
feat: macros (multi-rep, hygiene), Drop field-move, lean multi-OS CI
Sessions 56–69: declarative macro! with rep/zip/literal/block and
unhygienic var $name binders; partial field-move skip Drop; @[Release]
polish; LSP type hierarchy; CI Nim cache + lean macOS + Windows smoke.
2026-07-20 17:19:46 +03:00

74 lines
1.8 KiB
Plaintext

// Session 69 — unhygienic binders: `var $name` keeps the call-site identifier
// (not gensym'd). Hygienic template locals (`acc`) still get unique names.
import Std::Io::{PrintLine};
import Std::String::{String_FromInt};
// Introduce a binder named by the call-site ident; keep that name (unhygienic)
macro! let_mut {
( $name:ident, $init:literal ) => {
var $name: int = $init;
$name = $name + 1;
$name
}
}
// Hygienic local `acc` must not collide across two expansions
macro! double_acc {
( $start:literal ) => {
var acc: int = $start;
acc = acc + acc;
acc
}
}
// Mixed: unhygienic $name + hygienic scratch
macro! bump_named {
( $name:ident ) => {
var $name: int = 0;
var scratch: int = 1;
$name = $name + scratch;
$name
}
}
func Main() -> int {
// Unhygienic: binder becomes `counter` inside the expansion block
let a: int = let_mut!(counter, 10);
// 11
let b: int = let_mut!(other, 20);
// 21
// Hygienic: two expansions with local `acc`
let c: int = double_acc!(3);
let d: int = double_acc!(5);
// 6, 10
let e: int = bump_named!(n);
// 1
PrintLine(String_FromInt(a));
PrintLine(String_FromInt(b));
PrintLine(String_FromInt(c));
PrintLine(String_FromInt(d));
PrintLine(String_FromInt(e));
if a != 11 {
PrintLine("FAIL let_mut counter");
return 1;
}
if b != 21 {
PrintLine("FAIL let_mut other");
return 1;
}
if c != 6 {
PrintLine("FAIL double_acc 3");
return 1;
}
if d != 10 {
PrintLine("FAIL double_acc 5");
return 1;
}
if e != 1 {
PrintLine("FAIL bump_named");
return 1;
}
PrintLine("PASS macro_unhygienic");
return 0;
}