Add macro for parsing dictionaries
This commit is contained in:
parent
b56f952e9b
commit
d6662da7b9
1 changed files with 60 additions and 28 deletions
|
|
@ -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\"" => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue