added parsing of if statements

This commit is contained in:
Karma Riuk
2025-07-14 15:19:05 +02:00
parent 86574552aa
commit 9e63c923da
7 changed files with 244 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
#include "if_then_else.hpp"
#include <sstream>
namespace ast {
if_then_else::if_then_else(token::token token)
: token(std::move(token)),
consequence(nullptr),
alternative(nullptr) {};
std::string if_then_else::token_literal() const {
return token.literal;
};
std::string if_then_else::str() const {
std::stringstream ss;
ss << "if " << condition->str() << consequence->str();
if (alternative != nullptr)
ss << "else" << alternative->str();
return ss.str();
};
} // namespace ast

View File

@@ -0,0 +1,19 @@
#pragma once
#include "ast/ast.hpp"
#include "ast/statements/block.hpp"
#include "token/token.hpp"
#include <string>
namespace ast {
struct if_then_else : expression {
if_then_else(token::token);
token::token token;
ast::expression* condition;
ast::block_stmt *consequence, *alternative;
std::string token_literal() const override;
std::string str() const override;
};
} // namespace ast

View File

@@ -0,0 +1,25 @@
#include "block.hpp"
#include <sstream>
namespace ast {
block_stmt::block_stmt(token::token token): token(std::move(token)) {}
std::string block_stmt::token_literal() const {
return token.literal;
}
block_stmt::~block_stmt() {
for (const auto& stmt : statements)
delete stmt;
};
std::string block_stmt::str() const {
std::stringstream ss;
ss << "{";
for (const auto& stmt : statements)
ss << stmt->str();
ss << "}";
return ss.str();
};
} // namespace ast

View File

@@ -0,0 +1,20 @@
#pragma once
#include "ast/ast.hpp"
#include "token/token.hpp"
#include <vector>
namespace ast {
struct block_stmt : statement {
block_stmt(token::token token);
token::token token;
std::vector<ast::statement*> statements;
std::string token_literal() const override;
std::string str() const override;
~block_stmt();
};
} // namespace ast

View File

@@ -3,9 +3,11 @@
#include "ast/errors/error.hpp"
#include "ast/expressions/boolean.hpp"
#include "ast/expressions/identifier.hpp"
#include "ast/expressions/if_then_else.hpp"
#include "ast/expressions/infix.hpp"
#include "ast/expressions/integer.hpp"
#include "ast/expressions/prefix.hpp"
#include "ast/statements/block.hpp"
#include "token/token.hpp"
#include "token/type.hpp"
#include "utils/tracer.hpp"
@@ -51,6 +53,11 @@ namespace parser {
std::bind(&parser::parse_grouped_expr, this)
);
register_prefix(
token::type::IF,
std::bind(&parser::parse_if_then_else, this)
);
using namespace std::placeholders;
register_infix(
{token::type::PLUS,
@@ -256,6 +263,59 @@ namespace parser {
return ret;
};
ast::expression* parser::parse_if_then_else() {
// TRACE_FUNCTION;
ast::if_then_else* ret = new ast::if_then_else(current);
if (!expect_next(token::type::LPAREN)) {
delete ret;
return nullptr;
}
next_token();
ret->condition = parse_expression();
if (!expect_next(token::type::RPAREN)) {
delete ret;
return nullptr;
}
if (!expect_next(token::type::LBRACE)) {
delete ret;
return nullptr;
}
ret->consequence = parse_block();
if (next.type != token::type::ELSE)
return ret;
next_token();
if (!expect_next(token::type::LBRACE)) {
delete ret;
return nullptr;
}
ret->alternative = parse_block();
return ret;
};
ast::block_stmt* parser::parse_block() {
// TRACE_FUNCTION;
ast::block_stmt* ret = new ast::block_stmt(current);
// ret->statements.push_back(parse_statement());
next_token();
int i = 0;
while (current.type != token::type::RBRACE && i++ < 10) {
// for (next_token(); next.type != token::type::RBRACE;
// next_token()) {
ast::statement* stmt = parse_statement();
if (stmt != nullptr)
ret->statements.push_back(stmt);
next_token();
}
return ret;
}
ast::expression* parser::parse_infix_expr(ast::expression* left) {
// TRACE_FUNCTION;
ast::infix_expr* ret =

View File

@@ -3,6 +3,7 @@
#include "ast/ast.hpp"
#include "ast/errors/error.hpp"
#include "ast/program.hpp"
#include "ast/statements/block.hpp"
#include "ast/statements/expression.hpp"
#include "ast/statements/let.hpp"
#include "ast/statements/return.hpp"
@@ -54,6 +55,8 @@ namespace parser {
ast::expression* parse_boolean();
ast::expression* parse_prefix_expr();
ast::expression* parse_grouped_expr();
ast::expression* parse_if_then_else();
ast::block_stmt* parse_block();
ast::expression* parse_infix_expr(ast::expression*);
};