Add lists
This introduces: * new syntax for list literals, put comma-separated values between braces for your new list * new syntax for indexing, do `foo[index]` to get the value in `foo` at `index`. Lists also allow negative indices too. Any type that wants to be indexed can include their own __index__ function as well. * new VM instruction, BuildList. List literals were a lot easier to implement using this rather than creating a new list, creating a temporary stack value, and then duplicating + pushing to that temporary value over and over. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -743,6 +743,16 @@ impl Parser {
|
||||
.expect("expect name after '.'", TokenKind::Name)?
|
||||
.clone();
|
||||
expr = Box::new(GetExpr { expr, name });
|
||||
} else if self.mat(TokenKind::LBracket)? {
|
||||
let index = self.expr()?;
|
||||
let rbracket = self
|
||||
.expect("expect ']' after index expression", TokenKind::RBracket)?
|
||||
.clone();
|
||||
expr = Box::new(IndexExpr {
|
||||
expr,
|
||||
index,
|
||||
rbracket,
|
||||
})
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@@ -801,6 +811,8 @@ impl Parser {
|
||||
self.expect("expect ')' after expression", TokenKind::RParen)?;
|
||||
}
|
||||
Ok(expr)
|
||||
} else if self.mat(TokenKind::LBracket)? {
|
||||
self.list()
|
||||
} else {
|
||||
Err(self.error(format!("unexpected token {:?}", self.current.kind)))
|
||||
}
|
||||
@@ -854,6 +866,32 @@ impl Parser {
|
||||
params.push((name, ty));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn list(&mut self) -> Result<ExprP> {
|
||||
let lbracket = self.prev.clone().unwrap();
|
||||
let mut exprs = Vec::new();
|
||||
|
||||
if !self.check(TokenKind::RBracket) {
|
||||
exprs.push(self.expr()?);
|
||||
while self.mat(TokenKind::Comma)? {
|
||||
// allow trailing comma
|
||||
if self.check(TokenKind::RBracket) {
|
||||
break;
|
||||
}
|
||||
exprs.push(self.expr()?);
|
||||
}
|
||||
}
|
||||
|
||||
let rbracket = self
|
||||
.expect("expect ']' after list items", TokenKind::RBracket)?
|
||||
.clone();
|
||||
|
||||
Ok(Box::new(ListExpr {
|
||||
lbracket,
|
||||
exprs,
|
||||
rbracket,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user