#include "ast/call_expression_ast.h" #include "ast/number_expression_ast.h" #include "ast/variable_expression_ast.h" #include "parser.h" obelisk::Parser::Parser() { lexer_ = new obelisk::Lexer(); } obelisk::Parser::Parser(obelisk::Lexer* lexer) { if (lexer != nullptr) { lexer_ = lexer; } else { Parser(); } } obelisk::Parser::~Parser() { delete lexer_; } obelisk::Lexer* obelisk::Parser::getLexer() { return lexer_; } int obelisk::Parser::getNextToken() { setCurrentToken(getLexer()->getToken()); return getCurrentToken(); } int obelisk::Parser::getCurrentToken() { return currentToken_; } void obelisk::Parser::setCurrentToken(int currentToken) { currentToken_ = currentToken; } std::unique_ptr obelisk::Parser::logError( const char* str) { fprintf(stderr, "Error: %s\n", str); return nullptr; } std::unique_ptr obelisk::Parser::logErrorPrototype( const char* str) { logError(str); return nullptr; } std::unique_ptr obelisk::Parser::parseExpression() { auto LHS = parsePrimary(); if (!LHS) { return nullptr; } return LHS; } std::unique_ptr obelisk::Parser::parsePrimary() { switch (getCurrentToken()) { case obelisk::Lexer::kTokenIdentifier : return parseIdentifierExpression(); case obelisk::Lexer::kTokenNumber : return parseNumberExpression(); case '(' : return parseParenthesisExpression(); default : return logError("unknown token when expecting and expression"); } } std::unique_ptr obelisk::Parser::parseNumberExpression() { auto result = std::make_unique( getLexer()->getNumberValue()); getNextToken(); return std::move(result); } std::unique_ptr obelisk::Parser::parseParenthesisExpression() { getNextToken(); auto v = parseExpression(); if (!v) { return nullptr; } if (getCurrentToken() != ')') { return logError("expected ')'"); } getNextToken(); return v; } std::unique_ptr obelisk::Parser::parseIdentifierExpression() { std::string idName = getLexer()->getIdentifier(); getNextToken(); if (getCurrentToken() != '(') { return std::make_unique(idName); } getNextToken(); std::vector> args; if (getCurrentToken() != ')') { while (true) { if (auto arg = parseExpression()) { args.push_back(std::move(arg)); } else { return nullptr; } if (getCurrentToken() == ')') { break; } if (getCurrentToken() != ',') { return logError("Expected ')' or ',' in argument list"); } getNextToken(); } } getNextToken(); return std::make_unique(idName, std::move(args)); } std::unique_ptr obelisk::Parser::parsePrototype() { if (getCurrentToken() != obelisk::Lexer::kTokenIdentifier) { return logErrorPrototype("Expected function name in prototype"); } std::string functionName = getLexer()->getIdentifier(); getNextToken(); if (getCurrentToken() != '(') { return logErrorPrototype("Expected '(' in prototype"); } std::vector argNames; while (getNextToken() == obelisk::Lexer::kTokenIdentifier) { argNames.push_back(getLexer()->getIdentifier()); } if (getCurrentToken() != ')') { return logErrorPrototype("Expected ')' in prototype"); } getNextToken(); return std::make_unique(functionName, std::move(argNames)); } std::unique_ptr obelisk::Parser::parseDefinition() { getNextToken(); auto prototype = parsePrototype(); if (!prototype) { return nullptr; } if (auto expression = parseExpression()) { return std::make_unique(std::move(prototype), std::move(expression)); } return nullptr; } std::unique_ptr obelisk::Parser::parseTopLevelExpression() { if (auto expression = parseExpression()) { // Make an anonymous prototype auto prototype = std::make_unique("__anon_expr", std::vector()); return std::make_unique(std::move(prototype), std::move(expression)); } return nullptr; } std::unique_ptr obelisk::Parser::parseExtern() { getNextToken(); return parsePrototype(); }