2022-09-20 02:59:27 +00:00
|
|
|
use crate::{token::{Token, TokenType, OpType}, ParserError, expr::{Stmt, Expr}, value};
|
2022-09-06 13:52:29 +00:00
|
|
|
|
|
|
|
pub struct Parser {
|
|
|
|
tokens: Vec<Token>,
|
2022-09-07 20:11:51 +00:00
|
|
|
repl: bool,
|
2022-09-06 13:52:29 +00:00
|
|
|
idx: usize
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Parser {
|
2022-09-07 20:11:51 +00:00
|
|
|
pub fn new(tokens: Vec<Token>, repl: bool) -> Self {
|
|
|
|
Self { tokens, repl, idx: 0 }
|
2022-09-06 13:52:29 +00:00
|
|
|
}
|
2022-09-20 02:59:27 +00:00
|
|
|
|
|
|
|
pub fn parse(&mut self) -> Result<Vec<Stmt>, ParserError> {
|
|
|
|
let mut stmts = vec![];
|
|
|
|
while !self.at_end() {
|
|
|
|
stmts.push(self.statement(!self.repl)?);
|
|
|
|
}
|
|
|
|
Ok(stmts)
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////
|
|
|
|
// //
|
|
|
|
// Helper functions //
|
|
|
|
// //
|
|
|
|
////////////////////////
|
2022-09-06 13:52:29 +00:00
|
|
|
|
|
|
|
fn at_end(&self) -> bool {
|
|
|
|
self.idx >= self.tokens.len()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn peek(&self) -> &Token {
|
|
|
|
&self.tokens[self.idx]
|
|
|
|
}
|
|
|
|
|
|
|
|
fn next(&mut self) -> Token {
|
|
|
|
let t = self.tokens[self.idx].clone();
|
|
|
|
self.idx += 1;
|
|
|
|
t
|
|
|
|
}
|
|
|
|
|
2022-09-20 02:59:27 +00:00
|
|
|
fn expect(&mut self, tokty: TokenType) -> (bool, Token) {
|
|
|
|
let next = self.next();
|
|
|
|
(tokty == next.ty, next)
|
|
|
|
}
|
|
|
|
|
2022-09-06 13:52:29 +00:00
|
|
|
fn mk_error<S>(&self, msg: S) -> ParserError where S: Into<String> {
|
|
|
|
let token = if self.at_end() {
|
|
|
|
self.tokens.last().unwrap()
|
|
|
|
} else {
|
|
|
|
self.peek()
|
|
|
|
};
|
|
|
|
ParserError { pos: token.pos.clone(), message: msg.into() }
|
|
|
|
}
|
|
|
|
|
|
|
|
fn err_on_eof(&self) -> Result<(), ParserError> {
|
|
|
|
if self.at_end() {
|
|
|
|
Err(self.mk_error("Unexpected EOF"))
|
|
|
|
} else {
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-20 02:59:27 +00:00
|
|
|
fn ident(&mut self) -> Result<Token, ParserError> {
|
|
|
|
let next = self.next();
|
|
|
|
match next.ty {
|
|
|
|
TokenType::Ident(_) => Ok(next),
|
|
|
|
_ => Err(ParserError { message: "Expected identifier".into(), pos: next.pos })
|
2022-09-06 13:52:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-20 02:59:27 +00:00
|
|
|
fn commalist<T>(&mut self, terminator: TokenType, parse_item: fn(&mut Parser) -> Result<T, ParserError>) -> Result<Vec<T>, ParserError> {
|
|
|
|
let mut items = vec![];
|
|
|
|
while !self.at_end() && self.peek().ty != terminator {
|
|
|
|
let expr = parse_item(self)?;
|
|
|
|
items.push(expr);
|
|
|
|
self.err_on_eof()?;
|
|
|
|
if self.peek().ty == TokenType::Comma {
|
|
|
|
self.next();
|
|
|
|
} else if self.peek().ty == terminator {
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
return Err(self.mk_error(format!("Expected Comma or {:?} after list", terminator)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.err_on_eof()?;
|
|
|
|
self.next();
|
|
|
|
Ok(items)
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////
|
|
|
|
// //
|
|
|
|
// Statements //
|
|
|
|
// //
|
|
|
|
//////////////////
|
|
|
|
|
2022-09-16 20:05:28 +00:00
|
|
|
fn statement(&mut self, req_semicolon: bool) -> Result<Stmt, ParserError> {
|
2022-09-11 05:01:53 +00:00
|
|
|
let next_ty = &self.peek().ty;
|
2022-09-06 13:52:29 +00:00
|
|
|
|
2022-09-11 05:01:53 +00:00
|
|
|
match next_ty {
|
2022-09-06 13:52:29 +00:00
|
|
|
TokenType::Let => {
|
2022-09-07 22:10:43 +00:00
|
|
|
// let statement
|
2022-09-06 13:52:29 +00:00
|
|
|
self.next();
|
2022-09-16 20:05:28 +00:00
|
|
|
self.letstmt(req_semicolon)
|
2022-09-07 22:10:43 +00:00
|
|
|
},
|
2022-09-07 20:11:51 +00:00
|
|
|
TokenType::LBrace => {
|
2022-09-07 22:10:43 +00:00
|
|
|
// block
|
2022-09-07 20:11:51 +00:00
|
|
|
self.next();
|
2022-09-07 22:10:43 +00:00
|
|
|
self.block()
|
|
|
|
},
|
2022-09-06 13:52:29 +00:00
|
|
|
TokenType::If => {
|
2022-09-07 22:10:43 +00:00
|
|
|
// if statement
|
2022-09-06 13:52:29 +00:00
|
|
|
self.next();
|
2022-09-07 22:10:43 +00:00
|
|
|
self.ifstmt()
|
|
|
|
},
|
|
|
|
TokenType::For => {
|
2022-09-09 20:08:40 +00:00
|
|
|
// for loop
|
2022-09-07 22:10:43 +00:00
|
|
|
self.next();
|
|
|
|
self.forstmt()
|
|
|
|
},
|
2022-09-09 20:08:40 +00:00
|
|
|
TokenType::While => {
|
|
|
|
// while loop
|
|
|
|
self.next();
|
|
|
|
self.whilestmt()
|
|
|
|
},
|
2022-09-11 05:01:53 +00:00
|
|
|
TokenType::Break => {
|
|
|
|
let tok = self.next();
|
2022-09-16 20:05:28 +00:00
|
|
|
self.terminate_stmt(Stmt::Break{ pos: tok.pos }, req_semicolon)
|
2022-09-12 20:53:04 +00:00
|
|
|
},
|
2022-09-11 05:01:53 +00:00
|
|
|
TokenType::Continue => {
|
|
|
|
let tok = self.next();
|
2022-09-16 20:05:28 +00:00
|
|
|
self.terminate_stmt(Stmt::Continue{ pos: tok.pos }, req_semicolon)
|
2022-09-12 20:53:04 +00:00
|
|
|
},
|
|
|
|
TokenType::Return => {
|
|
|
|
let tok = self.next();
|
|
|
|
let expr = self.assignment()?;
|
2022-09-16 20:05:28 +00:00
|
|
|
self.terminate_stmt(Stmt::Return{ pos: tok.pos, expr }, req_semicolon)
|
2022-09-12 20:53:04 +00:00
|
|
|
},
|
|
|
|
TokenType::Fn => {
|
2022-09-13 17:31:29 +00:00
|
|
|
self.next();
|
2022-09-12 20:53:04 +00:00
|
|
|
self.fndef()
|
|
|
|
},
|
2022-09-20 02:59:27 +00:00
|
|
|
TokenType::Struct => {
|
|
|
|
self.next();
|
|
|
|
self.structstmt()
|
|
|
|
},
|
2022-09-06 13:52:29 +00:00
|
|
|
_ => {
|
2022-09-07 22:10:43 +00:00
|
|
|
// fallback to an expression terminated with a semicolon
|
2022-09-06 13:52:29 +00:00
|
|
|
let expr = self.assignment()?;
|
2022-09-16 20:05:28 +00:00
|
|
|
self.terminate_stmt(Stmt::Expr{ expr }, req_semicolon)
|
2022-09-11 05:01:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-09-06 13:52:29 +00:00
|
|
|
|
2022-09-16 20:05:28 +00:00
|
|
|
fn terminate_stmt(&mut self, stmt: Stmt, req_semicolon: bool) -> Result<Stmt, ParserError> {
|
|
|
|
if !req_semicolon {
|
|
|
|
return Ok(stmt)
|
|
|
|
}
|
2022-09-11 05:01:53 +00:00
|
|
|
if self.at_end() {
|
2022-09-16 20:05:28 +00:00
|
|
|
self.err_on_eof()?;
|
2022-09-06 13:52:29 +00:00
|
|
|
}
|
2022-09-11 05:01:53 +00:00
|
|
|
|
2022-09-20 02:59:27 +00:00
|
|
|
match self.expect(TokenType::Semicolon) {
|
|
|
|
(true, _) => Ok(stmt),
|
|
|
|
(false, _) => Err(self.mk_error("Missing semicolon after statement"))
|
2022-09-11 05:01:53 +00:00
|
|
|
}
|
|
|
|
|
2022-09-06 13:52:29 +00:00
|
|
|
}
|
|
|
|
|
2022-09-16 20:05:28 +00:00
|
|
|
fn letstmt(&mut self, req_semicolon: bool) -> Result<Stmt, ParserError> {
|
2022-09-07 20:11:51 +00:00
|
|
|
let expr = self.assignment()?;
|
|
|
|
// must be followed by an assignment expression
|
|
|
|
if let Expr::Binary{lhs, rhs, op: Token{ty: TokenType::Equal,..}} = expr {
|
|
|
|
if let Expr::Ident{value: tok} = *lhs {
|
2022-09-16 20:05:28 +00:00
|
|
|
self.terminate_stmt(Stmt::Let{lhs: tok, rhs: Some(*rhs)}, req_semicolon)
|
2022-09-07 20:11:51 +00:00
|
|
|
} else {
|
|
|
|
Err(self.mk_error("Invalid expression after 'let'".to_owned()))
|
|
|
|
}
|
|
|
|
} else if let Expr::Ident{value: tok} = expr {
|
2022-09-16 20:05:28 +00:00
|
|
|
self.terminate_stmt(Stmt::Let{lhs: tok, rhs: None}, req_semicolon)
|
2022-09-07 20:11:51 +00:00
|
|
|
} else {
|
|
|
|
Err(self.mk_error("Invalid expression after 'let'".to_owned()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn ifstmt(&mut self) -> Result<Stmt, ParserError> {
|
|
|
|
let mut if_clauses = vec![];
|
|
|
|
let mut ec = false;
|
|
|
|
loop {
|
|
|
|
let condition = self.assignment()?;
|
2022-09-16 20:05:28 +00:00
|
|
|
let body = self.statement(true)?;
|
2022-09-07 20:11:51 +00:00
|
|
|
if_clauses.push((condition, body));
|
|
|
|
match self.peek().ty {
|
|
|
|
TokenType::Elif => { self.next(); continue },
|
|
|
|
TokenType::Else => { self.next(); ec = true; break },
|
|
|
|
_ => break
|
|
|
|
}
|
|
|
|
}
|
2022-09-11 17:02:18 +00:00
|
|
|
let else_clause = if ec {
|
2022-09-16 20:05:28 +00:00
|
|
|
Some(Box::new(self.statement(true)?))
|
2022-09-07 20:11:51 +00:00
|
|
|
} else {
|
2022-09-11 17:02:18 +00:00
|
|
|
None
|
|
|
|
};
|
|
|
|
Ok(Stmt::If{
|
|
|
|
if_clauses, else_clause
|
2022-09-07 20:11:51 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-09-07 22:10:43 +00:00
|
|
|
fn forstmt(&mut self) -> Result<Stmt, ParserError> {
|
|
|
|
self.err_on_eof()?;
|
|
|
|
let var = self.next();
|
|
|
|
if let TokenType::Ident(_) = &var.ty {
|
|
|
|
self.err_on_eof()?;
|
2022-09-13 17:31:29 +00:00
|
|
|
let colon = self.next();
|
|
|
|
if colon.ty != TokenType::Colon {
|
2022-09-07 22:10:43 +00:00
|
|
|
return Err(self.mk_error("Expected colon"))
|
|
|
|
}
|
|
|
|
self.err_on_eof()?;
|
|
|
|
let expr = self.assignment()?;
|
|
|
|
self.err_on_eof()?;
|
2022-09-16 20:05:28 +00:00
|
|
|
let stmt = self.statement(true)?;
|
2022-09-13 17:31:29 +00:00
|
|
|
Ok(Stmt::For{ var, expr, stmt: Box::new(stmt), iter_pos: colon.pos })
|
2022-09-07 22:10:43 +00:00
|
|
|
} else {
|
|
|
|
Err(self.mk_error("Expected identifier after for"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-09 20:08:40 +00:00
|
|
|
fn whilestmt(&mut self) -> Result<Stmt, ParserError> {
|
|
|
|
self.err_on_eof()?;
|
|
|
|
let expr = self.assignment()?;
|
|
|
|
self.err_on_eof()?;
|
2022-09-16 20:05:28 +00:00
|
|
|
let stmt = self.statement(true)?;
|
2022-09-09 20:08:40 +00:00
|
|
|
Ok(Stmt::While{ expr, stmt: Box::new(stmt) })
|
|
|
|
}
|
|
|
|
|
2022-09-12 20:53:04 +00:00
|
|
|
fn fndef(&mut self) -> Result<Stmt, ParserError> {
|
|
|
|
self.err_on_eof()?;
|
|
|
|
let name = self.next();
|
|
|
|
let name = if let TokenType::Ident(_) = name.ty {
|
|
|
|
name
|
|
|
|
} else {
|
|
|
|
return Err(ParserError { message: "Expected identifer in function declaration".into(), pos: name.pos })
|
|
|
|
};
|
|
|
|
self.err_on_eof()?;
|
2022-09-20 02:59:27 +00:00
|
|
|
if !self.expect(TokenType::LParen).0 {
|
|
|
|
return Err(self.mk_error("Expected left parenthesis to start arguments list"))
|
2022-09-12 20:53:04 +00:00
|
|
|
}
|
2022-09-15 04:01:57 +00:00
|
|
|
let args = self.commalist(TokenType::RParen, Self::ident)?;
|
2022-09-12 20:53:04 +00:00
|
|
|
self.err_on_eof()?;
|
2022-09-16 20:05:28 +00:00
|
|
|
let body = self.statement(false)?;
|
2022-09-12 20:53:04 +00:00
|
|
|
Ok(Stmt::Fn { name, args, body: Box::new(body) })
|
|
|
|
}
|
|
|
|
|
2022-09-07 20:11:51 +00:00
|
|
|
fn block(&mut self) -> Result<Stmt, ParserError> {
|
|
|
|
let mut stmts = vec![];
|
|
|
|
while !self.at_end() && self.peek().ty != TokenType::RBrace {
|
2022-09-16 20:05:28 +00:00
|
|
|
stmts.push(self.statement(true)?)
|
2022-09-07 20:11:51 +00:00
|
|
|
}
|
|
|
|
self.err_on_eof()?;
|
|
|
|
self.next();
|
2022-09-11 17:02:18 +00:00
|
|
|
Ok(Stmt::Block{ stmts })
|
2022-09-07 20:11:51 +00:00
|
|
|
}
|
|
|
|
|
2022-09-20 02:59:27 +00:00
|
|
|
fn structstmt(&mut self) -> Result<Stmt, ParserError> {
|
|
|
|
self.err_on_eof()?;
|
|
|
|
let tok_name = self.ident()?;
|
|
|
|
let name = tok_name.ty.clone().as_ident().unwrap();
|
|
|
|
self.err_on_eof()?;
|
|
|
|
if !self.expect(TokenType::LBrace).0 {
|
|
|
|
return Err(self.mk_error("Expected left brace in struct definition"))
|
|
|
|
}
|
|
|
|
self.err_on_eof()?;
|
|
|
|
let items = self.commalist(TokenType::RBrace, Self::ident)?;
|
|
|
|
let ty = value::generate_type(name);
|
|
|
|
Ok(Stmt::Struct { name: tok_name, ty, items })
|
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////
|
|
|
|
// //
|
|
|
|
// Expressions //
|
|
|
|
// //
|
|
|
|
///////////////////
|
|
|
|
|
2022-09-06 13:52:29 +00:00
|
|
|
// Generic method for left-associative operators
|
|
|
|
fn expr(&mut self, op_type: OpType, next_level: fn(&mut Parser) -> Result<Expr, ParserError>) -> Result<Expr, ParserError> {
|
|
|
|
let mut expr = next_level(self)?;
|
|
|
|
while !self.at_end() && self.peek().ty.get_op_type() == Some(op_type) {
|
|
|
|
let op = self.next();
|
|
|
|
let right = next_level(self)?;
|
|
|
|
expr = Expr::Binary { lhs: Box::new(expr), rhs: Box::new(right), op };
|
|
|
|
}
|
|
|
|
Ok(expr)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn assignment(&mut self) -> Result<Expr, ParserError> {
|
|
|
|
let mut stack= vec![];
|
|
|
|
let mut expr = self.pipeline()?;
|
|
|
|
while !self.at_end() && self.peek().ty.get_op_type() == Some(OpType::Assignment) {
|
|
|
|
let op = self.next();
|
|
|
|
stack.push((expr, op));
|
|
|
|
expr = self.pipeline()?;
|
|
|
|
}
|
|
|
|
while let Some(item) = stack.pop() {
|
|
|
|
if !item.0.is_lvalue() {
|
|
|
|
return Err(self.mk_error("Invalid LValue for assignment operation"))
|
|
|
|
}
|
|
|
|
expr = Expr::Binary{ lhs: Box::new(item.0), rhs: Box::new(expr), op: item.1 };
|
|
|
|
}
|
|
|
|
Ok(expr)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn pipeline(&mut self) -> Result<Expr, ParserError> {
|
2022-09-17 14:54:56 +00:00
|
|
|
let mut expr = self.logical_or()?;
|
|
|
|
while !self.at_end() && self.peek().ty.get_op_type() == Some(OpType::Pipeline) {
|
|
|
|
let op = self.next();
|
|
|
|
let right = self.logical_or()?;
|
|
|
|
if op.ty == TokenType::PipeSlash || op.ty == TokenType::PipeBackslash {
|
2022-09-17 23:23:54 +00:00
|
|
|
self.err_on_eof()?;
|
2022-09-20 02:59:27 +00:00
|
|
|
if !self.expect(TokenType::Comma).0 {
|
2022-09-17 14:54:56 +00:00
|
|
|
return Err(self.mk_error("Expected comma after first argument"))
|
|
|
|
}
|
|
|
|
let right2 = self.logical_or()?;
|
|
|
|
expr = Expr::Ternary { arg1: Box::new(expr), arg2: Box::new(right), arg3: Box::new(right2), op }
|
|
|
|
} else {
|
|
|
|
expr = Expr::Binary { lhs: Box::new(expr), rhs: Box::new(right), op };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(expr)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn logical_or(&mut self) -> Result<Expr, ParserError> {
|
|
|
|
self.expr(OpType::LogicalOr, Self::logical_and)
|
2022-09-11 05:14:54 +00:00
|
|
|
}
|
|
|
|
|
2022-09-17 14:54:56 +00:00
|
|
|
fn logical_and(&mut self) -> Result<Expr, ParserError> {
|
|
|
|
self.expr(OpType::LogicalAnd, Self::comparison)
|
2022-09-09 20:08:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn comparison(&mut self) -> Result<Expr, ParserError> {
|
|
|
|
self.expr(OpType::Comparison, Self::additive)
|
2022-09-06 13:52:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn additive(&mut self) -> Result<Expr, ParserError> {
|
|
|
|
self.expr(OpType::Additive, Self::multiplicative)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn multiplicative(&mut self) -> Result<Expr, ParserError> {
|
|
|
|
self.expr(OpType::Multiplicative, Self::exponential)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Right associative, so cannot use self.expr(..)
|
|
|
|
fn exponential(&mut self) -> Result<Expr, ParserError> {
|
|
|
|
let mut stack= vec![];
|
2022-09-21 03:38:58 +00:00
|
|
|
let mut expr = self.range()?;
|
2022-09-06 13:52:29 +00:00
|
|
|
while !self.at_end() && self.peek().ty == TokenType::Caret {
|
|
|
|
let op = self.next();
|
|
|
|
stack.push((expr, op));
|
2022-09-21 03:38:58 +00:00
|
|
|
expr = self.range()?;
|
2022-09-06 13:52:29 +00:00
|
|
|
}
|
|
|
|
while let Some(item) = stack.pop() {
|
|
|
|
expr = Expr::Binary{ lhs: Box::new(item.0), rhs: Box::new(expr), op: item.1 };
|
|
|
|
}
|
|
|
|
Ok(expr)
|
|
|
|
}
|
|
|
|
|
2022-09-21 03:38:58 +00:00
|
|
|
fn range(&mut self) -> Result<Expr, ParserError> {
|
|
|
|
let start = self.unary()?;
|
|
|
|
if !self.at_end() && self.peek().ty == TokenType::DoubleDot {
|
|
|
|
self.next();
|
|
|
|
// consume = if inclusive
|
|
|
|
let incl = if !self.at_end() && self.peek().ty == TokenType::Equal {
|
|
|
|
self.next();
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
};
|
|
|
|
// consume end number or * for endless
|
|
|
|
let end = if !incl && !self.at_end() && self.peek().ty == TokenType::Star {
|
|
|
|
self.next();
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(self.unary()?)
|
|
|
|
};
|
|
|
|
// consume :step if it exists
|
|
|
|
let step = if !self.at_end() && self.peek().ty == TokenType::Colon {
|
|
|
|
self.next();
|
|
|
|
Some(self.unary()?)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
};
|
|
|
|
Ok(Expr::Range {
|
|
|
|
start: Box::new(start),
|
|
|
|
end: end.map(|x| Box::new(x)),
|
|
|
|
step: step.map(|x| Box::new(x)),
|
|
|
|
incl
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
Ok(start)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-06 13:52:29 +00:00
|
|
|
fn unary(&mut self) -> Result<Expr, ParserError> {
|
|
|
|
self.err_on_eof()?;
|
|
|
|
if matches!(self.peek().ty, TokenType::Bang | TokenType::Minus) {
|
|
|
|
let op = self.next();
|
|
|
|
Ok(Expr::Unary { arg: Box::new(self.fncall()?), op })
|
|
|
|
} else {
|
|
|
|
self.fncall()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn fncall(&mut self) -> Result<Expr, ParserError> {
|
2022-09-10 21:19:23 +00:00
|
|
|
let mut expr = self.expr_base()?;
|
|
|
|
while !self.at_end() {
|
|
|
|
match self.peek().ty {
|
|
|
|
TokenType::LParen => expr = self.fncall_inner(expr)?,
|
|
|
|
TokenType::LBrack => expr = self.arrindex_inner(expr)?,
|
|
|
|
_ => return Ok(expr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(expr)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn fncall_inner(&mut self, expr: Expr) -> Result<Expr, ParserError> {
|
|
|
|
let lparen = self.next();
|
|
|
|
let args = self.commalist(TokenType::RParen, Self::assignment)?;
|
2022-09-11 17:02:18 +00:00
|
|
|
Ok(Expr::FuncCall { func: Box::new(expr), args, pos: lparen.pos })
|
2022-09-10 21:19:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn arrindex_inner(&mut self, expr: Expr) -> Result<Expr, ParserError> {
|
|
|
|
let lbrack = self.next();
|
|
|
|
let index = self.assignment()?;
|
|
|
|
self.err_on_eof()?;
|
2022-09-20 02:59:27 +00:00
|
|
|
if !self.expect(TokenType::RBrack).0 {
|
2022-09-17 14:54:56 +00:00
|
|
|
return Err(self.mk_error("Expected RBrack after collection index"))
|
2022-09-06 13:52:29 +00:00
|
|
|
}
|
2022-09-11 17:02:18 +00:00
|
|
|
Ok(Expr::Index { lhs: Box::new(expr), index: Box::new(index), pos: lbrack.pos })
|
2022-09-06 13:52:29 +00:00
|
|
|
}
|
|
|
|
|
2022-09-15 04:01:57 +00:00
|
|
|
fn kv_pair(&mut self) -> Result<(Expr, Expr), ParserError> {
|
|
|
|
let key = self.assignment()?;
|
|
|
|
self.err_on_eof()?;
|
2022-09-20 02:59:27 +00:00
|
|
|
if !self.expect(TokenType::Colon).0 {
|
2022-09-17 14:54:56 +00:00
|
|
|
return Err(self.mk_error("Expected colon in key-value pair"))
|
2022-09-15 04:01:57 +00:00
|
|
|
}
|
|
|
|
self.err_on_eof()?;
|
|
|
|
let value = self.assignment()?;
|
|
|
|
Ok((key, value))
|
|
|
|
}
|
|
|
|
|
2022-09-06 13:52:29 +00:00
|
|
|
fn expr_base(&mut self) -> Result<Expr, ParserError> {
|
|
|
|
self.err_on_eof()?;
|
|
|
|
let next = self.next();
|
|
|
|
if matches!(next.ty,
|
|
|
|
TokenType::True | TokenType::False | TokenType::Nil
|
|
|
|
| TokenType::Int(_) | TokenType::Float(_) | TokenType::ImFloat(_)
|
2022-09-07 22:10:43 +00:00
|
|
|
| TokenType::String(_) | TokenType::Char(_)
|
2022-09-06 13:52:29 +00:00
|
|
|
) {
|
|
|
|
Ok(Expr::Literal { value: next })
|
|
|
|
} else if let TokenType::Ident(..) = next.ty {
|
|
|
|
Ok(Expr::Ident { value: next })
|
|
|
|
} else if next.ty == TokenType::LParen {
|
|
|
|
let expr = self.assignment()?;
|
|
|
|
if self.at_end() || TokenType::RParen != self.next().ty {
|
|
|
|
Err(self.mk_error("Left parenthesis never closed"))
|
|
|
|
} else {
|
|
|
|
Ok(expr)
|
|
|
|
}
|
2022-09-09 20:08:40 +00:00
|
|
|
} else if next.ty == TokenType::LBrack {
|
|
|
|
let items = self.commalist(TokenType::RBrack, Self::assignment)?;
|
|
|
|
Ok(Expr::List { items })
|
2022-09-15 04:01:57 +00:00
|
|
|
} else if next.ty == TokenType::LBrace {
|
|
|
|
let items = self.commalist(TokenType::RBrace, Self::kv_pair)?;
|
|
|
|
Ok(Expr::Map { items })
|
2022-09-12 20:53:04 +00:00
|
|
|
} else if next.ty == TokenType::Fn {
|
|
|
|
self.err_on_eof()?;
|
2022-09-20 02:59:27 +00:00
|
|
|
if !self.expect(TokenType::LParen).0 {
|
2022-09-17 14:54:56 +00:00
|
|
|
return Err(self.mk_error("Expected left parenthesis to start arguments list"))
|
2022-09-12 20:53:04 +00:00
|
|
|
}
|
2022-09-15 04:01:57 +00:00
|
|
|
let args = self.commalist(TokenType::RParen, Self::ident)?;
|
2022-09-12 20:53:04 +00:00
|
|
|
self.err_on_eof()?;
|
2022-09-16 20:05:28 +00:00
|
|
|
let body = self.statement(false)?;
|
2022-09-12 20:53:04 +00:00
|
|
|
Ok(Expr::Fn { args, body: Box::new(body) })
|
2022-09-06 13:52:29 +00:00
|
|
|
} else {
|
|
|
|
Err(self.mk_error(format!("Unexpected token: {:?}", next.ty)))
|
|
|
|
}
|
|
|
|
}
|
2022-09-11 17:02:18 +00:00
|
|
|
}
|