use crate::ast::{ASTType, BinOp, Lit, UnOp, AST}; use crate::{ ast::{LhsAssign, LhsAssignType}, ast_from_ast, ast_from_ast_token, ast_from_token, ast_from_token_ast, collect_lines, error::{ErrorKind, KabelError}, lexer::{Token, TokenType}, lit, name, unexpected_token, }; pub struct Parser { input: Vec, text: Vec, current: usize, token: Token, pub errors: Vec, } impl Parser { pub fn new(text: String, input: Vec) -> Self { Self { input: input.clone(), text: text .lines() .collect::>() .iter() .map(|s| s.to_string()) .collect(), current: 0, token: input[0].clone(), errors: Vec::new(), } } pub fn program(&mut self) -> AST { let mut program = Vec::new(); loop { if self.current >= self.input.len() { break; } match self.statement() { Ok(ast) => program.push(ast), Err(e) => self.errors.push(e), } } AST { kind: ASTType::Program(program), extensions: Vec::new(), start_line: 0, end_line: 0, start_column: 0, end_column: 0, } } pub fn statement(&mut self) -> Result { match self.peek()?.token_type { TokenType::Function => self.function_statement(), TokenType::Return => self.return_statement(), TokenType::Loop => self.loop_statement(), TokenType::While => self.while_statement(), TokenType::For => self.for_statement(), TokenType::Break => self.break_statement(), TokenType::Continue => self.continue_statement(), TokenType::If => self.if_statement(), TokenType::LeftBrace => self.block(), TokenType::Var => self.declaration(), TokenType::Print => self.print_statement(), // REMOVE LATER _ => self.expression_statement(), } } pub fn function_statement(&mut self) -> Result { let function_ident = self.read_token()?; let ident = self.read_token()?; if let TokenType::Ident(name) = ident.token_type { let left_paren = self.read_token()?; if let TokenType::LeftParen = left_paren.token_type { let mut expressions = Vec::new(); while self.peek()?.token_type != TokenType::RightParen { let ident = self.read_token()?; if let TokenType::Ident(name) = ident.token_type { expressions.push(name!(name, ident)); } else { return Err(unexpected_token!( self, "Expected identifier but found {}", ident )); } if let TokenType::Comma = self.peek()?.token_type { self.read_token()?; } } let right_paren = self.read_token()?; if let TokenType::RightParen = right_paren.token_type { let block = self.block()?; return Ok(ast_from_token_ast!( AST, ASTType::Function(name!(name, ident), expressions, Box::new(block.clone())), function_ident, block )); } else { return Err(unexpected_token!( self, "Expected ) but found {}", right_paren )); } } else { return Err(unexpected_token!( self, "Expected ( but found {}", left_paren )); } } else { return Err(unexpected_token!( self, "Expected identifier but found {}", ident )); } } pub fn return_statement(&mut self) -> Result { let return_ident = self.read_token()?; if let TokenType::Semicolon = self.peek()?.token_type { let semicolon = self.read_token()?; return Ok(ast_from_token!( AST, ASTType::Return(Box::new(None)), return_ident, semicolon )); } let expression = self.expression()?; let semicolon = self.read_token()?; if let TokenType::Semicolon = semicolon.token_type { Ok(ast_from_token!( AST, ASTType::Return(Box::new(Some(expression))), return_ident, semicolon )) } else { return Err(unexpected_token!( self, "Expected ; but found {}", semicolon )); } } pub fn loop_statement(&mut self) -> Result { let loop_ident = self.read_token()?; let block = self.block()?; Ok(ast_from_token_ast!( AST, ASTType::Loop(Box::new(block.clone())), loop_ident, block )) } pub fn while_statement(&mut self) -> Result { let while_ident = self.read_token()?; let left_paren = self.read_token()?; if let TokenType::LeftParen = left_paren.token_type { let condition = self.expression()?; let right_paren = self.read_token()?; if let TokenType::RightParen = right_paren.token_type { let block = self.block()?; return Ok(ast_from_token_ast!( AST, ASTType::While(Box::new(condition), Box::new(block.clone())), while_ident, block )); } else { return Err(unexpected_token!( self, "Expected ) but found {}", right_paren )); } } else { return Err(unexpected_token!( self, "Expected ( but found {}", left_paren )); } } pub fn for_statement(&mut self) -> Result { let for_ident = self.read_token()?; let left_paren = self.read_token()?; if let TokenType::LeftParen = left_paren.token_type { let expression1; if let TokenType::Semicolon = self.peek()?.token_type { expression1 = None; } else if let TokenType::Var = self.peek()?.token_type { expression1 = Some(self.declaration()?); } else { expression1 = Some(self.expression()?); let semicolon = self.read_token()?; if let TokenType::Semicolon = semicolon.token_type { } else { self.current -= 1; return Err(unexpected_token!( self, "Expected ; but found {}", semicolon )); } } let expression2; if let TokenType::Semicolon = self.peek()?.token_type { expression2 = None; } else { expression2 = Some(self.expression()?); } let semicolon_2 = self.read_token()?; if let TokenType::Semicolon = semicolon_2.token_type { let expression3; if let TokenType::RightParen = self.peek()?.token_type { expression3 = None; } else { expression3 = Some(self.expression()?); } let right_paren = self.read_token()?; if let TokenType::RightParen = right_paren.token_type { let block = self.block()?; //return Ok(Self::build_for(for_ident, semicolon_2, expression1, expression2, expression3, block)); return Ok(ast_from_token_ast!( AST, ASTType::For( Box::new(expression1), Box::new(expression2), Box::new(expression3), Box::new(block.clone()) ), for_ident, block )); } else { return Err(unexpected_token!( self, "Expected ) but found {}", right_paren )); } } else { return Err(unexpected_token!( self, "Expected ; but found {}", semicolon_2 )); } } else { return Err(unexpected_token!( self, "Expected ( but found {}", left_paren )); } } /*fn build_for(for_ident: Token, semicolon_2: Token, expression1: Option, expression2: Option, expression3: Option, block: AST) -> AST { let mut outer_block = Vec::new(); if let Some(expression1) = expression1.clone() { outer_block.push(expression1); } let mut new_block = block.clone(); if let Some(expression3) = expression3 { if let ASTType::Block(inner) = block.clone().kind { let mut new_inner = inner; new_inner.push(ast_from_ast!(ASTType::Expr(Box::new(expression3.clone())), expression3, expression3)); new_block = ast_from_ast!(ASTType::Block(new_inner), block, block); } } let condition = if let Some(expression2) = expression2 { expression2 } else { lit!(Bool, true, semicolon_2) }; let while_ast = ast_from_ast!(ASTType::While(Box::new(condition.clone()), Box::new(new_block.clone())), condition, block); outer_block.push(while_ast.clone()); let outer_block = ast_from_token_ast!(ASTType::Block(outer_block), for_ident, new_block); outer_block }*/ pub fn break_statement(&mut self) -> Result { let break_ident = self.read_token()?; let semicolon = self.read_token()?; if let TokenType::Semicolon = semicolon.token_type { Ok(ast_from_token!(AST, ASTType::Break, break_ident, semicolon)) } else { Err(unexpected_token!( self, "Expected ; but found {}", semicolon )) } } pub fn continue_statement(&mut self) -> Result { let continue_ident = self.read_token()?; let semicolon = self.read_token()?; if let TokenType::Semicolon = semicolon.token_type { Ok(ast_from_token!( AST, ASTType::Continue, continue_ident, semicolon )) } else { Err(unexpected_token!( self, "Expected ; but found {}", semicolon )) } } pub fn if_statement(&mut self) -> Result { let if_ident = self.read_token()?; let left_paren = self.read_token()?; if let TokenType::LeftParen = left_paren.token_type { let condition = self.expression()?; let right_paren = self.read_token()?; if let TokenType::RightParen = right_paren.token_type { let block = self.block()?; if self.current < self.input.len() { let else_ident = self.peek()?; if let TokenType::Else = else_ident.token_type { self.read_token()?; if let TokenType::LeftBrace = self.peek()?.token_type { let else_block = self.block()?; return Ok(ast_from_token_ast!( AST, ASTType::If( Box::new(condition), Box::new(block.clone()), Box::new(Some(else_block.clone())) ), if_ident, else_block )); } let else_if_ident = self.peek()?; if let TokenType::If = else_if_ident.token_type { let else_if = self.if_statement()?; return Ok(ast_from_token_ast!( AST, ASTType::If( Box::new(condition), Box::new(block.clone()), Box::new(Some(else_if.clone())) ), if_ident, else_if )); } return Err(unexpected_token!(self, "Unexpected token {}", else_ident)); } } return Ok(ast_from_token_ast!( AST, ASTType::If(Box::new(condition), Box::new(block.clone()), Box::new(None)), if_ident, block )); } else { return Err(unexpected_token!( self, "Expected ) but found {}", right_paren )); } } else { return Err(unexpected_token!( self, "Expected ( but found {}", left_paren )); } } pub fn block(&mut self) -> Result { let left_brace = self.read_token()?; if let TokenType::LeftBrace = left_brace.token_type { let mut stmts = Vec::new(); while self.peek()?.token_type != TokenType::RightBrace { stmts.push(self.statement()?); } let right_brace = self.read_token()?; return Ok(ast_from_token!( AST, ASTType::Block(stmts), left_brace, right_brace )); } else { return Err(unexpected_token!( self, "Expected {{ but found {}", left_brace )); } } pub fn declaration(&mut self) -> Result { let var = self.read_token()?; let ident = self.read_token()?; if let TokenType::Ident(name) = ident.token_type { let equal = self.read_token()?; if let TokenType::Equal = equal.token_type { let expr = self.expression()?; let semicolon = self.read_token()?; if let TokenType::Semicolon = semicolon.token_type { return Ok(ast_from_token!( AST, ASTType::Decl(name!(name, ident), Box::new(expr.clone())), var, semicolon )); } else { return Err(unexpected_token!(self, "Expected ; but found {}", equal)); } } else { return Err(unexpected_token!(self, "Expected = but found {}", equal)); } } else { return Err(unexpected_token!( self, "Expected identifier but found {}", ident )); } } // REMOVE LATER pub fn print_statement(&mut self) -> Result { let print_ident = self.read_token()?; let expression = self.expression()?; let semicolon = self.read_token()?; if matches!(semicolon.token_type, TokenType::Semicolon) { Ok(ast_from_token!( AST, ASTType::Print(Box::new(expression)), print_ident, semicolon )) } else { Err(unexpected_token!( self, "Expected ; but found {}", semicolon )) } } pub fn expression_statement(&mut self) -> Result { let expression = self.expression()?; if self.current >= self.input.len() { let last = self.input.last().unwrap(); return Err(KabelError::new( ErrorKind::UnexpectedEof, "Unexpected end of file, expected ;".to_string(), None, expression.start_line, last.end_column, self.text[last.line].to_string(), )); } let semicolon = self.read_token()?; if let TokenType::Semicolon = semicolon.token_type { return Ok(ast_from_ast_token!( AST, ASTType::Expr(Box::new(expression.clone())), expression, semicolon )); } else { self.current -= 1; return Err(unexpected_token!( self, "Expected ; but found {}", semicolon )); } } pub fn expression(&mut self) -> Result { let assignment = self.assignment()?; Ok(assignment) } pub fn assignment(&mut self) -> Result { if let TokenType::Ident(name) = self.peek()?.token_type { let ident = self.read_token()?; let lhs_type; if let TokenType::LeftSquare = self.peek()?.token_type { self.read_token()?; let index = self.expression()?; let right_square = self.read_token()?; lhs_type = ast_from_token!( LhsAssign, LhsAssignType::Subscript( Box::new(lit!(Ident, name.clone(), ident)), Box::new(index) ), ident, right_square ); } else { lhs_type = ast_from_token!(LhsAssign, LhsAssignType::Ident(name.clone()), ident, ident); } if self.current >= self.input.len() { self.current -= 1; return self.ternary(); } if let TokenType::Equal | TokenType::PlusEqual | TokenType::MinusEqual | TokenType::StarEqual | TokenType::SlashEqual | TokenType::PercentEqual | TokenType::AndEqual | TokenType::CaretEqual | TokenType::OrEqual = self.peek()?.token_type { let binop = self.read_token()?; let expr = self.expression()?; if binop.token_type == TokenType::Equal { return Ok(ast_from_token_ast!( AST, ASTType::Assign(lhs_type, Box::new(expr.clone())), ident, expr )); } else if binop.token_type == TokenType::PlusEqual { return Ok(ast_from_token_ast!( AST, ASTType::Assign( lhs_type, Box::new( ast_from_ast!( AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::Add, Box::new(expr.clone()) ), expr, expr ) .clone() ) ), ident, expr )); } else if binop.token_type == TokenType::MinusEqual { return Ok(ast_from_token_ast!( AST, ASTType::Assign( lhs_type, Box::new( ast_from_ast!( AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::Sub, Box::new(expr.clone()) ), expr, expr ) .clone() ) ), ident, expr )); } else if binop.token_type == TokenType::StarEqual { return Ok(ast_from_token_ast!( AST, ASTType::Assign( lhs_type, Box::new( ast_from_ast!( AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::Mul, Box::new(expr.clone()) ), expr, expr ) .clone() ) ), ident, expr )); } else if binop.token_type == TokenType::SlashEqual { return Ok(ast_from_token_ast!( AST, ASTType::Assign( lhs_type, Box::new( ast_from_ast!( AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::Div, Box::new(expr.clone()) ), expr, expr ) .clone() ) ), ident, expr )); } else if binop.token_type == TokenType::PercentEqual { return Ok(ast_from_token_ast!( AST, ASTType::Assign( lhs_type, Box::new( ast_from_ast!( AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::Mod, Box::new(expr.clone()) ), expr, expr ) .clone() ) ), ident, expr )); } else if binop.token_type == TokenType::AndEqual { return Ok(ast_from_token_ast!( AST, ASTType::Assign( lhs_type, Box::new( ast_from_ast!( AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::BitAnd, Box::new(expr.clone()) ), expr, expr ) .clone() ) ), ident, expr )); } else if binop.token_type == TokenType::CaretEqual { return Ok(ast_from_token_ast!( AST, ASTType::Assign( lhs_type, Box::new( ast_from_ast!( AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::BitXor, Box::new(expr.clone()) ), expr, expr ) .clone() ) ), ident, expr )); } else { return Ok(ast_from_token_ast!( AST, ASTType::Assign( lhs_type, Box::new( ast_from_ast!( AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::BitOr, Box::new(expr.clone()) ), expr, expr ) .clone() ) ), ident, expr )); } } self.current -= 1; return self.anonymous_function(); } return self.anonymous_function(); } pub fn anonymous_function(&mut self) -> Result { if let TokenType::LeftParen = self.peek()?.token_type { let left_paren = self.read_token()?; match self.peek()?.token_type { TokenType::Ident(name) => { let param = self.read_token()?; if matches!(self.peek()?.token_type, TokenType::Comma) { self.read_token()?; let mut params = vec![name!(name, param)]; while self.peek()?.token_type != TokenType::RightParen { let ident = self.read_token()?; if let TokenType::Ident(name) = ident.token_type { params.push(name!(name, ident)); } else { return Err(unexpected_token!( self, "Expected identifier but found {}", ident )); } if let TokenType::Comma = self.peek()?.token_type { self.read_token()?; } } self.read_token()?; // right paren if let TokenType::Arrow = self.peek()?.token_type { self.read_token()?; if let TokenType::LeftBrace = self.peek()?.token_type { let block = self.block()?; return Ok(ast_from_token_ast!( AST, ASTType::Anonymous(params, Box::new(block.clone())), left_paren, block )); } else { let left_brace = self.read_token()?; return Err(unexpected_token!( self, "Expected {{ but found {}", left_brace )); } } else { let arrow = self.read_token()?; return Err(unexpected_token!(self, "Expected => but found {}", arrow)); } } else if matches!(self.peek()?.token_type, TokenType::RightParen) { self.read_token()?; // right paren let params = vec![name!(name, param)]; if let TokenType::Arrow = self.peek()?.token_type { self.read_token()?; if let TokenType::LeftBrace = self.peek()?.token_type { let block = self.block()?; return Ok(ast_from_token_ast!( AST, ASTType::Anonymous(params, Box::new(block.clone())), left_paren, block )); } else { let left_brace = self.read_token()?; return Err(unexpected_token!( self, "Expected {{ but found {}", left_brace )); } } else { let arrow = self.read_token()?; return Err(unexpected_token!(self, "Expected => but found {}", arrow)); } } else { self.current -= 1; return self.group(left_paren); } } TokenType::RightParen => { self.read_token()?; // right paren if let TokenType::Arrow = self.peek()?.token_type { self.read_token()?; let block = self.block()?; return Ok(ast_from_token_ast!( AST, ASTType::Anonymous(Vec::new(), Box::new(block.clone())), left_paren, block )); } else { let arrow = self.read_token()?; return Err(unexpected_token!(self, "Expected => but found {}", arrow)); } } _ => { return self.group(left_paren); } } } return self.ternary(); } pub fn ternary(&mut self) -> Result { let condition = self.logical_or()?; if let TokenType::Question = self.peek()?.token_type { self.read_token()?; let true_expr = self.expression()?; if let TokenType::Colon = self.peek()?.token_type { self.read_token()?; let false_expr = self.expression()?; return Ok(ast_from_ast!( AST, ASTType::Ternary( Box::new(condition.clone()), Box::new(true_expr), Box::new(false_expr.clone()) ), condition, false_expr )); } else { return Err(unexpected_token!( self, "Expected : but found {}", self.token )); } } Ok(condition) } pub fn logical_or(&mut self) -> Result { let mut left = self.logical_and()?; while self.current < self.input.len() && self.peek()?.token_type == TokenType::OrOr { self.read_token()?; let right = self.logical_and()?; left = ast_from_ast!( AST, ASTType::Binary(Box::new(left.clone()), BinOp::Or, Box::new(right.clone())), left, right ); } Ok(left) } pub fn logical_and(&mut self) -> Result { let mut left = self.bit_and()?; while self.current < self.input.len() && self.peek()?.token_type == TokenType::AndAnd { self.read_token()?; let right = self.bit_and()?; left = ast_from_ast!( AST, ASTType::Binary(Box::new(left.clone()), BinOp::And, Box::new(right.clone())), left, right ); } Ok(left) } pub fn bit_and(&mut self) -> Result { let mut left = self.bit_xor()?; while self.current < self.input.len() && self.peek()?.token_type == TokenType::And { self.read_token()?; let right = self.bit_xor()?; left = ast_from_ast!( AST, ASTType::Binary( Box::new(left.clone()), BinOp::BitAnd, Box::new(right.clone()) ), left, right ); } Ok(left) } pub fn bit_xor(&mut self) -> Result { let mut left = self.bit_or()?; while self.current < self.input.len() && self.peek()?.token_type == TokenType::Caret { self.read_token()?; let right = self.bit_or()?; left = ast_from_ast!( AST, ASTType::Binary( Box::new(left.clone()), BinOp::BitXor, Box::new(right.clone()) ), left, right ); } Ok(left) } pub fn bit_or(&mut self) -> Result { let mut left = self.equality()?; while self.current < self.input.len() && self.peek()?.token_type == TokenType::Or { self.read_token()?; let right = self.equality()?; left = ast_from_ast!( AST, ASTType::Binary( Box::new(left.clone()), BinOp::BitOr, Box::new(right.clone()) ), left, right ); } Ok(left) } pub fn equality(&mut self) -> Result { let mut left = self.comparison()?; while self.current < self.input.len() && (self.peek()?.token_type == TokenType::EqualEqual || self.peek()?.token_type == TokenType::BangEqual) { let binop = self.read_token()?; let right = self.comparison()?; if binop.token_type == TokenType::EqualEqual { left = ast_from_ast!( AST, ASTType::Binary(Box::new(left.clone()), BinOp::Eq, Box::new(right.clone())), left, right ); } else { left = ast_from_ast!( AST, ASTType::Binary(Box::new(left.clone()), BinOp::Ne, Box::new(right.clone())), left, right ); } } Ok(left) } pub fn comparison(&mut self) -> Result { let mut left = self.term()?; while self.current < self.input.len() && (self.peek()?.token_type == TokenType::Less || self.peek()?.token_type == TokenType::LessEqual || self.peek()?.token_type == TokenType::Greater || self.peek()?.token_type == TokenType::GreaterEqual) { let binop = self.read_token()?; let right = self.term()?; if binop.token_type == TokenType::Less { left = ast_from_ast!( AST, ASTType::Binary(Box::new(left.clone()), BinOp::Ls, Box::new(right.clone())), left, right ); } else if binop.token_type == TokenType::LessEqual { left = ast_from_ast!( AST, ASTType::Binary(Box::new(left.clone()), BinOp::Le, Box::new(right.clone())), left, right ); } else if binop.token_type == TokenType::Greater { left = ast_from_ast!( AST, ASTType::Binary(Box::new(left.clone()), BinOp::Gr, Box::new(right.clone())), left, right ); } else { left = ast_from_ast!( AST, ASTType::Binary(Box::new(left.clone()), BinOp::Ge, Box::new(right.clone())), left, right ); } } Ok(left) } pub fn term(&mut self) -> Result { let mut left = self.factor()?; while self.current < self.input.len() && (self.peek()?.token_type == TokenType::Plus || self.peek()?.token_type == TokenType::Minus) { let binop = self.read_token()?; let right = self.factor()?; if binop.token_type == TokenType::Plus { left = ast_from_ast!( AST, ASTType::Binary(Box::new(left.clone()), BinOp::Add, Box::new(right.clone())), left, right ); } else { left = ast_from_ast!( AST, ASTType::Binary(Box::new(left.clone()), BinOp::Sub, Box::new(right.clone())), left, right ); } } Ok(left) } pub fn factor(&mut self) -> Result { let mut left = self.unary()?; while self.current < self.input.len() && (self.peek()?.token_type == TokenType::Star || self.peek()?.token_type == TokenType::Slash || self.peek()?.token_type == TokenType::Percent) { let binop = self.read_token()?; let right = self.unary()?; if binop.token_type == TokenType::Star { left = ast_from_ast!( AST, ASTType::Binary(Box::new(left.clone()), BinOp::Mul, Box::new(right.clone())), left, right ); } else if binop.token_type == TokenType::Slash { left = ast_from_ast!( AST, ASTType::Binary(Box::new(left.clone()), BinOp::Div, Box::new(right.clone())), left, right ); } else { left = ast_from_ast!( AST, ASTType::Binary(Box::new(left.clone()), BinOp::Mod, Box::new(right.clone())), left, right ); } } Ok(left) } pub fn unary(&mut self) -> Result { if let TokenType::Bang | TokenType::Minus = self.peek()?.token_type { let token = self.read_token()?; let unary = self.unary()?; if token.token_type == TokenType::Bang { return Ok(ast_from_token_ast!( AST, ASTType::Unary(UnOp::Not, Box::new(unary.clone())), token, unary )); } else { return Ok(ast_from_token_ast!( AST, ASTType::Unary(UnOp::Neg, Box::new(unary.clone())), token, unary )); } } self.subscript() } pub fn subscript(&mut self) -> Result { let mut primary = self.primary()?; while self.current < self.input.len() && self.peek()?.token_type == TokenType::LeftSquare { self.read_token()?; let expr = self.expression()?; let right_brace = self.read_token()?; if let TokenType::RightSquare = right_brace.token_type { primary = ast_from_ast_token!( AST, ASTType::Subscript(Box::new(primary.clone()), Box::new(expr)), primary, right_brace ); } else { return Err(unexpected_token!( self, "Expected ] but found {}", right_brace )); } } Ok(primary) } pub fn primary(&mut self) -> Result { let token = self.read_token()?; match token.token_type { TokenType::Ident(ref ident) => { if self.current < self.input.len() { if let TokenType::LeftParen = self.peek()?.token_type { return self.call(token); } if let TokenType::Period = self.peek()?.token_type { return self.member(token); } if let TokenType::PlusPlus | TokenType::MinusMinus = self.peek()?.token_type { return self.incdec(token); } } return Ok(lit!(Ident, ident.clone(), token)); } TokenType::Num(num) => { return Ok(lit!(Num, num, token)); } TokenType::Str(string) => { return Ok(lit!(Str, string, token)); } TokenType::True => return Ok(lit!(Bool, true, token)), TokenType::False => return Ok(lit!(Bool, false, token)), TokenType::LeftParen => { return self.group(token); } TokenType::LeftSquare => { return self.array(token); } _ => { return Err(unexpected_token!(self, "Unexpected token {}", token)); } } } pub fn array(&mut self, left_square: Token) -> Result { let mut expressions = Vec::new(); while self.peek()?.token_type != TokenType::RightSquare { expressions.push(self.expression()?); if let TokenType::Comma = self.peek()?.token_type { self.read_token()?; } } let right_square = self.read_token()?; Ok(ast_from_token!( AST, ASTType::Lit(Lit::Array(expressions)), left_square, right_square )) } pub fn member(&mut self, ident: Token) -> Result { if let TokenType::Ident(first) = ident.token_type { let mut expr: AST = lit!(Ident, first, ident); while self.peek()?.token_type == TokenType::Period { self.read_token()?; let child = self.read_token()?; if let TokenType::Ident(child_str) = child.clone().token_type { if self.current < self.input.len() { if let TokenType::LeftParen = self.peek()?.token_type { let call = self.call(child)?; expr = ast_from_ast!( AST, ASTType::Member(Box::new(expr.clone()), Box::new(call.clone())), expr, call ); if self.current >= self.input.len() { break; } continue; } } expr = ast_from_ast_token!( AST, ASTType::Member( Box::new(expr.clone()), Box::new(lit!(Ident, child_str, child)) ), expr, child ); } else { return Err(unexpected_token!(self, "Unexpected token {}", child)); } if self.current >= self.input.len() { break; } } return Ok(expr); } panic!("Bad member logic"); } pub fn call(&mut self, ident: Token) -> Result { self.read_token()?; let mut expressions = Vec::new(); while self.peek()?.token_type != TokenType::RightParen { expressions.push(self.expression()?); if let TokenType::Comma = self.peek()?.token_type { self.read_token()?; } } let right_paren = self.read_token()?; if let TokenType::Ident(name) = ident.token_type { return Ok(ast_from_token!( AST, ASTType::Call(Box::new(lit!(Ident, name, ident)), expressions), ident, right_paren )); } panic!("Call logic broke"); } pub fn incdec(&mut self, ident: Token) -> Result { if let TokenType::Ident(name) = ident.token_type { let oper = self.read_token()?; if oper.token_type == TokenType::PlusPlus { return Ok(ast_from_token!( AST, ASTType::Assign( ast_from_token!( LhsAssign, LhsAssignType::Ident(name.clone()), ident, ident ), Box::new(ast_from_token!( AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::Add, Box::new(lit!(Num, 1., oper)) ), oper, oper )) ), ident, oper )); } else { return Ok(ast_from_token!( AST, ASTType::Assign( ast_from_token!( LhsAssign, LhsAssignType::Ident(name.clone()), ident, ident ), Box::new(ast_from_token!( AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::Sub, Box::new(lit!(Num, 1., oper)) ), oper, oper )) ), ident, oper )); } } panic!("Inc/dec logic broke"); } pub fn group(&mut self, left_paren: Token) -> Result { let expr = self.expression()?; let right_paren = self.peek(); if let Ok(right_paren) = right_paren { if right_paren.token_type != TokenType::RightParen { return Err(KabelError::new( ErrorKind::MissingDelimiter, "Missing right parenthesis".to_string(), None, right_paren.line, right_paren.start_column, self.text[left_paren.line..right_paren.line] .iter() .fold("".to_string(), |acc, string| acc + string + "\n"), )); } self.read_token()?; return Ok(ast_from_token!(AST, expr.kind, left_paren, right_paren)); } if let Err(e) = right_paren { return Err(KabelError::new( ErrorKind::MissingDelimiter, "Missing right parenthesis".to_string(), None, e.line, e.column, collect_lines!(self.text[left_paren.line..expr.end_line]), )); } unreachable!(); } pub fn read_token(&mut self) -> Result { if self.current >= self.input.len() { let last_token = self.input[self.input.len() - 1].clone(); return Err(KabelError::new( ErrorKind::UnexpectedEof, "Unexpected end of file".to_string(), None, last_token.line, last_token.start_column, self.text[last_token.line].clone(), )); } self.token = self.input[self.current].clone(); self.current += 1; return Ok(self.token.clone()); } pub fn peek(&mut self) -> Result { if self.current >= self.input.len() { let last_token = self.input[self.input.len() - 1].clone(); return Err(KabelError::new( ErrorKind::UnexpectedEof, "Unexpected end of file".to_string(), None, last_token.line, last_token.start_column, self.text[last_token.line].clone(), )); } return Ok(self.input[self.current].clone()); } }