Allow implicit cast from char to int
This commit is contained in:
parent
e0f2a1620e
commit
28483812ea
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
#include "casting.h"
|
#include "casting.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace types {
|
namespace types {
|
||||||
std::vector<CastDefinition> create_casts() {
|
std::vector<CastDefinition> create_casts() {
|
||||||
@ -21,15 +22,21 @@ namespace types {
|
|||||||
[](codegen::Builder&, std::shared_ptr<Type>, llvm::Value* value) {
|
[](codegen::Builder&, std::shared_ptr<Type>, llvm::Value* value) {
|
||||||
return value;
|
return value;
|
||||||
} });
|
} });
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else if (target_ty->is_signed()) {
|
|
||||||
casts.push_back(CastDefinition{ source_ty, target_ty, false,
|
bool allow_implicit = false;
|
||||||
|
if (target_ty->size() >= source_ty->size())
|
||||||
|
allow_implicit = true;
|
||||||
|
|
||||||
|
if (target_ty->is_signed()) {
|
||||||
|
casts.push_back(CastDefinition{ source_ty, target_ty, allow_implicit,
|
||||||
[](codegen::Builder& builder, std::shared_ptr<Type> target, llvm::Value* value) {
|
[](codegen::Builder& builder, std::shared_ptr<Type> target, llvm::Value* value) {
|
||||||
return builder.builder->CreateSExtOrTrunc(value, target->codegen(builder), "cast");
|
return builder.builder->CreateSExtOrTrunc(value, target->codegen(builder), "cast");
|
||||||
} });
|
} });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
casts.push_back(CastDefinition{ source_ty, target_ty, false,
|
casts.push_back(CastDefinition{ source_ty, target_ty, allow_implicit,
|
||||||
[](codegen::Builder& builder, std::shared_ptr<Type> target, llvm::Value* value) {
|
[](codegen::Builder& builder, std::shared_ptr<Type> target, llvm::Value* value) {
|
||||||
return builder.builder->CreateZExtOrTrunc(value, target->codegen(builder), "cast");
|
return builder.builder->CreateZExtOrTrunc(value, target->codegen(builder), "cast");
|
||||||
} });
|
} });
|
||||||
|
|||||||
@ -15,9 +15,13 @@ namespace {
|
|||||||
std::shared_ptr<types::Type> result;
|
std::shared_ptr<types::Type> result;
|
||||||
};
|
};
|
||||||
|
|
||||||
Result<TypecheckRes, std::string> check_type(typecheck::State& state, std::shared_ptr<types::Type> checked, std::shared_ptr<types::Type> target) {
|
Result<TypecheckRes, std::string> check_type(
|
||||||
|
typecheck::State& state,
|
||||||
|
std::shared_ptr<types::Type> checked,
|
||||||
|
std::shared_ptr<types::Type> target) {
|
||||||
auto potential_cast = types::find_cast(state.casts, checked, target);
|
auto potential_cast = types::find_cast(state.casts, checked, target);
|
||||||
|
|
||||||
|
|
||||||
if (types::types_equal(checked, target)) {
|
if (types::types_equal(checked, target)) {
|
||||||
return TypecheckRes{ TypecheckResKind::Ok, target };
|
return TypecheckRes{ TypecheckResKind::Ok, target };
|
||||||
}
|
}
|
||||||
|
|||||||
@ -140,6 +140,19 @@ namespace types {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t FundamentalType::size() {
|
||||||
|
switch (this->m_ty) {
|
||||||
|
case FundamentalTypeKind::Int:
|
||||||
|
return 32;
|
||||||
|
case FundamentalTypeKind::Bool:
|
||||||
|
return 1;
|
||||||
|
case FundamentalTypeKind::Char:
|
||||||
|
return 8;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Invalid type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string FunctionType::formatted() {
|
std::string FunctionType::formatted() {
|
||||||
std::stringstream out{ "" };
|
std::stringstream out{ "" };
|
||||||
out << "(";
|
out << "(";
|
||||||
@ -170,6 +183,10 @@ namespace types {
|
|||||||
return std::pair(ptr, self);
|
return std::pair(ptr, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t FunctionType::size() {
|
||||||
|
return 64;
|
||||||
|
}
|
||||||
|
|
||||||
std::string PointerType::formatted() {
|
std::string PointerType::formatted() {
|
||||||
std::stringstream out{ "" };
|
std::stringstream out{ "" };
|
||||||
out << this->m_inner->formatted() << "*";
|
out << this->m_inner->formatted() << "*";
|
||||||
@ -183,6 +200,10 @@ namespace types {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t PointerType::size() {
|
||||||
|
return 64;
|
||||||
|
}
|
||||||
|
|
||||||
bool types_equal(std::shared_ptr<types::Type> type1, std::shared_ptr<types::Type> type2) {
|
bool types_equal(std::shared_ptr<types::Type> type1, std::shared_ptr<types::Type> type2) {
|
||||||
if (type1->m_kind != type2->m_kind)
|
if (type1->m_kind != type2->m_kind)
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -34,6 +34,7 @@ namespace types {
|
|||||||
virtual llvm::Value* lt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs);
|
virtual llvm::Value* lt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs);
|
||||||
virtual llvm::Value* gt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs);
|
virtual llvm::Value* gt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs);
|
||||||
virtual bool is_signed();
|
virtual bool is_signed();
|
||||||
|
virtual uint32_t size() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FundamentalType : public Type {
|
class FundamentalType : public Type {
|
||||||
@ -49,6 +50,7 @@ namespace types {
|
|||||||
virtual llvm::Value* lt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override;
|
virtual llvm::Value* lt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override;
|
||||||
virtual llvm::Value* gt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override;
|
virtual llvm::Value* gt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) override;
|
||||||
virtual bool is_signed() override;
|
virtual bool is_signed() override;
|
||||||
|
virtual uint32_t size() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -68,6 +70,7 @@ namespace types {
|
|||||||
virtual llvm::Type* codegen(codegen::Builder& builder) override;
|
virtual llvm::Type* codegen(codegen::Builder& builder) override;
|
||||||
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr) override;
|
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr) override;
|
||||||
virtual std::optional<std::shared_ptr<Type>> return_type() override;
|
virtual std::optional<std::shared_ptr<Type>> return_type() override;
|
||||||
|
virtual uint32_t size() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -82,6 +85,7 @@ namespace types {
|
|||||||
virtual std::string formatted() override;
|
virtual std::string formatted() override;
|
||||||
virtual llvm::Type* codegen(codegen::Builder& builder) override;
|
virtual llvm::Type* codegen(codegen::Builder& builder) override;
|
||||||
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr) override;
|
virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr) override;
|
||||||
|
virtual uint32_t size() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool types_equal(std::shared_ptr<types::Type> type1, std::shared_ptr<types::Type> type2);
|
bool types_equal(std::shared_ptr<types::Type> type1, std::shared_ptr<types::Type> type2);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user