Add some new binary operations

This commit is contained in:
Sofia 2026-04-10 17:11:03 +03:00
parent d69e2c0929
commit 422f95e553
3 changed files with 68 additions and 2 deletions

View File

@ -56,6 +56,21 @@ namespace AST {
lhs.ty->add(builder, lhs.value, rhs.value), lhs.ty->add(builder, lhs.value, rhs.value),
lhs.ty lhs.ty
}; };
case types::BinOp::Sub:
return codegen::StackValue{
lhs.ty->sub(builder, lhs.value, rhs.value),
lhs.ty
};
case types::BinOp::LessThan:
return codegen::StackValue{
lhs.ty->lt(builder, lhs.value, rhs.value),
std::make_shared<types::FundamentalType>(types::FundamentalTypeKind::Bool),
};
case types::BinOp::GreaterThan:
return codegen::StackValue{
lhs.ty->gt(builder, lhs.value, rhs.value),
std::make_shared<types::FundamentalType>(types::FundamentalTypeKind::Bool),
};
default: default:
throw std::runtime_error("invalid binop"); throw std::runtime_error("invalid binop");
} }
@ -127,6 +142,8 @@ namespace types {
switch (this->m_ty) { switch (this->m_ty) {
case FundamentalTypeKind::Int: case FundamentalTypeKind::Int:
return builder.builder->getInt32Ty(); return builder.builder->getInt32Ty();
case FundamentalTypeKind::Bool:
return builder.builder->getInt1Ty();
default: default:
return builder.builder->getVoidTy(); return builder.builder->getVoidTy();
} }

View File

@ -5,10 +5,16 @@
namespace types { namespace types {
int operator_precedence(BinOp& op) { int operator_precedence(BinOp& op) {
switch (op) { switch (op) {
case BinOp::Add:
case BinOp::Sub:
return 10;
case BinOp::LessThan:
case BinOp::GreaterThan:
return 20;
case BinOp::Assignment: case BinOp::Assignment:
return 1000; return 1000;
case BinOp::Add:
return 10;
default: default:
return 1000; return 1000;
} }
@ -20,6 +26,12 @@ namespace types {
return "="; return "=";
case BinOp::Add: case BinOp::Add:
return "+"; return "+";
case BinOp::Sub:
return "-";
case BinOp::LessThan:
return "<";
case BinOp::GreaterThan:
return ">";
default: default:
return "??"; return "??";
} }
@ -42,4 +54,31 @@ namespace types {
throw std::runtime_error("Invalid type for add"); throw std::runtime_error("Invalid type for add");
} }
} }
llvm::Value* FundamentalType::sub(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
switch (this->m_ty) {
case FundamentalTypeKind::Int:
return builder.builder->CreateSub(lhs, rhs);
default:
throw std::runtime_error("Invalid type");
}
}
llvm::Value* FundamentalType::lt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
switch (this->m_ty) {
case FundamentalTypeKind::Int:
return builder.builder->CreateCmp(llvm::CmpInst::Predicate::ICMP_SLT, lhs, rhs);
default:
throw std::runtime_error("Invalid type");
}
}
llvm::Value* FundamentalType::gt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
switch (this->m_ty) {
case FundamentalTypeKind::Int:
return builder.builder->CreateCmp(llvm::CmpInst::Predicate::ICMP_SGT, lhs, rhs);
default:
throw std::runtime_error("Invalid type");
}
}
} }

View File

@ -10,6 +10,9 @@ namespace types {
enum class BinOp { enum class BinOp {
Assignment, Assignment,
Add, Add,
Sub,
LessThan,
GreaterThan,
}; };
int operator_precedence(BinOp& op); int operator_precedence(BinOp& op);
@ -17,6 +20,7 @@ namespace types {
enum FundamentalTypeKind { enum FundamentalTypeKind {
Int, Int,
Bool
}; };
class Type { class Type {
@ -25,6 +29,9 @@ namespace types {
virtual std::string formatted() = 0; virtual std::string formatted() = 0;
virtual llvm::Type* codegen(codegen::Builder& builder) = 0; virtual llvm::Type* codegen(codegen::Builder& builder) = 0;
virtual llvm::Value* add(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) = 0; virtual llvm::Value* add(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) = 0;
virtual llvm::Value* sub(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) = 0;
virtual llvm::Value* lt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) = 0;
virtual llvm::Value* gt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) = 0;
}; };
class FundamentalType : public Type { class FundamentalType : public Type {
@ -36,6 +43,9 @@ namespace types {
virtual std::string formatted() override; virtual std::string formatted() override;
virtual llvm::Type* codegen(codegen::Builder& builder) override; virtual llvm::Type* codegen(codegen::Builder& builder) override;
virtual llvm::Value* add(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override; virtual llvm::Value* add(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override;
virtual llvm::Value* sub(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override;
virtual llvm::Value* lt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override;
virtual llvm::Value* gt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override;
}; };
} }