Allow using non-Some-wrapped values in optional KV attributes
This commit is contained in:
parent
dc8447f08e
commit
16f3488d20
@ -83,6 +83,11 @@ pub enum MatchBinding {
|
||||
/// `None =>`
|
||||
UnitVariant { name: IStr },
|
||||
|
||||
/// `$var`
|
||||
/// (A fallback case)
|
||||
/// TODO this is not implemented in the grammar yet, but is used in generated rules
|
||||
Variable { name: IStr },
|
||||
|
||||
/// `_ =>`
|
||||
Ignore,
|
||||
}
|
||||
|
@ -363,10 +363,10 @@ impl<'a, O: OutputSystem + Send, LS: LocalisationSystem + Sync + Send> Interpret
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
warn!(
|
||||
"trying to `match` non-reflective vs {name} at {}",
|
||||
step.locator
|
||||
);
|
||||
// warn!(
|
||||
// "trying to `match` non-reflective vs {name} at {}",
|
||||
// step.locator
|
||||
// );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -416,14 +416,19 @@ impl<'a, O: OutputSystem + Send, LS: LocalisationSystem + Sync + Send> Interpret
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
warn!(
|
||||
"trying to `match` non-reflective vs {name}(...) at {}",
|
||||
step.locator
|
||||
);
|
||||
// warn!(
|
||||
// "trying to `match` non-reflective vs {name}(...) at {}",
|
||||
// step.locator
|
||||
// );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
MatchBinding::Variable { name } => binder.bind(
|
||||
&mut self.scopes[scope_idx].variables,
|
||||
&Binding::Variable(name.clone()),
|
||||
matchable_evaled,
|
||||
),
|
||||
MatchBinding::Ignore => {
|
||||
// always matches: no variable to bind, no conditions to check!
|
||||
}
|
||||
@ -782,11 +787,7 @@ impl<'a, O: OutputSystem + Send, LS: LocalisationSystem + Sync + Send> Interpret
|
||||
Expression::Variable { name, loc } => {
|
||||
let locals = &self.scopes[scope_idx].variables;
|
||||
match locals.get(name as &str) {
|
||||
Some(variable_value) => {
|
||||
let new = variable_value.clone();
|
||||
eprintln!("{variable_value:?} -> {new:?}");
|
||||
Ok(variable_value.clone())
|
||||
}
|
||||
Some(variable_value) => Ok(variable_value.clone()),
|
||||
None => {
|
||||
let locals_list = locals.keys().join(", ");
|
||||
Err(InterpreterError::TypeError {
|
||||
|
@ -215,20 +215,30 @@ fn compile_ast_block_to_steps(
|
||||
let extra_inject = (attr_name.as_str() == "class" && !he.classes.is_empty())
|
||||
.then(|| intern(he.classes.iter().map(|istr| istr.as_str()).join(" ") + " "));
|
||||
if attr_flags.optional {
|
||||
// For optional fields:
|
||||
// - if it matches Some($x), unwrap to $x and emit $x
|
||||
// - if it matches None, skip
|
||||
// - if it matches neither, assume it's already unwrapped and emit directly
|
||||
// A little bit ugly to say the least...
|
||||
let mut some_stage = Vec::new();
|
||||
let virtual_varname = intern("___attrval");
|
||||
|
||||
gen_steps_to_write_attribute(
|
||||
he,
|
||||
attr_name,
|
||||
attr_expr,
|
||||
&Expression::Variable {
|
||||
name: virtual_varname.clone(),
|
||||
loc: he.loc.clone(),
|
||||
},
|
||||
extra_inject.clone(),
|
||||
&mut some_stage,
|
||||
);
|
||||
let binding = MatchBinding::TupleVariant {
|
||||
name: intern("Some"),
|
||||
pieces: vec![Binding::Variable(intern("___attrval"))],
|
||||
pieces: vec![Binding::Variable(virtual_varname.clone())],
|
||||
};
|
||||
|
||||
let mut arms = vec![(binding, some_stage)];
|
||||
let mut arms = vec![(binding, some_stage.clone())];
|
||||
|
||||
if let Some(extra_inject) = extra_inject {
|
||||
let mut none_stage = Vec::new();
|
||||
@ -244,15 +254,29 @@ fn compile_ast_block_to_steps(
|
||||
},
|
||||
none_stage,
|
||||
));
|
||||
} else {
|
||||
arms.push((
|
||||
MatchBinding::UnitVariant {
|
||||
name: intern("None"),
|
||||
},
|
||||
Vec::new(),
|
||||
));
|
||||
}
|
||||
|
||||
arms.push((
|
||||
MatchBinding::Variable {
|
||||
name: virtual_varname.clone(),
|
||||
},
|
||||
some_stage,
|
||||
));
|
||||
|
||||
instructions.push(Step {
|
||||
def: StepDef::Match {
|
||||
matchable: attr_expr.clone(),
|
||||
arms,
|
||||
},
|
||||
locator: he.loc.clone(),
|
||||
})
|
||||
});
|
||||
} else {
|
||||
gen_steps_to_write_attribute(
|
||||
he,
|
||||
|
Loading…
x
Reference in New Issue
Block a user