Add a tuple binding

This commit is contained in:
Olivier 'reivilibre' 2023-11-21 23:16:58 +00:00
parent cbfdece2cb
commit 159457616a
4 changed files with 41 additions and 2 deletions

View File

@ -76,6 +76,7 @@ pub enum MatchBinding {
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum Binding {
Variable(IStr),
Tuple(Vec<Binding>),
Ignore,
}

View File

@ -205,9 +205,10 @@ MapLiteral = { "{" ~ commaSeparatedKVPairs ~ "}" }
// As in a let binding or for binding.
// More options in the future, but for now you just get one identifier and that's it!
Binding = {
VarBinding | IgnoreBinding
VarBinding | TupleBinding | IgnoreBinding
}
VarBinding = { "$" ~ Identifier }
TupleBinding = { "(" ~ Binding ~ "," ~ ws* ~ (Binding ~ "," ~ ws*)+ ~ (Binding)? ~ ")" }
IgnoreBinding = { "_" }
LocalisationIdentifier = @{ ASCII_ALPHA ~ (ASCII_ALPHANUMERIC | "_" | "-")+ }

View File

@ -422,6 +422,7 @@ impl HornbeamParser {
Ok(match_nodes!(input.into_children();
[VarBinding(b)] => b,
[IgnoreBinding(b)] => b,
[TupleBinding(b)] => b,
))
}
@ -434,6 +435,14 @@ impl HornbeamParser {
Ok(Binding::Ignore)
}
fn TupleBinding(input: Node) -> PCResult<Binding> {
Ok(match_nodes!(input.into_children();
[Binding(bs)..] => {
Binding::Tuple(bs.collect())
}
))
}
fn EmptyForBlock(input: Node) -> PCResult<Vec<Block>> {
HornbeamParser::helper_blocks(input.into_children())
}

View File

@ -127,13 +127,41 @@ impl Binder {
binding: &Binding,
value: Value,
) {
// TODO duplicated code
match binding {
Binding::Variable(var_name) => {
let var_name = String::from(var_name as &str);
variables.insert(var_name.clone(), value);
self.variables_to_unbind.push(var_name);
}
Binding::Tuple(field_bindings) => {
match value {
Value::Str(_) | Value::Int(_) | Value::Bool(_) | Value::List(_) => {
// Error binding
todo!()
}
Value::Reflective(reflective) => match reflective.reflect_ref() {
ReflectRef::Tuple(tuple) => {
if tuple.field_len() != field_bindings.len() {
// Error binding
todo!();
}
for (field_idx, field_binding) in field_bindings.iter().enumerate() {
self.bind(
variables,
field_binding,
Value::from_reflect(
tuple.field(field_idx).unwrap().clone_value(),
),
);
}
}
_ => {
// Error binding
todo!()
}
},
}
}
Binding::Ignore => {}
}
}