Parse binary operators

This commit is contained in:
Sofia 2026-04-09 17:14:58 +03:00
parent 4d307d0eb9
commit 78816dff10
5 changed files with 111 additions and 12 deletions

View File

@ -3,6 +3,37 @@
#include <sstream>
namespace AST {
int operator_precedence(BinOp& op) {
return 0;
}
std::string format_operator(BinOp& op) {
switch (op) {
case BinOp::Assignment:
return "=";
default:
return "??";
}
}
std::string IntLiteralExpression::formatted() {
std::stringstream out{ "" };
out << this->m_value;
return out.str();
}
std::string ValueReferenceExpression::formatted() {
return this->m_name;
}
std::string BinaryOperationExpression::formatted() {
std::stringstream out{ "" };
out << this->m_lhs->formatted();
out << " " << format_operator(this->m_binop) << " ";
out << this->m_rhs->formatted();
return out.str();
}
std::string ExpressionStatement::formatted() {
std::stringstream out{ "" };
out << this->m_expr->formatted();
@ -28,16 +59,6 @@ namespace AST {
return out.str();
}
std::string IntLiteralExpression::formatted() {
std::stringstream out{ "" };
out << this->m_value;
return out.str();
}
std::string ValueReferenceExpression::formatted() {
return this->m_name;
}
std::string Function::formatted() {
std::stringstream out{ "" };
out << this->m_name;

View File

@ -8,6 +8,13 @@
#include <memory>
namespace AST {
enum class BinOp {
Assignment,
};
int operator_precedence(BinOp& op);
std::string format_operator(BinOp& op);
class Node {
public:
virtual std::string formatted() = 0;
@ -51,6 +58,20 @@ namespace AST {
virtual llvm::Value* codegen(codegen::Builder& builder, codegen::Scope& scope) override;
};
class BinaryOperationExpression : public Expression {
private:
std::unique_ptr<Expression> m_lhs;
BinOp m_binop;
std::unique_ptr<Expression> m_rhs;
public:
BinaryOperationExpression(std::unique_ptr<Expression> lhs, BinOp op, std::unique_ptr<Expression> rhs)
: m_lhs{ std::move(lhs) }, m_binop{ op }, m_rhs{ std::move(rhs) } {
}
virtual ~BinaryOperationExpression() override = default;
virtual std::string formatted() override;
virtual llvm::Value* codegen(codegen::Builder& builder, codegen::Scope& scope) override;
};
class ReturnStatement : public Statement {
private:

View File

@ -22,6 +22,11 @@ namespace AST {
}
}
llvm::Value* BinaryOperationExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
auto ty = builder.builder->getInt32Ty();
return llvm::ConstantInt::get(ty, 0);
}
void ReturnStatement::codegen(codegen::Builder& builder, codegen::Scope& scope) {
if (!builder.block)
return;

View File

@ -18,7 +18,7 @@ namespace parsing {
}
}
Result<std::unique_ptr<AST::Expression>, std::string> parse_expression(token::TokenStream& stream) {
Result<std::unique_ptr<AST::Expression>, std::string> parse_primary_expression(token::TokenStream& stream) {
token::TokenStream inner{ stream };
try {
auto token = inner.next();
@ -43,6 +43,58 @@ namespace parsing {
}
}
Result<AST::BinOp, std::string> parse_binop(token::TokenStream& stream) {
token::TokenStream inner{ stream };
try {
auto token = inner.next();
if (token.type != token::Type::Symbol) {
throw std::runtime_error("Expected binop");
}
if (token.content == "=") {
stream.m_position = inner.m_position;
return new AST::BinOp{ AST::BinOp::Assignment };
}
throw std::runtime_error("Expected binop");
}
catch (std::runtime_error error) {
return new std::string{ error.what() };
}
}
std::unique_ptr<AST::Expression> parse_rhs(
token::TokenStream& stream, std::unique_ptr<AST::Expression> lhs, int prev_precedence) {
auto binop_res = parse_binop(stream);
while (binop_res.ok()) {
auto binop = binop_res.unwrap();
auto rhs = parse_primary_expression(stream).unwrap();
if (AST::operator_precedence(binop) > prev_precedence) {
rhs = parse_rhs(stream, std::move(rhs), AST::operator_precedence(binop));
}
auto binop_expr = new AST::BinaryOperationExpression{ std::move(lhs), binop, std::move(rhs) };
lhs = std::unique_ptr<AST::Expression>{ binop_expr };
binop_res = parse_binop(stream);
}
return lhs;
}
Result<std::unique_ptr<AST::Expression>, std::string> parse_expression(token::TokenStream& stream) {
try {
auto lhs = parse_primary_expression(stream).unwrap();
return new std::unique_ptr{ parse_rhs(stream, std::move(lhs), 0) };
}
catch (std::runtime_error error) {
return new std::string{ error.what() };
}
}
Result<std::unique_ptr<AST::InitializationStatement>, std::string> parse_init_statement(token::TokenStream& stream) {
token::TokenStream inner{ stream };
try {

2
test.c
View File

@ -1,5 +1,5 @@
int main() {
int a = 5;
a;
a = 15;
return a;
}