diff --git a/schala-lang/language/src/reduced_ir/mod.rs b/schala-lang/language/src/reduced_ir/mod.rs index e4eb3f5..450e6fa 100644 --- a/schala-lang/language/src/reduced_ir/mod.rs +++ b/schala-lang/language/src/reduced_ir/mod.rs @@ -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>, diff --git a/schala-lang/language/src/reduced_ir/types.rs b/schala-lang/language/src/reduced_ir/types.rs index 21340bf..b6fd275 100644 --- a/schala-lang/language/src/reduced_ir/types.rs +++ b/schala-lang/language/src/reduced_ir/types.rs @@ -60,6 +60,7 @@ pub enum Expression { Conditional { cond: Box, then_clause: Vec, else_clause: Vec }, CaseMatch { cond: Box, alternatives: Vec }, Loop { cond: Box, statements: Vec }, + Index { indexee: Box, indexer: Box }, ReductionError(String), } diff --git a/schala-lang/language/src/tree_walk_eval/evaluator.rs b/schala-lang/language/src/tree_walk_eval/evaluator.rs index a242fab..279eb16 100644 --- a/schala-lang/language/src/tree_walk_eval/evaluator.rs +++ b/schala-lang/language/src/tree_walk_eval/evaluator.rs @@ -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 } => { diff --git a/schala-lang/language/src/tree_walk_eval/test.rs b/schala-lang/language/src/tree_walk_eval/test.rs index 88dfcdb..5f42f81 100644 --- a/schala-lang/language/src/tree_walk_eval/test.rs +++ b/schala-lang/language/src/tree_walk_eval/test.rs @@ -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)", + ); }