#![allow(clippy::expect_used, clippy::panic, clippy::unwrap_used)]
use zerodds_lang_cst::common::{Doc, Ident, Literal, Path};
const ARMS: usize = 10_000;
const STACK: usize = 128 * 1024;
const ROOM: usize = 64 * 1024 * 1024;
fn rendered<Tree, Out>(
build: impl FnOnce() -> Tree + Send,
render: impl FnOnce(&Tree) -> Out + Send,
) -> Out
where
Tree: Send + Sync,
Out: Send,
{
std::thread::scope(|outer| {
std::thread::Builder::new()
.stack_size(ROOM)
.spawn_scoped(outer, move || {
let tree = build();
std::thread::scope(|inner| {
std::thread::Builder::new()
.stack_size(STACK)
.spawn_scoped(inner, || render(&tree))
.expect("the rendering thread starts")
.join()
.expect("the rendering thread finishes")
})
})
.expect("the building thread starts")
.join()
.expect("the building thread finishes")
})
}
fn assert_flat(text: &str, continuation: &str, deepest: usize) {
assert_eq!(
text.matches(continuation).count(),
ARMS - 1,
"every arm after the first continues the chain"
);
let widest = text
.lines()
.map(|line| line.len() - line.trim_start().len())
.max()
.expect("the output has lines");
assert!(
widest <= deepest,
"no line is indented past the body of one arm: {widest} > {deepest}"
);
}
#[test]
fn a_c_dispatch_chain_of_ten_thousand_arms_renders_flat() {
use zerodds_lang_cst::c::{Block, Decl, Expr, Function, Statement, Type};
let text = rendered(
|| {
let arm = |value: i128| Expr::Binary {
op: "==",
lhs: Box::new(Expr::Name(Ident::new("id"))),
rhs: Box::new(Expr::Literal(Literal::int(value))),
};
let mut otherwise: Option<Block> = None;
for value in (0..ARMS).rev() {
otherwise = Some(Block {
statements: vec![Statement::If {
condition: arm(value as i128),
then: Block {
statements: vec![Statement::Break],
},
otherwise,
}],
});
}
Decl::Function(Function {
doc: Doc::none(),
is_static: true,
is_inline: false,
is_maybe_unused: false,
returns: Type::Void,
name: Ident::new("dispatch"),
params: Vec::new(),
body: otherwise,
})
},
zerodds_lang_render::c::decl,
);
assert_flat(&text, "} else if (", 8);
}
#[test]
fn a_d_dispatch_chain_of_ten_thousand_arms_renders_flat() {
use zerodds_lang_cst::d::{Decl, Expr, FuncDecl, Stmt};
let text = rendered(
|| {
let mut otherwise: Option<Vec<Stmt>> = None;
for _ in 0..ARMS {
otherwise = Some(vec![Stmt::If {
condition: Expr::Name(Ident::new("ok")),
then: vec![Stmt::Break],
otherwise,
}]);
}
Decl::Func(FuncDecl {
doc: Doc::none(),
name: Ident::new("dispatch"),
params: Vec::new(),
returns: None,
body: otherwise.expect("the chain has arms"),
})
},
zerodds_lang_render::d::decl,
);
assert_flat(&text, "else if (", 8);
}
#[test]
fn an_fsharp_dispatch_chain_of_ten_thousand_arms_renders_flat() {
use zerodds_lang_cst::fsharp::{Decl, Expr, LetDecl, Stmt};
let text = rendered(
|| {
let mut otherwise: Option<Vec<Stmt>> = None;
for _ in 0..ARMS {
otherwise = Some(vec![Stmt::If {
condition: Expr::Name(Ident::new("ok")),
then: vec![Stmt::Leave],
otherwise,
}]);
}
Decl::Let(LetDecl {
doc: Doc::none(),
name: Ident::new("dispatch"),
params: Vec::new(),
type_: None,
body: otherwise.expect("the chain has arms"),
})
},
zerodds_lang_render::fsharp::decl,
);
assert_flat(&text, "elif ", 8);
}
#[test]
fn a_go_dispatch_chain_of_ten_thousand_arms_renders_flat() {
use zerodds_lang_cst::go::{Decl, Expr, FuncDecl, Stmt};
let text = rendered(
|| {
let mut otherwise: Option<Vec<Stmt>> = None;
for _ in 0..ARMS {
otherwise = Some(vec![Stmt::If {
condition: Expr::name("ok"),
then: vec![Stmt::Break],
otherwise,
}]);
}
Decl::Func(FuncDecl {
doc: Doc::none(),
name: Ident::new("dispatch"),
params: Vec::new(),
results: Vec::new(),
body: otherwise.expect("the chain has arms"),
})
},
zerodds_lang_render::go::decl,
);
assert_flat(&text, "} else if ", 8);
}
#[test]
fn a_kotlin_dispatch_chain_of_ten_thousand_arms_renders_flat() {
use zerodds_lang_cst::kotlin::{Block, Decl, Expr, FuncDecl, Stmt, Type};
let text = rendered(
|| {
let mut otherwise: Option<Block> = None;
for _ in 0..ARMS {
otherwise = Some(Block {
statements: vec![Stmt::If {
condition: Expr::name("ok"),
then: Block {
statements: vec![Stmt::Break],
},
otherwise,
}],
});
}
Decl::Func(FuncDecl {
doc: Doc::none(),
name: Ident::new("dispatch"),
params: Vec::new(),
returns: Type::Named {
path: Path::new(&["Unit"]),
args: Vec::new(),
},
body: otherwise.expect("the chain has arms").statements,
})
},
zerodds_lang_render::kotlin::decl,
);
assert_flat(&text, "} else if (", 8);
}
#[test]
fn a_lua_dispatch_chain_of_ten_thousand_arms_renders_flat() {
use zerodds_lang_cst::lua::{Expr, Stat};
let text = rendered(
|| {
let mut otherwise: Option<Vec<Stat>> = None;
for _ in 0..ARMS {
otherwise = Some(vec![Stat::If {
condition: Expr::bool(true),
then: vec![Stat::Break],
otherwise,
}]);
}
let mut chain = otherwise.expect("the chain has arms");
chain.remove(0)
},
zerodds_lang_render::lua::stat,
);
assert_flat(&text, "elseif ", 4);
}
#[test]
fn a_node_dispatch_chain_of_ten_thousand_arms_renders_flat() {
use zerodds_lang_cst::node::{Expr, Stat};
let text = rendered(
|| {
let mut otherwise: Option<Vec<Stat>> = None;
for _ in 0..ARMS {
otherwise = Some(vec![Stat::If {
condition: Expr::name("ok"),
then: vec![Stat::Break],
otherwise,
}]);
}
let mut chain = otherwise.expect("the chain has arms");
chain.remove(0)
},
zerodds_lang_render::node::stat,
);
assert_flat(&text, "} else if (", 4);
}
#[test]
fn a_python_dispatch_chain_of_ten_thousand_arms_renders_flat() {
use zerodds_lang_cst::python::{Expr, Statement};
let text = rendered(
|| {
let mut otherwise: Option<Vec<Statement>> = None;
for _ in 0..ARMS {
otherwise = Some(vec![Statement::If {
condition: Expr::name("ok"),
then: vec![Statement::Break],
otherwise,
}]);
}
let mut chain = otherwise.expect("the chain has arms");
chain.remove(0)
},
zerodds_lang_render::python::statement,
);
assert_flat(&text, "elif ", 4);
}
#[test]
fn a_swift_dispatch_chain_of_ten_thousand_arms_renders_flat() {
use zerodds_lang_cst::swift::{Decl, Expr, FuncDecl, Stmt};
let text = rendered(
|| {
let mut otherwise: Option<Vec<Stmt>> = None;
for _ in 0..ARMS {
otherwise = Some(vec![Stmt::If {
condition: Expr::Name(Ident::new("ok")),
then: vec![Stmt::Break],
otherwise,
}]);
}
Decl::Func(FuncDecl {
doc: Doc::none(),
visibility: zerodds_lang_cst::common::Visibility::Internal,
name: Ident::new("dispatch"),
params: Vec::new(),
throws: false,
returns: None,
body: otherwise.expect("the chain has arms"),
})
},
zerodds_lang_render::swift::decl,
);
assert_flat(&text, "} else if ", 8);
}
#[test]
fn a_zig_dispatch_chain_of_ten_thousand_arms_renders_flat() {
use zerodds_lang_cst::zig::{Decl, Expr, FuncDecl, Stmt, Type};
let text = rendered(
|| {
let mut otherwise: Option<Vec<Stmt>> = None;
for _ in 0..ARMS {
otherwise = Some(vec![Stmt::If {
condition: Expr::Name(Ident::new("ok")),
then: vec![Stmt::Break],
otherwise,
}]);
}
Decl::Func(FuncDecl {
doc: Doc::none(),
is_pub: false,
name: Ident::new("dispatch"),
params: Vec::new(),
returns: Type::Named(Ident::new("void")),
body: otherwise.expect("the chain has arms"),
})
},
zerodds_lang_render::zig::decl,
);
assert_flat(&text, "} else if (", 8);
}