2022-06-02 16:25:01 +00:00
|
|
|
#pragma once
|
2022-06-07 16:12:43 +00:00
|
|
|
#include <memory>
|
|
|
|
#include "Lexer.h"
|
2022-06-08 15:39:51 +00:00
|
|
|
#include "AST/NumberNode.h"
|
2022-06-08 17:34:16 +00:00
|
|
|
#include "Error.h"
|
|
|
|
#include <cassert>
|
2022-06-02 16:25:01 +00:00
|
|
|
|
2022-06-08 17:34:16 +00:00
|
|
|
/* Parser class for the Sapphire compiler. */
|
2022-06-02 16:25:01 +00:00
|
|
|
class Parser
|
|
|
|
{
|
2022-06-08 17:34:16 +00:00
|
|
|
/* Struct to store a parsing result which can be either a parsing error or a success, in which case it contains a pointer to the result. */
|
2022-06-08 15:39:51 +00:00
|
|
|
template<typename T>
|
|
|
|
struct ErrorOr
|
|
|
|
{
|
2022-06-08 17:34:16 +00:00
|
|
|
/* Return the stored pointer. */
|
2022-06-08 15:39:51 +00:00
|
|
|
std::shared_ptr<T> get()
|
|
|
|
{
|
2022-06-08 17:34:16 +00:00
|
|
|
assert(!m_is_error);
|
2022-06-08 15:39:51 +00:00
|
|
|
return m_ptr;
|
|
|
|
}
|
2022-06-08 17:34:16 +00:00
|
|
|
|
|
|
|
/* Call Error::throw_error() with the stored error's location, line text, and the error string provided to this struct instance. */
|
|
|
|
void ethrow()
|
2022-06-08 15:39:51 +00:00
|
|
|
{
|
2022-06-08 17:34:16 +00:00
|
|
|
assert(m_is_error);
|
|
|
|
Error::throw_error(error_tok->loc,error_tok->line(),m_error);
|
2022-06-08 15:39:51 +00:00
|
|
|
}
|
|
|
|
|
2022-06-08 17:34:16 +00:00
|
|
|
/* Construct a new successful ErrorOr with a heap-allocated pointer to the result class. */
|
2022-06-08 15:49:22 +00:00
|
|
|
ErrorOr(T* ptr) : m_ptr(ptr), m_is_error(false) {}
|
2022-06-08 17:34:16 +00:00
|
|
|
/* Construct a new failed ErrorOr with the error details and the token where parsing failed. */
|
2022-06-08 15:39:51 +00:00
|
|
|
ErrorOr(const std::string& error, const Token& error_tok) : m_error(error), m_is_error(true), error_tok(error_tok) {}
|
|
|
|
|
2022-06-08 17:34:16 +00:00
|
|
|
/* Is this ErrorOr instance successful or failed? */
|
2022-06-08 15:39:51 +00:00
|
|
|
bool is_error() { return m_is_error; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool m_is_error;
|
|
|
|
std::string m_error;
|
2022-06-08 15:50:19 +00:00
|
|
|
std::shared_ptr<Token> error_tok;
|
2022-06-08 15:39:51 +00:00
|
|
|
std::shared_ptr<T> m_ptr;
|
|
|
|
};
|
2022-06-02 16:25:01 +00:00
|
|
|
private:
|
2022-06-08 15:39:51 +00:00
|
|
|
Parser(const TokenStream& tokens);
|
|
|
|
TokenStream tokens;
|
|
|
|
|
|
|
|
ErrorOr<ExprNode> walk_expr();
|
|
|
|
ErrorOr<NumberNode> walk_number();
|
2022-06-08 17:17:16 +00:00
|
|
|
|
|
|
|
int m_index;
|
|
|
|
int saved_m_index;
|
|
|
|
|
|
|
|
void save_current_position();
|
|
|
|
void restore_current_position();
|
2022-06-02 16:25:01 +00:00
|
|
|
public:
|
|
|
|
~Parser();
|
2022-06-07 16:12:43 +00:00
|
|
|
|
2022-06-08 17:34:16 +00:00
|
|
|
/* Construct a new Parser with the given TokenStream. */
|
2022-06-07 16:12:43 +00:00
|
|
|
static std::shared_ptr<Parser> new_parser(const TokenStream& tokens);
|
2022-06-08 17:34:16 +00:00
|
|
|
/* Parse the stored TokenStream and return the top-level node of the result Abstract Syntax Tree. */
|
2022-06-07 16:12:43 +00:00
|
|
|
std::shared_ptr<ASTNode> parse();
|
2022-06-02 16:25:01 +00:00
|
|
|
};
|