Change binop res to type
This commit is contained in:
parent
2e08d373f5
commit
06231f466a
@ -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 } };
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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 :(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user