diff --git a/ablescript/src/ast.rs b/ablescript/src/ast.rs index a5f19055..3a7941e7 100644 --- a/ablescript/src/ast.rs +++ b/ablescript/src/ast.rs @@ -190,6 +190,7 @@ pub enum ExprKind { expr: Box, index: Box, }, + Len(Box), Variable(String), } diff --git a/ablescript/src/interpret.rs b/ablescript/src/interpret.rs index 183eb9ff..044e9e3d 100644 --- a/ablescript/src/interpret.rs +++ b/ablescript/src/interpret.rs @@ -175,6 +175,7 @@ impl ExecEnv { .map(|x| x.borrow().clone()) .unwrap_or(Value::Nul) } + Len(_) => todo!("length"), // TODO: not too happy with constructing an artificial // Ident here. diff --git a/ablescript/src/parser.rs b/ablescript/src/parser.rs index 6f7ebb66..9fd351e9 100644 --- a/ablescript/src/parser.rs +++ b/ablescript/src/parser.rs @@ -195,10 +195,7 @@ impl<'source> Parser<'source> { Token::LeftBracket => match buf.take() { Some(buf) => Ok(Expr::new( - ExprKind::Index { - expr: Box::new(buf), - index: Box::new(self.expr_flow(Token::RightBracket)?), - }, + self.index_flow(buf)?, start..self.lexer.span().end, )), None => Ok(Expr::new(self.cart_flow()?, start..self.lexer.span().end)), @@ -279,6 +276,27 @@ impl<'source> Parser<'source> { Ok(ExprKind::Cart(cart)) } + /// Flow for indexing operations + /// + /// Indexing with empty index resolves to length of expression, else it indexes + fn index_flow(&mut self, expr: Expr) -> Result { + let mut buf = None; + Ok(loop { + match self.checked_next()? { + Token::RightBracket => match buf { + Some(index) => { + break ExprKind::Index { + expr: Box::new(expr), + index: Box::new(index), + } + } + None => break ExprKind::Len(Box::new(expr)), + }, + token => buf = Some(self.parse_expr(token, &mut buf)?), + } + }) + } + /// Flow for operators /// /// Generates operation from LHS buffer and next expression as RHS