From 48a3eb0e85f631624dae96544a19f88ad31619df Mon Sep 17 00:00:00 2001 From: Sofia Date: Mon, 13 Apr 2026 23:50:07 +0300 Subject: [PATCH] Improve binop result calculation --- src/binops.cpp | 48 +++++++++++++++++++++++++++++++++------------ src/binops.h | 2 +- src/codegen.cpp | 2 +- src/typechecker.cpp | 12 ++++++------ src/types.h | 2 ++ 5 files changed, 46 insertions(+), 20 deletions(-) diff --git a/src/binops.cpp b/src/binops.cpp index a7653d5..d1ffb78 100644 --- a/src/binops.cpp +++ b/src/binops.cpp @@ -16,45 +16,69 @@ namespace types { for (auto& ty : { int_ty, char_ty, bool_ty }) { definitions.push_back(BinopDefinition{ 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"); - } }); + }, + [](BinopDefinition& def, std::shared_ptr, std::shared_ptr) {return def.lhs;} + }); definitions.push_back(BinopDefinition{ 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"); - } }); + }, + [](BinopDefinition& def, std::shared_ptr, std::shared_ptr) {return def.lhs;} + }); } // Signed comparisons for (auto& ty : { int_ty }) { definitions.push_back(BinopDefinition{ 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"); - } }); + }, + [](BinopDefinition&, std::shared_ptr, std::shared_ptr) { + return std::shared_ptr{ + new types::FundamentalType{ types::FundamentalTypeKind::Bool } }; + } + }); definitions.push_back(BinopDefinition{ 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"); - } }); + }, + [](BinopDefinition&, std::shared_ptr, std::shared_ptr) { + return std::shared_ptr{ + new types::FundamentalType{ types::FundamentalTypeKind::Bool } }; + } + }); } // Unsigned comparisons for (auto& ty : { bool_ty, char_ty }) { definitions.push_back(BinopDefinition{ 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, "icmpslt"); - } }); + }, + [](BinopDefinition&, std::shared_ptr, std::shared_ptr) { + return std::shared_ptr{ + new types::FundamentalType{ types::FundamentalTypeKind::Bool } }; + } + }); definitions.push_back(BinopDefinition{ 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, "icmpsgt"); - } }); + }, + [](BinopDefinition&, std::shared_ptr, std::shared_ptr) { + return std::shared_ptr{ + new types::FundamentalType{ types::FundamentalTypeKind::Bool } }; + } + }); } return definitions; diff --git a/src/binops.h b/src/binops.h index bfba32d..801474a 100644 --- a/src/binops.h +++ b/src/binops.h @@ -22,8 +22,8 @@ namespace types { std::shared_ptr lhs; BinOp op; std::shared_ptr rhs; - std::shared_ptr result; llvm::Value* (*codegen)(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs); + std::shared_ptr(*result)(BinopDefinition& def, std::shared_ptr lhs, std::shared_ptr rhs); }; std::vector create_binops(); diff --git a/src/codegen.cpp b/src/codegen.cpp index 7effa5a..ff6afd3 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -74,7 +74,7 @@ namespace AST { if (binop) { return codegen::StackValue{ binop->codegen(builder, lhs.value, rhs.value), - binop->result + binop->result(*binop, lhs.ty, rhs.ty) }; } throw CompileError("invalid binop", this->m_meta); diff --git a/src/typechecker.cpp b/src/typechecker.cpp index a047a4a..ab8ef1f 100644 --- a/src/typechecker.cpp +++ b/src/typechecker.cpp @@ -133,7 +133,7 @@ namespace AST { ); if (binop) { - return binop->result; + return binop->result(*binop, lhs_ty, rhs_ty); } // If that fails, try to find binop that matches on one side perfectly @@ -143,7 +143,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, *expected_ty)) { + if (!types::types_equal(binop.result(binop, lhs_ty, rhs_ty), *expected_ty)) { continue; } } @@ -153,7 +153,7 @@ namespace AST { // Skip if not implicitly castable to lhs continue; this->m_rhs = handle_res(std::move(this->m_rhs), rhs_res, state); - return binop.result; + return binop.result(binop, lhs_ty, rhs_ty); } else if (types::types_equal(binop.rhs, rhs_ty)) { auto lhs_res = check_type(state, lhs_ty, binop.lhs); @@ -161,7 +161,7 @@ namespace AST { // Skip if not implicitly castable to rhs continue; this->m_lhs = handle_res(std::move(this->m_lhs), lhs_res, state); - return binop.result; + return binop.result(binop, lhs_ty, rhs_ty); } } @@ -171,7 +171,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, *expected_ty); + auto result_res = check_type(state, binop.result(binop, lhs_ty, rhs_ty), *expected_ty); if (!result_res.ok()) continue; } @@ -179,7 +179,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; + return binop.result(binop, lhs_ty, rhs_ty); } // No suitable binops found :( diff --git a/src/types.h b/src/types.h index 9d012ef..8cc7d41 100644 --- a/src/types.h +++ b/src/types.h @@ -18,6 +18,8 @@ namespace types { Bool, Char, Void, + /// @brief Mainly used for binop resolution + Any, }; class Type {