diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-05-05 01:11:55 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-05-05 01:13:53 +0200 |
commit | 58454a50daefde53614c3bbd42d082892c24a65a (patch) | |
tree | e32cd7ceaba9813e235799fba6760b22db36a7af | |
parent | 4c2334613ea00cec3c0be5a6f6cacdb53ab4cbd3 (diff) | |
download | rebel-58454a50daefde53614c3bbd42d082892c24a65a.tar rebel-58454a50daefde53614c3bbd42d082892c24a65a.zip |
rebel-lang: add support for assigning map entries
-rw-r--r-- | crates/rebel-lang/src/typing.rs | 21 | ||||
-rw-r--r-- | crates/rebel-lang/src/value.rs | 23 |
2 files changed, 22 insertions, 22 deletions
diff --git a/crates/rebel-lang/src/typing.rs b/crates/rebel-lang/src/typing.rs index b794f6d..0dcb4c7 100644 --- a/crates/rebel-lang/src/typing.rs +++ b/crates/rebel-lang/src/typing.rs @@ -548,22 +548,23 @@ impl<'scope> Context<'scope> { let initialized = self.0.initialized.clone(); Ok(match pat { pat::DestrPat::Index { base, index } => { - match self.type_expr(index)? { - Type::Int => {} - _ => { - return Err(Error::typ("invalid array index type")); - } - } - let (typ, ident) = self.lookup_destr_pat_var_type_mut(base)?; + let index_type = self.type_expr(index)?; + let (base_type, ident) = self.lookup_destr_pat_var_type_mut(base)?; if !initialized.contains(ident.name) { return Err(Error::typ( "tried to assign field of uninitialized variable", )); } ( - match typ { - Type::Array(inner) => inner.as_mut(), - _ => return Err(Error::typ("invalid array index base")), + match (base_type, index_type) { + (Type::Array(inner), Type::Int) => inner.as_mut(), + (Type::Map(key_type, value_type), index_type) => { + *key_type = key_type + .clone() + .unify(OrdType::try_from(index_type)?, Coerce::Common)?; + value_type.as_mut() + } + _ => return Err(Error::typ("invalid types for index operation")), }, ident, ) diff --git a/crates/rebel-lang/src/value.rs b/crates/rebel-lang/src/value.rs index dbd9876..82c1f5c 100644 --- a/crates/rebel-lang/src/value.rs +++ b/crates/rebel-lang/src/value.rs @@ -459,19 +459,18 @@ impl<'scope> Context<'scope> { fn lookup_destr_pat_var_value_mut(&mut self, pat: &pat::DestrPat) -> Result<&mut Value> { Ok(match pat { pat::DestrPat::Index { base, index } => { - let index = usize::try_from(match self.eval_expr(index)? { - Value::Int(index) => index, - _ => { - return Err(Error::typ("invalid array index type")); - } - }) - .or(Err(Error::eval("array index out of bounds")))?; - let value = self.lookup_destr_pat_var_value_mut(base)?; - match value { - Value::Array(inner) => inner - .get_mut(index) + let index_value = self.eval_expr(index)?; + let base_value = self.lookup_destr_pat_var_value_mut(base)?; + match (base_value, index_value) { + (Value::Array(inner), Value::Int(index)) => usize::try_from(index) + .ok() + .and_then(|index| inner.get_mut(index)) .ok_or(Error::eval("array index out of bounds"))?, - _ => return Err(Error::typ("invalid array index base")), + (Value::Map(entries), key) => { + let key = OrdValue::try_from(key)?; + entries.entry(key).or_insert(Value::Uninitialized) + } + _ => return Err(Error::typ("invalid types for index operation")), } } pat::DestrPat::Field { base, field } => { |