Allow implicit cast from char to int
This commit is contained in:
parent
e0f2a1620e
commit
28483812ea
@ -1,5 +1,6 @@
|
||||
|
||||
#include "casting.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace types {
|
||||
std::vector<CastDefinition> create_casts() {
|
||||
@ -21,15 +22,21 @@ namespace types {
|
||||
[](codegen::Builder&, std::shared_ptr<Type>, llvm::Value* 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) {
|
||||
return builder.builder->CreateSExtOrTrunc(value, target->codegen(builder), "cast");
|
||||
} });
|
||||
}
|
||||
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) {
|
||||
return builder.builder->CreateZExtOrTrunc(value, target->codegen(builder), "cast");
|
||||
} });
|
||||
|
||||
@ -15,9 +15,13 @@ namespace {
|
||||
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);
|
||||
|
||||
|
||||
if (types::types_equal(checked, 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::stringstream out{ "" };
|
||||
out << "(";
|
||||
@ -170,6 +183,10 @@ namespace types {
|
||||
return std::pair(ptr, self);
|
||||
}
|
||||
|
||||
uint32_t FunctionType::size() {
|
||||
return 64;
|
||||
}
|
||||
|
||||
std::string PointerType::formatted() {
|
||||
std::stringstream out{ "" };
|
||||
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) {
|
||||
if (type1->m_kind != type2->m_kind)
|
||||
return false;
|
||||
|
||||
@ -34,6 +34,7 @@ namespace types {
|
||||
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 bool is_signed();
|
||||
virtual uint32_t size() = 0;
|
||||
};
|
||||
|
||||
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* gt(codegen::Builder& builder, llvm::Value* lhs, llvm::Value* rhs) 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 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 uint32_t size() override;
|
||||
};
|
||||
|
||||
|
||||
@ -82,6 +85,7 @@ namespace types {
|
||||
virtual std::string formatted() 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 uint32_t size() override;
|
||||
};
|
||||
|
||||
bool types_equal(std::shared_ptr<types::Type> type1, std::shared_ptr<types::Type> type2);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user