Implement basic list indexing
This commit is contained in:
parent
c66f67e469
commit
8a9c63eccf
@ -176,7 +176,7 @@ impl<'a, 'b> Reducer<'a, 'b> {
|
||||
Expression::Callable(Callable::RecordConstructor { type_id, tag, field_order });
|
||||
Expression::Call { f: Box::new(constructor), args: ordered_args }
|
||||
}
|
||||
Index { .. } => Expression::ReductionError("Index expr not implemented".to_string()),
|
||||
Index { indexee, indexers } => self.reduce_index(indexee.as_ref(), indexers.as_slice()),
|
||||
WhileExpression { condition, body } => {
|
||||
let cond = Box::new(if let Some(condition) = condition {
|
||||
self.expression(condition)
|
||||
@ -193,6 +193,16 @@ impl<'a, 'b> Reducer<'a, 'b> {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO figure out the semantics of multiple indexers - for now, just ignore them
|
||||
fn reduce_index(&mut self, indexee: &ast::Expression, indexers: &[ast::Expression]) -> Expression {
|
||||
if indexers.len() != 1 {
|
||||
return Expression::ReductionError("Invalid index expression".to_string());
|
||||
}
|
||||
let indexee = self.expression(indexee);
|
||||
let indexer = self.expression(&indexers[0]);
|
||||
Expression::Index { indexee: Box::new(indexee), indexer: Box::new(indexer) }
|
||||
}
|
||||
|
||||
fn reduce_if_expression(
|
||||
&mut self,
|
||||
discriminator: Option<&ast::Expression>,
|
||||
|
@ -60,6 +60,7 @@ pub enum Expression {
|
||||
Conditional { cond: Box<Expression>, then_clause: Vec<Statement>, else_clause: Vec<Statement> },
|
||||
CaseMatch { cond: Box<Expression>, alternatives: Vec<Alternative> },
|
||||
Loop { cond: Box<Expression>, statements: Vec<Statement> },
|
||||
Index { indexee: Box<Expression>, indexer: Box<Expression> },
|
||||
ReductionError(String),
|
||||
}
|
||||
|
||||
|
@ -172,6 +172,18 @@ impl<'a, 'b> Evaluator<'a, 'b> {
|
||||
}
|
||||
Expression::CaseMatch { box cond, alternatives } =>
|
||||
self.case_match_expression(cond, alternatives)?,
|
||||
Expression::Index { box indexee, box indexer } => {
|
||||
let indexee = self.expression(indexee)?;
|
||||
let indexer = self.expression(indexer)?;
|
||||
match (indexee, indexer) {
|
||||
(Primitive::List(items), Primitive::Literal(Literal::Nat(n))) =>
|
||||
match items.get(n as usize) {
|
||||
Some(item) => item.clone(),
|
||||
None => return Err(format!("Invalid index {} for this value", n).into()),
|
||||
},
|
||||
_ => return Err("Invalid index type".to_string().into()),
|
||||
}
|
||||
}
|
||||
Expression::Loop { box cond, statements } => self.loop_expression(cond, statements)?,
|
||||
Expression::ReductionError(e) => return Err(e.into()),
|
||||
Expression::Access { name, box expr } => {
|
||||
|
@ -536,4 +536,13 @@ a
|
||||
"#,
|
||||
"[7, 8, 9]",
|
||||
);
|
||||
|
||||
eval_assert(
|
||||
r#"
|
||||
let a = [7, 8, 9]
|
||||
fn foo() { return 2 }
|
||||
(a[0], a[foo()])
|
||||
"#,
|
||||
"(7, 9)",
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user