Change binop res to type

This commit is contained in:
Sofia 2026-05-10 19:34:50 +03:00
parent 2e08d373f5
commit 06231f466a
4 changed files with 17 additions and 35 deletions

View File

@ -35,19 +35,17 @@ namespace types {
bool_ty
}) {
definitions.push_back(BinopDefinition{
ty, types::BinOp::Add, ty,
ty, types::BinOp::Add, ty, ty,
[](codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
return builder.builder->CreateAdd(lhs, rhs, "add");
},
[](BinopDefinition& def, std::shared_ptr<types::Type>, std::shared_ptr<types::Type>) {return def.lhs;}
});
definitions.push_back(BinopDefinition{
ty, types::BinOp::Sub, ty,
ty, types::BinOp::Sub, ty, ty,
[](codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
return builder.builder->CreateSub(lhs, rhs, "sub");
},
[](BinopDefinition& def, std::shared_ptr<types::Type>, std::shared_ptr<types::Type>) {return def.lhs;}
});
}
@ -56,25 +54,17 @@ namespace types {
short_int_ty, int_ty, long_int_ty, long_long_int_ty, char_ty,
}) {
definitions.push_back(BinopDefinition{
ty, types::BinOp::LessThan, ty,
ty, types::BinOp::LessThan, ty, bool_ty,
[](codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
return builder.builder->CreateICmpSLT(lhs, rhs, "icmpslt");
},
[](BinopDefinition&, std::shared_ptr<types::Type>, std::shared_ptr<types::Type>) {
return std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
}
});
definitions.push_back(BinopDefinition{
ty, types::BinOp::GreaterThan, ty,
ty, types::BinOp::GreaterThan, ty, bool_ty,
[](codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
return builder.builder->CreateICmpSGT(lhs, rhs, "icmpsgt");
},
[](BinopDefinition&, std::shared_ptr<types::Type>, std::shared_ptr<types::Type>) {
return std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
}
});
}
@ -84,25 +74,17 @@ namespace types {
bool_ty
}) {
definitions.push_back(BinopDefinition{
ty, types::BinOp::LessThan, ty,
ty, types::BinOp::LessThan, ty, bool_ty,
[](codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
return builder.builder->CreateICmpULT(lhs, rhs, "icmpult");
},
[](BinopDefinition&, std::shared_ptr<types::Type>, std::shared_ptr<types::Type>) {
return std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
}
});
definitions.push_back(BinopDefinition{
ty, types::BinOp::GreaterThan, ty,
ty, types::BinOp::GreaterThan, ty, bool_ty,
[](codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
return builder.builder->CreateICmpUGT(lhs, rhs, "icmpugt");
},
[](BinopDefinition&, std::shared_ptr<types::Type>, std::shared_ptr<types::Type>) {
return std::shared_ptr<types::Type>{
new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
}
});
}

View File

@ -32,8 +32,8 @@ namespace types {
std::shared_ptr<Type> lhs;
BinOp op;
std::shared_ptr<Type> rhs;
std::shared_ptr<Type> result;
llvm::Value* (*codegen)(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs);
std::shared_ptr<Type>(*result)(BinopDefinition& def, std::shared_ptr<Type> lhs, std::shared_ptr<Type> rhs);
};
std::vector<BinopDefinition> create_binops();

View File

@ -120,7 +120,7 @@ namespace AST {
this->m_binop,
rhs);
if (binop) {
return binop->result(*binop, lhs, rhs);
return binop->result;
}
throw CompileError("invalid binop", this->m_meta);
}
@ -148,7 +148,7 @@ namespace AST {
if (binop) {
return codegen::StackValue{
binop->codegen(builder, lhs.value, rhs.value),
binop->result(*binop, lhs.ty, rhs.ty)
binop->result
};
}
throw CompileError("invalid binop", this->m_meta);

View File

@ -205,7 +205,7 @@ namespace AST {
);
if (binop) {
return { binop->result(*binop, lhs_ty, rhs_ty), false, false };
return { binop->result, false, false };
}
// If that fails, try to find binop that matches on one side perfectly
@ -215,7 +215,7 @@ namespace AST {
if (expected_ty) {
// Skip any binops that would not be immediately assignable to
// the expected type
if (!types::types_equal(binop.result(binop, lhs_ty, rhs_ty), *expected_ty)) {
if (!types::types_equal(binop.result, *expected_ty)) {
continue;
}
}
@ -229,7 +229,7 @@ namespace AST {
rhs_res = check_type(state, rhs_ty, binop.rhs);
this->m_rhs = handle_res(std::move(this->m_rhs), rhs_res, state);
return { binop.result(binop, lhs_ty, rhs_ty), false, false };
return { binop.result, false, false };
}
else if (types::types_equal(binop.rhs, rhs_ty)) {
auto lhs_res = check_type(state, lhs_ty, binop.lhs);
@ -240,7 +240,7 @@ namespace AST {
lhs_ty = this->m_lhs->typecheck(state, scope, binop.lhs).type;
lhs_res = check_type(state, lhs_ty, binop.lhs);
this->m_lhs = handle_res(std::move(this->m_lhs), lhs_res, state);
return { binop.result(binop, lhs_ty, rhs_ty), false, false };
return { binop.result, false, false };
}
}
@ -250,7 +250,7 @@ namespace AST {
if (expected_ty) {
// Skip any binops that would not be immediately assignable to
// the expected type
if (!types::types_equal(binop.result(binop, lhs_ty, rhs_ty), *expected_ty)) {
if (!types::types_equal(binop.result, *expected_ty)) {
continue;
}
}
@ -266,7 +266,7 @@ namespace AST {
rhs_res = check_type(state, rhs_ty, binop.rhs);
this->m_lhs = handle_res(std::move(this->m_lhs), lhs_res, state);
this->m_rhs = handle_res(std::move(this->m_rhs), rhs_res, state);
return { binop.result(binop, lhs_ty, rhs_ty), false, false };
return { binop.result, false, false };
}
// Finally check for any binop that allows the result to be implicitly
@ -275,7 +275,7 @@ namespace AST {
if (expected_ty) {
// Skip any binops that would not even be implicitly castable to
// the expected result
auto result_res = check_type(state, binop.result(binop, lhs_ty, rhs_ty), *expected_ty);
auto result_res = check_type(state, binop.result, *expected_ty);
if (!result_res.ok())
continue;
}
@ -285,7 +285,7 @@ namespace AST {
auto rhs_result = check_type(state, rhs_ty, binop.rhs);
this->m_lhs = handle_res(std::move(this->m_lhs), lhs_result, state);
this->m_rhs = handle_res(std::move(this->m_rhs), lhs_result, state);
return { binop.result(binop, lhs_ty, rhs_ty), false, false };
return { binop.result, false, false };
}
// No suitable binops found :(