Skip to content

Commit

Permalink
Allow to encode array of tuples type
Browse files Browse the repository at this point in the history
  • Loading branch information
danhper committed Nov 20, 2024
1 parent b83d1db commit f4cd0ed
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 2 deletions.
29 changes: 27 additions & 2 deletions src/interpreter/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,9 +441,34 @@ pub fn evaluate_expression(env: &mut Env, expr: Box<Expression>) -> 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::<Result<_>>()?);
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())
Expand Down
7 changes: 7 additions & 0 deletions src/interpreter/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,13 @@ impl Value {
}
}

pub fn as_type(&self) -> Result<Type> {
match self {
Value::TypeObject(type_) => Ok(type_.clone()),
_ => bail!("cannot convert {} to type", self.get_type()),
}
}

pub fn as_i32(&self) -> Result<i32> {
match self {
Value::Int(n, _) => Ok(n.as_i32()),
Expand Down

0 comments on commit f4cd0ed

Please sign in to comment.