Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use crate::token::*;
- use crate::grammar::*;
- use crate::error::*;
- use std::rc::Rc;
- struct TokenExplorer {
- tokens: Vec<Token>,
- current: usize,
- }
- impl TokenExplorer {
- fn match_next(&mut self, types: Vec<TokenType>) -> bool {
- for tt in types {
- if self.check(tt) {
- self.advance();
- return true;
- }
- }
- false
- }
- fn check(&mut self, tt: TokenType) -> bool {
- if self.is_at_end() {
- false
- } else {
- self.peek().token_type == tt
- }
- }
- fn advance(&mut self) -> &Token {
- if !self.is_at_end() {
- self.current += 1;
- }
- self.previous()
- }
- fn is_at_end(&mut self) -> bool {
- self.peek().token_type == TokenType::EOF
- }
- fn peek(&mut self) -> &Token {
- self.tokens.get(self.current).unwrap()
- }
- fn previous(&mut self) -> &Token {
- self.tokens.get(self.current - 1).unwrap()
- }
- fn consume(&mut self, tt: TokenType, message: &str) -> Result<&Token, LoxError> {
- if self.check(tt) {
- Ok(self.advance())
- } else {
- Err(Self::error(self.peek(), message))
- }
- }
- fn error(token: &Token, message: &str) -> LoxError {
- if token.token_type == TokenType::EOF {
- LoxError::new(token.line, String::from(" at end"), String::from(message))
- } else {
- LoxError::new(token.line, String::from(format!(" at '{}'", &token.lexeme)), String::from(message))
- }
- }
- fn synchronize(&mut self) {
- self.advance();
- while !self.is_at_end() {
- if self.previous().token_type == TokenType::Semicolon {
- return;
- }
- match self.peek().token_type {
- TokenType::Class |
- TokenType::Fun |
- TokenType::Var |
- TokenType::For |
- TokenType::If |
- TokenType::While |
- TokenType::Print |
- TokenType::Return => {
- return;
- },
- _ => ()
- }
- self.advance();
- }
- }
- }
- struct Parser {
- tokens: TokenExplorer,
- }
- impl Parser {
- pub fn new(tokens: Vec<Token>) -> Parser {
- Parser {
- tokens: TokenExplorer {
- tokens: tokens,
- current: 0,
- }
- }
- }
- fn expression(&mut self) -> Rc<dyn Expr> {
- self.equality()
- }
- fn equality(&mut self) -> Rc<dyn Expr> {
- let mut expr = self.comparison();
- while self.tokens.match_next(vec![TokenType::BangEqual, TokenType::EqualEqual]) {
- // ==============================================================
- // Error occurs here (and similarly in the other functions below)
- // cannot borrow \`*self\` as mutable more than once at a time
- let operator = self.tokens.previous();
- // ----------- first mutable borrow occurs here
- let right = self.comparison();
- // ^^^^ second mutable borrow occurs here
- expr = Rc::new(Binary {
- left: expr,
- operator: *operator,
- // -------- first borrow later used here
- right: right,
- });
- }
- expr
- }
- fn comparison(&mut self) -> Rc<dyn Expr> {
- let mut expr = self.addition();
- while self.tokens.match_next(vec![TokenType::Greater, TokenType::GreaterEqual, TokenType::Less, TokenType::LessEqual]) {
- let operator = self.tokens.previous();
- let right = self.addition();
- expr = Rc::new(Binary {
- left: expr,
- operator: *operator,
- right,
- });
- }
- expr
- }
- fn addition(&mut self) -> Rc<dyn Expr> {
- let mut expr = self.multiplication();
- while self.tokens.match_next(vec![TokenType::Minus, TokenType::Plus]) {
- let operator = self.tokens.previous();
- let right = self.multiplication();
- expr = Rc::new(Binary {
- left: expr,
- operator: *operator,
- right,
- });
- }
- expr
- }
- fn multiplication(&mut self) -> Rc<dyn Expr> {
- let mut expr = self.unary();
- while self.tokens.match_next(vec![TokenType::Slash, TokenType::Star]) {
- let operator = self.tokens.previous();
- let right = self.unary();
- expr = Rc::new(Binary {
- left: expr,
- operator: *operator,
- right,
- });
- }
- expr
- }
- fn unary(&mut self) -> Rc<dyn Expr> {
- if self.tokens.match_next(vec![TokenType::Bang, TokenType::Minus]) {
- let operator = self.tokens.previous();
- let right = self.unary();
- return Rc::new(Unary {
- operator: *operator,
- right,
- });
- }
- self.primary()
- }
- fn primary(&mut self) -> Rc<dyn Expr> {
- if self.tokens.match_next(vec![TokenType::False]) {
- return Rc::new(Literal {
- value: LiteralType::Bool(false)
- });
- } else if self.tokens.match_next(vec![TokenType::True]) {
- return Rc::new(Literal {
- value: LiteralType::Bool(true)
- });
- } else if self.tokens.match_next(vec![TokenType::Nil]) {
- return Rc::new(Literal {
- value: LiteralType::Nil
- });
- }
- if self.tokens.match_next(vec![TokenType::Number, TokenType::Str]) {
- return Rc::new(Literal {
- value: self.tokens.previous().literal.unwrap()
- })
- }
- if self.tokens.match_next(vec![TokenType::LeftParen]) {
- //else {
- let expression = self.expression();
- self.tokens.consume(TokenType::RightParen, "Expect ')' after expression.");
- return Rc::new(Grouping {
- expression
- })
- }
- panic!("oopsie doopsie");
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement