Add macro for parsing dictionaries

This commit is contained in:
hal8174 2025-08-10 22:07:44 +02:00
parent b56f952e9b
commit d6662da7b9
Signed by: hal8174
SSH key fingerprint: SHA256:NN98ZYwnrreQLSOV/g+amY7C3yL/mS1heD7bi5t6PPw

View file

@ -47,42 +47,74 @@ fn parse_look_at(iter: &mut Tokenizer) -> Result<Statement> {
)) ))
} }
macro_rules! parse_dict {
($tokenizer:expr => $($name_decl:ident, $type:ty, $default:expr);+ => $($name_parsing:ident, $expr:expr, $parsing:expr);+
) => {
{
$(
let mut $name_decl = None;
)+
while let Some(p) = $tokenizer.next_if(|p| p.starts_with('"')).transpose()? {
match p.as_str() {
$(
$expr => {
if $name_parsing.is_none() {
$name_parsing = Some($parsing);
} else {
return Err(miette!("dfs"))
}
}
)+
_ => {todo!()}
}
}
#[derive(Debug)]
struct Dict {
$(
$name_decl: $type,
)+
}
$(
let $name_decl = $name_decl.unwrap_or_else(|| $default);
)*
Dict {
$($name_decl,)*
}
}
};
}
fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> { fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
let shape_type = iter.next().ok_or(miette!("unable to get shape type"))??; let shape_type = iter.next().ok_or(miette!("unable to get shape type"))??;
match shape_type.as_str() { match shape_type.as_str() {
"\"sphere\"" => { "\"sphere\"" => {
let mut radius = 1.0; let t = parse_dict!(iter =>
let zmin = -radius; radius, Float, 1.0;
let zmax = radius; zmin, Float, {-radius};
let phimax = 360.0; zmax, Float, {radius};
let mut alpha = ShapeAlpha::None; phimax, Float, 360.0;
alpha, ShapeAlpha, ShapeAlpha::None
while let Some(p) = iter.next_if(|p| p.starts_with('"')).transpose()? { =>
match p.as_str() { radius, "\"float radius\"", iter.parse_parameter()?;
"\"float radius\"" => { zmin, "\"float zmin\"", iter.parse_parameter()?;
radius = iter.parse_parameter()?; zmax, "\"float zmax\"", iter.parse_parameter()?;
} phimax, "\"float phimax\"", iter.parse_parameter()?;
"\"float alpha\"" => { alpha, "\"float alpha\"", ShapeAlpha::Value(iter.parse_parameter()?);
alpha = ShapeAlpha::Value(iter.parse_parameter()?); alpha, "\"texture alpha\"", ShapeAlpha::Texture(iter.parse_parameter()?)
} );
"\"texture alpha\"" => {
alpha = ShapeAlpha::Texture(iter.parse_parameter()?);
}
_ => {
bail!("unknown argument {}", p)
}
}
}
Ok(Statement::Shape( Ok(Statement::Shape(
ShapeType::Sphere { ShapeType::Sphere {
radius, radius: t.radius,
zmin, zmin: t.zmin,
zmax, zmax: t.zmax,
phimax, phimax: t.phimax,
}, },
alpha, t.alpha,
)) ))
} }
"\"trianglemesh\"" => { "\"trianglemesh\"" => {