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
};
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:
throw std::runtime_error("invalid binop");
}
@ -127,6 +142,8 @@ namespace types {
switch (this->m_ty) {
case FundamentalTypeKind::Int:
return builder.builder->getInt32Ty();
case FundamentalTypeKind::Bool:
return builder.builder->getInt1Ty();
default:
return builder.builder->getVoidTy();
}

View File

@ -5,10 +5,16 @@
namespace types {
int operator_precedence(BinOp& op) {
switch (op) {
case BinOp::Add:
case BinOp::Sub:
return 10;
case BinOp::LessThan:
case BinOp::GreaterThan:
return 20;
case BinOp::Assignment:
return 1000;
case BinOp::Add:
return 10;
default:
return 1000;
}
@ -20,6 +26,12 @@ namespace types {
return "=";
case BinOp::Add:
return "+";
case BinOp::Sub:
return "-";
case BinOp::LessThan:
return "<";
case BinOp::GreaterThan:
return ">";
default:
return "??";
}
@ -42,4 +54,31 @@ namespace types {
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 {
Assignment,
Add,
Sub,
LessThan,
GreaterThan,
};
int operator_precedence(BinOp& op);
@ -17,6 +20,7 @@ namespace types {
enum FundamentalTypeKind {
Int,
Bool
};
class Type {
@ -25,6 +29,9 @@ namespace types {
virtual std::string formatted() = 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* 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 {
@ -36,6 +43,9 @@ namespace types {
virtual std::string formatted() 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* 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;
};
}