Improve typechecking for binops
This commit is contained in:
parent
adc74333ff
commit
e064b3f04d
@ -6,6 +6,7 @@ namespace AST {
|
|||||||
std::string IntLiteralExpression::formatted() {
|
std::string IntLiteralExpression::formatted() {
|
||||||
std::stringstream out{ "" };
|
std::stringstream out{ "" };
|
||||||
out << this->m_value;
|
out << this->m_value;
|
||||||
|
out << this->m_ty->formatted();
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -55,7 +55,7 @@ namespace AST {
|
|||||||
: Expression{ meta }
|
: Expression{ meta }
|
||||||
, m_value{ value }
|
, m_value{ value }
|
||||||
, m_ty{ { std::shared_ptr<types::Type>{
|
, m_ty{ { std::shared_ptr<types::Type>{
|
||||||
new types::FundamentalType{true, types::FundamentalTypeKind::Int}
|
new types::FundamentalType{true, types::FundamentalTypeKind::AnyInt}
|
||||||
} } } {
|
} } } {
|
||||||
}
|
}
|
||||||
virtual ~IntLiteralExpression() override = default;
|
virtual ~IntLiteralExpression() override = default;
|
||||||
|
|||||||
@ -107,13 +107,32 @@ namespace types {
|
|||||||
|
|
||||||
auto int_ty = std::shared_ptr<types::Type>{
|
auto int_ty = std::shared_ptr<types::Type>{
|
||||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Int } };
|
new types::FundamentalType{ false, types::FundamentalTypeKind::Int } };
|
||||||
|
auto uint_ty = std::shared_ptr<types::Type>{
|
||||||
|
new types::FundamentalType{ false, types::FundamentalTypeKind::UInt } };
|
||||||
auto char_ty = std::shared_ptr<types::Type>{
|
auto char_ty = std::shared_ptr<types::Type>{
|
||||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Char } };
|
new types::FundamentalType{ false, types::FundamentalTypeKind::Char } };
|
||||||
|
auto uchar_ty = std::shared_ptr<types::Type>{
|
||||||
|
new types::FundamentalType{ false, types::FundamentalTypeKind::UChar } };
|
||||||
|
auto short_int_ty = std::shared_ptr<types::Type>{
|
||||||
|
new types::FundamentalType{ false, types::FundamentalTypeKind::ShortInt } };
|
||||||
|
auto ushort_int_ty = std::shared_ptr<types::Type>{
|
||||||
|
new types::FundamentalType{ false, types::FundamentalTypeKind::UShortInt } };
|
||||||
|
auto long_int_ty = std::shared_ptr<types::Type>{
|
||||||
|
new types::FundamentalType{ false, types::FundamentalTypeKind::LongInt } };
|
||||||
|
auto ulong_int_ty = std::shared_ptr<types::Type>{
|
||||||
|
new types::FundamentalType{ false, types::FundamentalTypeKind::ULongInt } };
|
||||||
|
auto long_long_int_ty = std::shared_ptr<types::Type>{
|
||||||
|
new types::FundamentalType{ false, types::FundamentalTypeKind::LongLongInt } };
|
||||||
|
auto ulong_long_int_ty = std::shared_ptr<types::Type>{
|
||||||
|
new types::FundamentalType{ false, types::FundamentalTypeKind::ULongLongInt } };
|
||||||
auto bool_ty = std::shared_ptr<types::Type>{
|
auto bool_ty = std::shared_ptr<types::Type>{
|
||||||
new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
|
new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
|
||||||
|
|
||||||
// Integer Increment/Decrement unaries
|
// Integer Increment/Decrement unaries
|
||||||
for (auto& ty : { int_ty, char_ty }) {
|
for (auto& ty : {
|
||||||
|
short_int_ty, int_ty, long_int_ty, long_long_int_ty, char_ty,
|
||||||
|
ushort_int_ty, uint_ty, ulong_int_ty, ulong_long_int_ty, uchar_ty,
|
||||||
|
}) {
|
||||||
definitions.push_back(UnopDefinition{
|
definitions.push_back(UnopDefinition{
|
||||||
ty, types::Unary::AddPostfix, ty,
|
ty, types::Unary::AddPostfix, ty,
|
||||||
[](codegen::Builder& builder, std::shared_ptr<Type> ty, llvm::Value* ptr) {
|
[](codegen::Builder& builder, std::shared_ptr<Type> ty, llvm::Value* ptr) {
|
||||||
@ -168,7 +187,11 @@ namespace types {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Not & Negation
|
// Not & Negation
|
||||||
for (auto& ty : { int_ty, char_ty, bool_ty }) {
|
for (auto& ty : {
|
||||||
|
short_int_ty, int_ty, long_int_ty, long_long_int_ty, char_ty,
|
||||||
|
ushort_int_ty, uint_ty, ulong_int_ty, ulong_long_int_ty, uchar_ty,
|
||||||
|
bool_ty
|
||||||
|
}) {
|
||||||
definitions.push_back(UnopDefinition{
|
definitions.push_back(UnopDefinition{
|
||||||
ty, types::Unary::Not, ty,
|
ty, types::Unary::Not, ty,
|
||||||
[](codegen::Builder& builder, std::shared_ptr<Type> ty, llvm::Value* value) {
|
[](codegen::Builder& builder, std::shared_ptr<Type> ty, llvm::Value* value) {
|
||||||
|
|||||||
@ -28,6 +28,8 @@ namespace types {
|
|||||||
new FundamentalType{ false, FundamentalTypeKind::ULongLongInt } };
|
new FundamentalType{ false, FundamentalTypeKind::ULongLongInt } };
|
||||||
auto bool_ty = std::shared_ptr<Type>{
|
auto bool_ty = std::shared_ptr<Type>{
|
||||||
new FundamentalType{ false, FundamentalTypeKind::Bool } };
|
new FundamentalType{ false, FundamentalTypeKind::Bool } };
|
||||||
|
auto any_int_ty = std::shared_ptr<Type>{
|
||||||
|
new FundamentalType{ false, FundamentalTypeKind::AnyInt } };
|
||||||
|
|
||||||
auto numerical_types = {
|
auto numerical_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,
|
||||||
@ -35,6 +37,13 @@ namespace types {
|
|||||||
bool_ty
|
bool_ty
|
||||||
};
|
};
|
||||||
|
|
||||||
|
for (auto& target_ty : numerical_types) {
|
||||||
|
casts.push_back(CastDefinition{ any_int_ty, target_ty, true,
|
||||||
|
[](codegen::Builder&, std::shared_ptr<Type>, llvm::Value* value) {
|
||||||
|
return value;
|
||||||
|
} });
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& source_ty : numerical_types) {
|
for (auto& source_ty : numerical_types) {
|
||||||
for (auto& target_ty : numerical_types) {
|
for (auto& target_ty : numerical_types) {
|
||||||
if (types::types_equal(source_ty, target_ty)) {
|
if (types::types_equal(source_ty, target_ty)) {
|
||||||
|
|||||||
@ -224,6 +224,10 @@ namespace AST {
|
|||||||
if (!rhs_res.ok())
|
if (!rhs_res.ok())
|
||||||
// Skip if not implicitly castable to lhs
|
// Skip if not implicitly castable to lhs
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
rhs_ty = this->m_rhs->typecheck(state, scope, binop.rhs).type;
|
||||||
|
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(binop, lhs_ty, rhs_ty), false, false };
|
||||||
}
|
}
|
||||||
@ -232,6 +236,9 @@ namespace AST {
|
|||||||
if (!lhs_res.ok())
|
if (!lhs_res.ok())
|
||||||
// Skip if not implicitly castable to rhs
|
// Skip if not implicitly castable to rhs
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
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);
|
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(binop, lhs_ty, rhs_ty), false, false };
|
||||||
}
|
}
|
||||||
@ -247,6 +254,8 @@ namespace AST {
|
|||||||
if (!result_res.ok())
|
if (!result_res.ok())
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
lhs_ty = this->m_lhs->typecheck(state, scope, binop.lhs).type;
|
||||||
|
rhs_ty = this->m_rhs->typecheck(state, scope, binop.rhs).type;
|
||||||
auto lhs_result = check_type(state, lhs_ty, binop.lhs);
|
auto lhs_result = check_type(state, lhs_ty, binop.lhs);
|
||||||
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);
|
||||||
|
|||||||
@ -70,6 +70,9 @@ namespace types {
|
|||||||
case FundamentalTypeKind::ULongLongInt:
|
case FundamentalTypeKind::ULongLongInt:
|
||||||
out << "ULongLongInt";
|
out << "ULongLongInt";
|
||||||
break;
|
break;
|
||||||
|
case FundamentalTypeKind::AnyInt:
|
||||||
|
out << "AnyInt";
|
||||||
|
break;
|
||||||
case FundamentalTypeKind::Bool:
|
case FundamentalTypeKind::Bool:
|
||||||
out << "Bool";
|
out << "Bool";
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -26,6 +26,9 @@ namespace types {
|
|||||||
ULongInt,
|
ULongInt,
|
||||||
ULongLongInt,
|
ULongLongInt,
|
||||||
|
|
||||||
|
/// @brief stand-in type for integer literals
|
||||||
|
AnyInt,
|
||||||
|
|
||||||
Bool,
|
Bool,
|
||||||
Char,
|
Char,
|
||||||
UChar,
|
UChar,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user