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::Callable(Callable::RecordConstructor { type_id, tag, field_order });
|
||||||
Expression::Call { f: Box::new(constructor), args: ordered_args }
|
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 } => {
|
WhileExpression { condition, body } => {
|
||||||
let cond = Box::new(if let Some(condition) = condition {
|
let cond = Box::new(if let Some(condition) = condition {
|
||||||
self.expression(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(
|
fn reduce_if_expression(
|
||||||
&mut self,
|
&mut self,
|
||||||
discriminator: Option<&ast::Expression>,
|
discriminator: Option<&ast::Expression>,
|
||||||
|
@ -60,6 +60,7 @@ pub enum Expression {
|
|||||||
Conditional { cond: Box<Expression>, then_clause: Vec<Statement>, else_clause: Vec<Statement> },
|
Conditional { cond: Box<Expression>, then_clause: Vec<Statement>, else_clause: Vec<Statement> },
|
||||||
CaseMatch { cond: Box<Expression>, alternatives: Vec<Alternative> },
|
CaseMatch { cond: Box<Expression>, alternatives: Vec<Alternative> },
|
||||||
Loop { cond: Box<Expression>, statements: Vec<Statement> },
|
Loop { cond: Box<Expression>, statements: Vec<Statement> },
|
||||||
|
Index { indexee: Box<Expression>, indexer: Box<Expression> },
|
||||||
ReductionError(String),
|
ReductionError(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,6 +172,18 @@ impl<'a, 'b> Evaluator<'a, 'b> {
|
|||||||
}
|
}
|
||||||
Expression::CaseMatch { box cond, alternatives } =>
|
Expression::CaseMatch { box cond, alternatives } =>
|
||||||
self.case_match_expression(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::Loop { box cond, statements } => self.loop_expression(cond, statements)?,
|
||||||
Expression::ReductionError(e) => return Err(e.into()),
|
Expression::ReductionError(e) => return Err(e.into()),
|
||||||
Expression::Access { name, box expr } => {
|
Expression::Access { name, box expr } => {
|
||||||
|
@ -536,4 +536,13 @@ a
|
|||||||
"#,
|
"#,
|
||||||
"[7, 8, 9]",
|
"[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