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)] #[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum Binding { pub enum Binding {
Variable(IStr), Variable(IStr),
Tuple(Vec<Binding>),
Ignore, Ignore,
} }

View File

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

View File

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

View File

@ -127,13 +127,41 @@ impl Binder {
binding: &Binding, binding: &Binding,
value: Value, value: Value,
) { ) {
// TODO duplicated code
match binding { match binding {
Binding::Variable(var_name) => { Binding::Variable(var_name) => {
let var_name = String::from(var_name as &str); let var_name = String::from(var_name as &str);
variables.insert(var_name.clone(), value); variables.insert(var_name.clone(), value);
self.variables_to_unbind.push(var_name); 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 => {} Binding::Ignore => {}
} }
} }