From f4cd0ed0f818fd302642388b7eb9138d944b04c1 Mon Sep 17 00:00:00 2001 From: Daniel Perez Date: Wed, 20 Nov 2024 20:15:53 +0000 Subject: [PATCH] Allow to encode array of tuples type --- src/interpreter/interpreter.rs | 29 +++++++++++++++++++++++++++-- src/interpreter/value.rs | 7 +++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/interpreter/interpreter.rs b/src/interpreter/interpreter.rs index a7cf57d..aa33df3 100644 --- a/src/interpreter/interpreter.rs +++ b/src/interpreter/interpreter.rs @@ -441,9 +441,34 @@ pub fn evaluate_expression(env: &mut Env, expr: Box) -> BoxFuture<'_ Expression::ArraySubscript(_, expr, subscript_opt) => { let lhs = evaluate_expression(env, expr).await?; match lhs { - Value::Tuple(values) | Value::Array(values, _) => { + Value::Tuple(values) => { + let is_type_tuple = + values.iter().all(|v| matches!(v, Value::TypeObject(_))); + + if !is_type_tuple { + let subscript = subscript_opt + .ok_or(anyhow!("arrays do not support empty subscript"))?; + let value = evaluate_expression(env, subscript).await?; + let index = ArrayIndex::try_from(value)?.get_index(values.len())?; + return Ok(values[index].clone()); + } + + let type_ = + Type::Tuple(values.iter().map(|v| v.as_type()).collect::>()?); + match subscript_opt { + Some(subscript) => { + let value = evaluate_expression(env, subscript).await?; + Ok(Value::TypeObject(Type::FixedArray( + Box::new(type_), + value.as_usize()?, + ))) + } + None => Ok(Value::TypeObject(Type::Array(Box::new(type_)))), + } + } + Value::Array(values, _) => { let subscript = subscript_opt - .ok_or(anyhow!("tuples and arrays do not support empty subscript"))?; + .ok_or(anyhow!("arrays do not support empty subscript"))?; let value = evaluate_expression(env, subscript).await?; let index = ArrayIndex::try_from(value)?.get_index(values.len())?; Ok(values[index].clone()) diff --git a/src/interpreter/value.rs b/src/interpreter/value.rs index 5529d4b..aa95c3d 100644 --- a/src/interpreter/value.rs +++ b/src/interpreter/value.rs @@ -426,6 +426,13 @@ impl Value { } } + pub fn as_type(&self) -> Result { + match self { + Value::TypeObject(type_) => Ok(type_.clone()), + _ => bail!("cannot convert {} to type", self.get_type()), + } + } + pub fn as_i32(&self) -> Result { match self { Value::Int(n, _) => Ok(n.as_i32()),