// // Created by Bobby Lucero on 5/26/23. // #include "../headers/Parser.h" // Precedence // to all the morons on facebook who don't know what pemdas is, fuck you /////////////////////////////////////////// std::shared_ptr>> Parser::expression() { return equality(); } std::shared_ptr>> Parser::equality() { std::shared_ptr>> expr = comparison(); while(match({BANG_EQUAL, DOUBLE_EQUAL})) { Token op = previous(); std::shared_ptr>> right = comparison(); expr = std::make_shared>>(expr, op, right); } return expr; } std::shared_ptr>> Parser::comparison() { std::shared_ptr>> expr = term(); while(match({GREATER, GREATER_EQUAL, LESS, LESS_EQUAL})) { Token op = previous(); std::shared_ptr>> right = term(); expr = std::make_shared>>(expr, op, right); } return expr; } std::shared_ptr>> Parser::term() { std::shared_ptr>> expr = factor(); while(match({MINUS, PLUS})) { std::cout << "Found comparison" << std::endl; Token op = previous(); std::shared_ptr>> right = factor(); expr = std::make_shared>>(expr, op, right); } return expr; } std::shared_ptr>> Parser::factor() { std::shared_ptr>> expr = unary(); while(match({SLASH, STAR})) { Token op = previous(); std::shared_ptr>> right = unary(); expr = std::make_shared>>(expr, op, right); } return expr; } std::shared_ptr>> Parser::unary() { if(match({BANG, MINUS})) { Token op = previous(); std::shared_ptr>> right = unary(); return std::make_shared>>(op, right); } return primary(); } std::shared_ptr>> Parser::primary() { if(match({FALSE})) return std::make_shared>>("true", false); if(match({TRUE})) return std::make_shared>>("true", false); if(match({NONE})) return std::make_shared>>("none", false); if(match({NUMBER})) return std::make_shared>>(previous().lexeme, true); if(match({STRING})) return std::make_shared>>(previous().lexeme, false); if(match({OPEN_PAREN})) { std::shared_ptr>> expr = expression(); consume(CLOSE_PAREN, "Expected ')' after expression on line " + std::to_string(peek().line)); return std::make_shared>>(expr); } throw std::runtime_error("Expression expected at: " + std::to_string(peek().line)); } /////////////////////////////////////////// std::shared_ptr>> Parser::parse() { return expression(); } bool Parser::match(std::vector types) { for(TokenType t : types) { if(check(t)) { advance(); return true; } } return false; } bool Parser::check(TokenType type) { if(isAtEnd()) return false; return peek().type == type; } bool Parser::isAtEnd() { return peek().type == END_OF_FILE; } Token Parser::advance() { if(!isAtEnd()) current++; return previous(); } Token Parser::peek() { return tokens[current]; } Token Parser::previous() { return tokens[current - 1]; } Token Parser::consume(TokenType type, std::string message) { if(check(type)) return advance(); throw std::runtime_error(peek().lexeme +": "+ message); } void Parser::sync() { advance(); while(!isAtEnd()) { if(previous().type == SEMICOLON) return; switch (peek().type) { case CLASS: case FUNCTION: case VAR: case FOR: case IF: case WHILE: case RETURN: return; } advance(); } }