Implemented Len in parser

This commit is contained in:
Erin 2022-01-22 20:37:44 +01:00 committed by ondra05
parent a7bba352d5
commit 30ab0cf7da
3 changed files with 24 additions and 4 deletions

View file

@ -190,6 +190,7 @@ pub enum ExprKind {
expr: Box<Expr>,
index: Box<Expr>,
},
Len(Box<Expr>),
Variable(String),
}

View file

@ -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.

View file

@ -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<ExprKind, Error> {
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