summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2024-05-05 01:11:55 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2024-05-05 01:13:53 +0200
commit58454a50daefde53614c3bbd42d082892c24a65a (patch)
treee32cd7ceaba9813e235799fba6760b22db36a7af
parent4c2334613ea00cec3c0be5a6f6cacdb53ab4cbd3 (diff)
downloadrebel-58454a50daefde53614c3bbd42d082892c24a65a.tar
rebel-58454a50daefde53614c3bbd42d082892c24a65a.zip
rebel-lang: add support for assigning map entries
-rw-r--r--crates/rebel-lang/src/typing.rs21
-rw-r--r--crates/rebel-lang/src/value.rs23
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 } => {