-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
489 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,7 +33,7 @@ See `LICENSE` for more information. | |
|
||
# Roadmap | ||
|
||
- Lexer | ||
- Le | ||
- Parser | ||
- Compiler | ||
- JIT | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
|
||
#pragma once | ||
|
||
#include <memory> | ||
#include <vector> | ||
#include <exception> | ||
#include <scanner/tokens.hh> | ||
#include <reader/reader.hh> | ||
#include <ast/expr.hh> | ||
|
||
using namespace rift::scanner; | ||
using namespace rift::reader; | ||
|
||
using GenExpr = rift::ast::Expr::Expr<rift::scanner::Token>; | ||
|
||
namespace rift | ||
{ | ||
namespace parser | ||
{ | ||
class Parser : public Reader<Token> | ||
{ | ||
public: | ||
Parser(const std::vector<Token> &tokens) : Reader<Token>(tokens), tokens(tokens) {}; | ||
~Parser() = default; | ||
protected: | ||
std::vector<Token> tokens; | ||
std::exception exception; | ||
|
||
private: | ||
#pragma mark - Grammar Evaluators | ||
|
||
/// @note rules in order of precedence | ||
|
||
/// @example 1 + 2 * 3 | ||
std::unique_ptr<GenExpr> expression(); | ||
/// @example 1 == 1, 1 != 2 | ||
std::unique_ptr<GenExpr> equality(); | ||
/// @example 1 > 2, 1 <= 2 | ||
std::unique_ptr<GenExpr> comparison(); | ||
/// @example 1 + 2, 1 - 2 | ||
std::unique_ptr<GenExpr> term(); | ||
/// @example 1 * 2, 1 / 2 | ||
std::unique_ptr<GenExpr> factor(); | ||
/// @example -1, !1 | ||
std::unique_ptr<GenExpr> unary(); | ||
/// @example 1, "string", true, false, nil | ||
std::unique_ptr<GenExpr> primary(); | ||
|
||
void synchronize(); | ||
|
||
std::unique_ptr<GenExpr> parse(); | ||
}; | ||
|
||
class ParserException : public ReaderException | ||
{ | ||
public: | ||
ParserException(const std::string &message) : message(message) {} | ||
~ParserException() = default; | ||
|
||
const char *what() const noexcept override { return message.c_str(); } | ||
|
||
private: | ||
std::string message; | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
|
||
#pragma once | ||
|
||
#include <error/error.hh> | ||
#include <exception> | ||
|
||
namespace rift | ||
{ | ||
namespace reader | ||
{ | ||
|
||
class ReaderException; | ||
|
||
/// @class Reader | ||
/// @tparam T The type of the reader <Token(Parser), Char(Scanner)> | ||
/// @brief The base class for reading through lines with utilities | ||
template <typename T> | ||
class Reader | ||
{ | ||
public: | ||
Reader(const std::vector<T> &source): source(source) {start=0;curr=0;line=1;}; | ||
~Reader() = default; | ||
|
||
protected: | ||
std::vector<T> source; | ||
unsigned start, curr, line; | ||
|
||
#pragma mark - Reader Methods | ||
|
||
inline bool atEnd() { return this->curr >= source.size(); } | ||
inline T advance() { return (!atEnd()) ? source.at(curr++) : T(); } | ||
// inline typename std::enable_if<std::is_same<T, char>::value, T>::type advance() { return (!atEnd()) ? source.at(curr++) : '\0'; } | ||
// inline typename std::enable_if<!std::is_same<T, char>::value, T>::type advance() { return (!atEnd()) ? source.at(curr++) : nullptr; } | ||
|
||
/// @brief Peeks at the current character | ||
inline bool peek(T expected) { return !atEnd() && source.at(curr) == expected; }; | ||
/// @brief Peeks at the current character with an offset | ||
inline bool peek_off(T expected, int offset) { return curr+offset<source.size() && source.at(curr+offset) == expected; }; | ||
/// @brief Peeks at the current character | ||
inline T peek() { return !atEnd() ? source.at(curr) : T(); }; | ||
/// @brief Peeks at the next character | ||
inline T peekNext() { return curr+1<source.size() ? source.at(curr+1) : T(); }; | ||
/// @brief Peeks at the next 2 characters | ||
inline bool peek3(T expected) { return peek_off(expected, 0) && peek_off(expected, 1) && peek_off(expected, 2); } | ||
/// @brief Peeks the previous character | ||
inline T peekPrev() { return curr-1>=0 ? source.at(curr-1) : T(); }; | ||
|
||
/// @brief Scans a comment and advances the cursor | ||
inline void scanComment() { while (peek('\n')) advance();}; | ||
/// @brief Consumes a T and advances the cursor (Error if not found) | ||
inline T consume (T expected, std::unique_ptr<ReaderException> error) { | ||
if (peek(expected)) return advance(); | ||
rift::error::report(line, "consume", "expected " << expected); | ||
if (error) throw error; | ||
} | ||
/// @brief Matches a T from a set of T's{token, character} and advances the cursor | ||
inline bool match(std::vector<T> expected) { | ||
for (auto &c : expected) { | ||
if (peek(c)) { | ||
advance(); | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
inline bool match_one(T expected) { return peek(expected) ? advance() : false; } | ||
}; | ||
|
||
/// @class ReaderException | ||
/// @brief The base exception for the reader (implement in derived classes) | ||
class ReaderException | ||
{ | ||
public: | ||
ReaderException() = default; | ||
~ReaderException() = default; | ||
virtual const char* what() const noexcept { return "BaseException"; } | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.