put the impl in the cpp file for Parser

This commit is contained in:
Shautvast 2024-10-22 12:29:48 +02:00
parent b6309de7a2
commit e2ee2b130e
2 changed files with 135 additions and 118 deletions

View file

@ -70,3 +70,123 @@ Expression *Parser::parse(vector<Token> tokenlist) {
current_token = 0; current_token = 0;
return expression(); return expression();
} }
Token Parser::peek() { return tokens[current_token]; };
bool Parser::is_at_end() { return peek().tokentype == Token::END_OF_FILE; };
Token *Parser::previous() { return &tokens[current_token - 1]; };
Token *Parser::advance() {
if (!is_at_end())
current_token += 1;
return previous();
}
bool Parser::check(Token::Type type) {
if (is_at_end()) {
return false;
}
return peek().tokentype == type;
}
bool Parser::match(int count, ...) {
va_list list;
va_start(list, count);
for (int i = 0; i < count; i++) {
Token::Type ttc = va_arg(list, Token::Type);
// cout << token_name(ttc) << "\n";
if (check(ttc)) {
advance();
return true;
}
}
return false;
};
Token *Parser::consume(Token::Type typ, string message) {
if (check(typ)) {
return advance();
}
throw error(peek(), message);
}
runtime_error Parser::error(Token token, string message) {
cout << token.as_string() << " " << message;
return runtime_error(message); // TODO no exceptions
}
Expression *Parser::primary() {
if (match(1, Token::Type::FALSE))
return new Literal(false);
if (match(1, Token::Type::TRUE))
return new Literal(true);
if (match(1, Token::Type::NIL))
return new Literal(new Void());
if (match(1, Token::Type::NUMBER)) {
return new Literal(stod(previous()->literal));
}
if (match(1, Token::Type::STRING)) {
return new Literal(previous()->literal);
}
if (match(1, Token::Type::LEFT_PAREN)) {
Expression *e = expression();
consume(Token::Type::RIGHT_PAREN, "Expect ')'.");
return new Grouping(e);
}
throw runtime_error("Expected an expression");
}
Expression *Parser::unary() {
if (match(2, Token::BANG, Token::Type::MINUS)) {
Token *op = previous();
Expression *right = unary();
return new Unary(op, right);
}
return primary();
}
Expression *Parser::expression() { return equality(); }
Expression *Parser::factor() {
Expression *expr = unary();
while (match(2, Token::Type::SLASH, Token::Type::STAR)) {
Token *op = previous();
Expression *right = unary();
expr = new Binary(expr, op, right);
}
return expr;
}
Expression *Parser::term() {
Expression *expr = factor();
while (match(2, Token::Type::MINUS, Token::Type::PLUS)) {
Token *op = previous();
Expression *right = unary();
expr = new Binary(expr, op, right);
}
return expr;
}
Expression *Parser::equality(void) {
Expression *expr = comparison();
while (match(2, Token::Type::BANG_EQUAL, Token::Type::BANG_EQUAL)) {
Token *op = previous();
Expression *right = comparison();
return new Binary(expr, op, right);
}
return expr;
}
Expression *Parser::comparison(void) {
Expression *expr = term();
while (match(4, Token::Type::GREATER, Token::Type::GREATER_EQUAL,
Token::Type::LESS, Token::Type::LESS_EQUAL)) {
Token *op = previous();
Expression *right = term();
expr = new Binary(expr, op, right);
}
return expr;
}

View file

@ -89,125 +89,22 @@ class Parser {
vector<Token> tokens; vector<Token> tokens;
int current_token; int current_token;
Token peek() { return tokens[current_token]; }; Token peek();
bool is_at_end();
bool is_at_end() { return peek().tokentype == Token::END_OF_FILE; }; Token *previous();
Token *advance();
Token *previous() { return &tokens[current_token - 1]; }; bool check(Token::Type type);
bool match(int count, ...);
Token *advance() { Token *consume(Token::Type typ, string message);
if (!is_at_end()) runtime_error error(Token token, string message);
current_token += 1; Expression *primary();
return previous(); Expression *unary();
} Expression *expression();
Expression *factor();
bool check(Token::Type type) { Expression *term();
if (is_at_end()) { Expression *equality(void);
return false; Expression *comparison(void);
}
return peek().tokentype == type;
}
bool match(int count, ...) {
va_list list;
va_start(list, count);
for (int i = 0; i < count; i++) {
Token::Type ttc = va_arg(list, Token::Type);
// cout << token_name(ttc) << "\n";
if (check(ttc)) {
advance();
return true;
}
}
return false;
};
Token *consume(Token::Type typ, string message) {
if (check(typ)) {
return advance();
}
throw error(peek(), message);
}
runtime_error error(Token token, string message) {
cout << token.as_string() << " " << message;
return runtime_error(message); // TODO no exceptions
}
Expression *primary() {
if (match(1, Token::Type::FALSE))
return new Literal(false);
if (match(1, Token::Type::TRUE))
return new Literal(true);
if (match(1, Token::Type::NIL))
return new Literal(new Void());
if (match(1, Token::Type::NUMBER)) {
return new Literal(stod(previous()->literal));
}
if (match(1, Token::Type::STRING)) {
return new Literal(previous()->literal);
}
if (match(1, Token::Type::LEFT_PAREN)) {
Expression *e = expression();
consume(Token::Type::RIGHT_PAREN, "Expect ')'.");
return new Grouping(e);
}
throw runtime_error("Expected an expression");
}
public: public:
Expression *parse(vector<Token> tokenlist); Expression *parse(vector<Token> tokenlist);
Expression *unary() {
if (match(2, Token::BANG, Token::Type::MINUS)) {
Token *op = previous();
Expression *right = unary();
return new Unary(op, right);
}
return primary();
}
Expression *expression() { return equality(); }
Expression *factor() {
Expression *expr = unary();
while (match(2, Token::Type::SLASH, Token::Type::STAR)) {
Token *op = previous();
Expression *right = unary();
expr = new Binary(expr, op, right);
}
return expr;
}
Expression *term() {
Expression *expr = factor();
while (match(2, Token::Type::MINUS, Token::Type::PLUS)) {
Token *op = previous();
Expression *right = unary();
expr = new Binary(expr, op, right);
}
return expr;
}
Expression *equality(void) {
Expression *expr = comparison();
while (match(2, Token::Type::BANG_EQUAL, Token::Type::BANG_EQUAL)) {
Token *op = previous();
Expression *right = comparison();
return new Binary(expr, op, right);
}
return expr;
}
Expression *comparison(void) {
Expression *expr = term();
while (match(4, Token::Type::GREATER, Token::Type::GREATER_EQUAL,
Token::Type::LESS, Token::Type::LESS_EQUAL)) {
Token *op = previous();
Expression *right = term();
expr = new Binary(expr, op, right);
}
return expr;
}
}; };