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 bool_ty
}) { }) {
definitions.push_back(BinopDefinition{ definitions.push_back(BinopDefinition{
ty, types::BinOp::Add, ty, ty, types::BinOp::Add, ty, ty,
[](codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) { [](codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
return builder.builder->CreateAdd(lhs, rhs, "add"); 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{ definitions.push_back(BinopDefinition{
ty, types::BinOp::Sub, ty, ty, types::BinOp::Sub, ty, ty,
[](codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) { [](codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
return builder.builder->CreateSub(lhs, rhs, "sub"); 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, short_int_ty, int_ty, long_int_ty, long_long_int_ty, char_ty,
}) { }) {
definitions.push_back(BinopDefinition{ 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) { [](codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
return builder.builder->CreateICmpSLT(lhs, rhs, "icmpslt"); 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{ 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) { [](codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
return builder.builder->CreateICmpSGT(lhs, rhs, "icmpsgt"); 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 bool_ty
}) { }) {
definitions.push_back(BinopDefinition{ 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) { [](codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
return builder.builder->CreateICmpULT(lhs, rhs, "icmpult"); 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{ 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) { [](codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) {
return builder.builder->CreateICmpUGT(lhs, rhs, "icmpugt"); 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; std::shared_ptr<Type> lhs;
BinOp op; BinOp op;
std::shared_ptr<Type> rhs; std::shared_ptr<Type> rhs;
std::shared_ptr<Type> result;
llvm::Value* (*codegen)(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs); 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(); std::vector<BinopDefinition> create_binops();

View File

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

View File

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