Add const-ability to types

This commit is contained in:
Sofia 2026-04-16 19:43:36 +03:00
parent f9208a525d
commit 8e6980715e
8 changed files with 105 additions and 82 deletions

View File

@ -52,7 +52,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{types::FundamentalTypeKind::Int} new types::FundamentalType{true, types::FundamentalTypeKind::Int}
} } } { } } } {
} }
virtual ~IntLiteralExpression() override = default; virtual ~IntLiteralExpression() override = default;

View File

@ -6,11 +6,11 @@ namespace types {
std::vector<BinopDefinition> definitions{}; std::vector<BinopDefinition> definitions{};
auto int_ty = std::shared_ptr<types::Type>{ auto int_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ types::FundamentalTypeKind::Int } }; new types::FundamentalType{ false, types::FundamentalTypeKind::Int } };
auto char_ty = std::shared_ptr<types::Type>{ auto char_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ types::FundamentalTypeKind::Char } }; new types::FundamentalType{ false, types::FundamentalTypeKind::Char } };
auto bool_ty = std::shared_ptr<types::Type>{ auto bool_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ types::FundamentalTypeKind::Bool } }; new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
// Integer arithmetic binops // Integer arithmetic binops
for (auto& ty : { int_ty, char_ty, bool_ty }) { for (auto& ty : { int_ty, char_ty, bool_ty }) {
@ -40,7 +40,7 @@ namespace types {
}, },
[](BinopDefinition&, std::shared_ptr<types::Type>, std::shared_ptr<types::Type>) { [](BinopDefinition&, std::shared_ptr<types::Type>, std::shared_ptr<types::Type>) {
return std::shared_ptr<types::Type>{ return std::shared_ptr<types::Type>{
new types::FundamentalType{ types::FundamentalTypeKind::Bool } }; new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
} }
}); });
@ -51,7 +51,7 @@ namespace types {
}, },
[](BinopDefinition&, std::shared_ptr<types::Type>, std::shared_ptr<types::Type>) { [](BinopDefinition&, std::shared_ptr<types::Type>, std::shared_ptr<types::Type>) {
return std::shared_ptr<types::Type>{ return std::shared_ptr<types::Type>{
new types::FundamentalType{ types::FundamentalTypeKind::Bool } }; new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
} }
}); });
} }
@ -65,7 +65,7 @@ namespace types {
}, },
[](BinopDefinition&, std::shared_ptr<types::Type>, std::shared_ptr<types::Type>) { [](BinopDefinition&, std::shared_ptr<types::Type>, std::shared_ptr<types::Type>) {
return std::shared_ptr<types::Type>{ return std::shared_ptr<types::Type>{
new types::FundamentalType{ types::FundamentalTypeKind::Bool } }; new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
} }
}); });
@ -76,7 +76,7 @@ namespace types {
}, },
[](BinopDefinition&, std::shared_ptr<types::Type>, std::shared_ptr<types::Type>) { [](BinopDefinition&, std::shared_ptr<types::Type>, std::shared_ptr<types::Type>) {
return std::shared_ptr<types::Type>{ return std::shared_ptr<types::Type>{
new types::FundamentalType{ types::FundamentalTypeKind::Bool } }; new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
} }
}); });
} }

View File

@ -7,11 +7,11 @@ namespace types {
std::vector<CastDefinition> casts{}; std::vector<CastDefinition> casts{};
auto int_ty = std::shared_ptr<Type>{ auto int_ty = std::shared_ptr<Type>{
new FundamentalType{ FundamentalTypeKind::Int } }; new FundamentalType{ false, FundamentalTypeKind::Int } };
auto char_ty = std::shared_ptr<Type>{ auto char_ty = std::shared_ptr<Type>{
new FundamentalType{ FundamentalTypeKind::Char } }; new FundamentalType{ false, FundamentalTypeKind::Char } };
auto bool_ty = std::shared_ptr<Type>{ auto bool_ty = std::shared_ptr<Type>{
new FundamentalType{ FundamentalTypeKind::Bool } }; new FundamentalType{ false, FundamentalTypeKind::Bool } };
auto numerical_types = { int_ty, char_ty, bool_ty }; auto numerical_types = { int_ty, char_ty, bool_ty };

View File

@ -31,7 +31,7 @@ namespace AST {
std::shared_ptr<types::Type> StringLiteralExpression::get_codegen_type(codegen::Scope&) { std::shared_ptr<types::Type> StringLiteralExpression::get_codegen_type(codegen::Scope&) {
auto stack_type = new types::ArrayType{ auto stack_type = new types::ArrayType{
std::make_unique<types::FundamentalType>(types::FundamentalTypeKind::Char), std::make_shared<types::FundamentalType>(true, types::FundamentalTypeKind::Char),
static_cast<uint32_t>(this->m_value.size()) + 1, static_cast<uint32_t>(this->m_value.size()) + 1,
true true
}; };
@ -40,7 +40,7 @@ namespace AST {
codegen::StackValue StringLiteralExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) { codegen::StackValue StringLiteralExpression::codegen(codegen::Builder& builder, codegen::Scope& scope) {
auto stack_type = new types::ArrayType{ auto stack_type = new types::ArrayType{
std::make_unique<types::FundamentalType>(types::FundamentalTypeKind::Char), std::make_shared<types::FundamentalType>(true, types::FundamentalTypeKind::Char),
static_cast<uint32_t>(this->m_value.size()) + 1, static_cast<uint32_t>(this->m_value.size()) + 1,
true true
}; };
@ -52,7 +52,7 @@ namespace AST {
return codegen::StackValue{ return codegen::StackValue{
global_str, global_str,
std::unique_ptr<types::Type>{ std::unique_ptr<types::Type>{
new types::PointerType { std::shared_ptr<types::Type> {stack_type } } new types::PointerType { false, std::shared_ptr<types::Type> {stack_type } }
}, },
}; };
} }
@ -205,7 +205,7 @@ namespace AST {
std::shared_ptr<types::Type> RefExpression::get_codegen_type(codegen::Scope& scope) { std::shared_ptr<types::Type> RefExpression::get_codegen_type(codegen::Scope& scope) {
return std::shared_ptr<types::Type> { return std::shared_ptr<types::Type> {
new types::PointerType{ this->m_expr->get_codegen_type(scope) } new types::PointerType{ false, this->m_expr->get_codegen_type(scope) }
}; };
} }
@ -283,7 +283,7 @@ namespace AST {
auto gep_value = builder.builder->CreateGEP(array_ty->m_inner->codegen(builder, scope.structs), value.value, idx_list, "GEP"); auto gep_value = builder.builder->CreateGEP(array_ty->m_inner->codegen(builder, scope.structs), value.value, idx_list, "GEP");
auto ptr_ty = std::shared_ptr<types::Type>{ auto ptr_ty = std::shared_ptr<types::Type>{
new types::PointerType { array_ty->m_inner} new types::PointerType { array_ty->m_inner->m_const, array_ty->m_inner}
}; };
if (scope.is_lvalue) { if (scope.is_lvalue) {
@ -347,7 +347,7 @@ namespace AST {
ptr_ty->m_inner->codegen(builder, scope.structs), struct_ptr.value, idx); ptr_ty->m_inner->codegen(builder, scope.structs), struct_ptr.value, idx);
auto ptr_ty = std::shared_ptr<types::Type>{ auto ptr_ty = std::shared_ptr<types::Type>{
new types::PointerType { field_ty } new types::PointerType { field_ty->m_const, field_ty }
}; };
if (scope.is_lvalue) { if (scope.is_lvalue) {
@ -392,7 +392,7 @@ namespace AST {
} }
auto ptr_ty = std::shared_ptr<types::Type>{ auto ptr_ty = std::shared_ptr<types::Type>{
new types::PointerType{this->m_ty} new types::PointerType{this->m_ty->m_const, this->m_ty}
}; };
if (scope.is_lvalue) { if (scope.is_lvalue) {
@ -416,7 +416,7 @@ namespace AST {
} }
auto ptr_ty = std::shared_ptr<types::Type>{ auto ptr_ty = std::shared_ptr<types::Type>{
new types::PointerType{this->m_ty} new types::PointerType{this->m_ty->m_const, this->m_ty}
}; };
if (scope.is_lvalue) { if (scope.is_lvalue) {
@ -481,7 +481,9 @@ namespace AST {
builder.builder->CreateStore(value.value, ptr, false); builder.builder->CreateStore(value.value, ptr, false);
} }
auto ptr_ty = std::shared_ptr<types::Type>{ new types::PointerType{ this->m_type } }; auto ptr_ty = std::shared_ptr<types::Type>{
new types::PointerType{ this->m_type->m_const, this->m_type }
};
scope.values[this->m_name] = codegen::StackValue{ ptr, ptr_ty }; scope.values[this->m_name] = codegen::StackValue{ ptr, ptr_ty };
} }
@ -530,7 +532,9 @@ namespace AST {
param_ty_ptrs.push_back(param.second); param_ty_ptrs.push_back(param.second);
} }
auto fn_ty_ptr = std::shared_ptr<types::Type>{ new types::FunctionType{ ret_ty_ptr, param_ty_ptrs, this->m_is_vararg } }; auto fn_ty_ptr = std::shared_ptr<types::Type>{
new types::FunctionType{ true, ret_ty_ptr, param_ty_ptrs, this->m_is_vararg }
};
auto fn_ty = fn_ty_ptr->codegen(builder, scope.structs); auto fn_ty = fn_ty_ptr->codegen(builder, scope.structs);
auto function = llvm::Function::Create( auto function = llvm::Function::Create(
@ -568,7 +572,7 @@ namespace AST {
builder.builder->SetInsertPoint(BB); builder.builder->SetInsertPoint(BB);
auto arg_ptr = builder.builder->CreateAlloca(param_ty_ptrs[counter]->codegen(builder, scope.structs)); auto arg_ptr = builder.builder->CreateAlloca(param_ty_ptrs[counter]->codegen(builder, scope.structs));
auto param_ty_ptr = std::shared_ptr<types::Type>{ auto param_ty_ptr = std::shared_ptr<types::Type>{
new types::PointerType { param_ty_ptrs[counter]} new types::PointerType { true, param_ty_ptrs[counter]}
}; };
auto arg = function->getArg(counter++); auto arg = function->getArg(counter++);
builder.builder->CreateStore(arg, arg_ptr); builder.builder->CreateStore(arg, arg_ptr);

View File

@ -12,6 +12,11 @@ namespace parsing {
Result<std::shared_ptr<types::Type>, std::string> parse_type(token::TokenStream& stream, Scope& scope) { Result<std::shared_ptr<types::Type>, std::string> parse_type(token::TokenStream& stream, Scope& scope) {
token::TokenStream inner{ stream }; token::TokenStream inner{ stream };
try { try {
bool is_const = false;
if (inner.peek().type == token::Type::Ident && inner.peek().content == "const") {
is_const = true;
}
auto token = inner.expect(token::Type::Ident); auto token = inner.expect(token::Type::Ident);
std::shared_ptr<types::Type> returned{}; std::shared_ptr<types::Type> returned{};
@ -56,7 +61,14 @@ namespace parsing {
if (struct_name && !maybe_fields && scope.structs.find(*struct_name) != scope.structs.end()) { if (struct_name && !maybe_fields && scope.structs.find(*struct_name) != scope.structs.end()) {
auto original_ty = scope.structs[*struct_name]; auto original_ty = scope.structs[*struct_name];
auto original_struct_ty = dynamic_cast<types::StructType*>(original_ty.get()); auto original_struct_ty = dynamic_cast<types::StructType*>(original_ty.get());
auto ty = new types::StructType{ struct_name, original_struct_ty->m_fields, true, false, original_struct_ty->m_id }; auto ty = new types::StructType{
is_const,
struct_name,
original_struct_ty->m_fields,
true,
false,
original_struct_ty->m_id
};
returned = std::shared_ptr<types::Type>{ ty }; returned = std::shared_ptr<types::Type>{ ty };
} }
else { else {
@ -64,16 +76,37 @@ namespace parsing {
auto original_ty = scope.structs[*struct_name]; auto original_ty = scope.structs[*struct_name];
auto original_struct_ty = dynamic_cast<types::StructType*>(original_ty.get()); auto original_struct_ty = dynamic_cast<types::StructType*>(original_ty.get());
if (!original_struct_ty->m_fields.has_value()) { if (!original_struct_ty->m_fields.has_value()) {
auto ty = new types::StructType{ struct_name, maybe_fields, false, true, original_struct_ty->m_id }; auto ty = new types::StructType{
is_const,
struct_name,
maybe_fields,
false,
true,
original_struct_ty->m_id
};
returned = std::shared_ptr<types::Type>{ ty }; returned = std::shared_ptr<types::Type>{ ty };
} }
else { else {
auto ty = new types::StructType{ struct_name, maybe_fields, false, false, struct_id_counter++ }; auto ty = new types::StructType{
is_const,
struct_name,
maybe_fields,
false,
false,
struct_id_counter++
};
returned = std::shared_ptr<types::Type>{ ty }; returned = std::shared_ptr<types::Type>{ ty };
} }
} }
else { else {
auto ty = new types::StructType{ struct_name, maybe_fields, false, false, struct_id_counter++ }; auto ty = new types::StructType{
is_const,
struct_name,
maybe_fields,
false,
false,
struct_id_counter++
};
returned = std::shared_ptr<types::Type>{ ty }; returned = std::shared_ptr<types::Type>{ ty };
} }
} }
@ -83,15 +116,15 @@ namespace parsing {
std::string type_name = token.content; std::string type_name = token.content;
if (type_name == "int") { if (type_name == "int") {
auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Int }; auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::Int };
returned = std::shared_ptr<types::Type>{ ty }; returned = std::shared_ptr<types::Type>{ ty };
} }
else if (type_name == "char") { else if (type_name == "char") {
auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Char }; auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::Char };
returned = std::shared_ptr<types::Type>{ ty }; returned = std::shared_ptr<types::Type>{ ty };
} }
else if (type_name == "void") { else if (type_name == "void") {
auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Void }; auto ty = new types::FundamentalType{ is_const, types::FundamentalTypeKind::Void };
returned = std::shared_ptr<types::Type>{ ty }; returned = std::shared_ptr<types::Type>{ ty };
} }
else { else {
@ -101,7 +134,12 @@ namespace parsing {
while (inner.peek().type == token::Type::Symbol && inner.peek().content == "*") { while (inner.peek().type == token::Type::Symbol && inner.peek().content == "*") {
inner.next(); inner.next();
auto ty = new types::PointerType{ std::move(returned) }; auto ptr_const = false;
if (inner.peek().type == token::Type::Ident && inner.peek().content == "const") {
inner.next();
ptr_const = true;
}
auto ty = new types::PointerType{ ptr_const, std::move(returned) };
returned = std::shared_ptr<types::Type>{ ty }; returned = std::shared_ptr<types::Type>{ ty };
} }
@ -162,7 +200,7 @@ namespace parsing {
before_meta + inner.metadata(), before_meta + inner.metadata(),
std::move(expressions), std::move(expressions),
std::shared_ptr<types::Type> { std::shared_ptr<types::Type> {
new types::FundamentalType{ types::FundamentalTypeKind::Any } new types::FundamentalType{ true, types::FundamentalTypeKind::Any }
}) })
}; };
} }
@ -390,16 +428,9 @@ namespace parsing {
auto array_postfix = parse_array_postfix(inner, false, scope); auto array_postfix = parse_array_postfix(inner, false, scope);
while (array_postfix.ok()) { while (array_postfix.ok()) {
auto postfix = array_postfix.unwrap(); auto postfix = array_postfix.unwrap();
if (postfix) { ty = std::shared_ptr<types::Type>{
ty = std::shared_ptr<types::Type>{ new types::ArrayType(ty, *postfix, false)
new types::ArrayType(ty, *postfix, false) };
};
}
else {
ty = std::shared_ptr<types::Type>{
new types::PointerType(ty)
};
}
array_postfix = parse_array_postfix(inner, false, scope); array_postfix = parse_array_postfix(inner, false, scope);
} }
@ -516,7 +547,7 @@ namespace parsing {
} }
else { else {
param_ty = std::shared_ptr<types::Type>{ param_ty = std::shared_ptr<types::Type>{
new types::PointerType(param_ty) new types::PointerType(true, param_ty)
}; };
} }
postfix = parse_array_postfix(inner, true, scope); postfix = parse_array_postfix(inner, true, scope);

View File

@ -136,7 +136,7 @@ namespace AST {
std::optional<std::shared_ptr<types::Type>> std::optional<std::shared_ptr<types::Type>>
) { ) {
auto char_ty = std::shared_ptr<types::Type>{ auto char_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ types::FundamentalTypeKind::Char } new types::FundamentalType{ true, types::FundamentalTypeKind::Char }
}; };
auto ptr_ty = new types::ArrayType{ char_ty, static_cast<uint32_t>(this->m_value.size()) + 1, true }; auto ptr_ty = new types::ArrayType{ char_ty, static_cast<uint32_t>(this->m_value.size()) + 1, true };
return { std::shared_ptr<types::Type>{ptr_ty}, true, false }; return { std::shared_ptr<types::Type>{ptr_ty}, true, false };
@ -155,7 +155,7 @@ namespace AST {
state.errors.push_back(CompileError("Value " + this->m_name + " not defined", this->m_meta)); state.errors.push_back(CompileError("Value " + this->m_name + " not defined", this->m_meta));
return { std::shared_ptr<types::Type>{ return { std::shared_ptr<types::Type>{
new types::FundamentalType{ types::FundamentalTypeKind::Void } new types::FundamentalType{ false, types::FundamentalTypeKind::Void }
}, false, true }; }, false, true };
} }
@ -255,7 +255,7 @@ namespace AST {
this->m_meta)); this->m_meta));
return { std::shared_ptr<types::Type>{ return { std::shared_ptr<types::Type>{
new types::FundamentalType{ types::FundamentalTypeKind::Void } }, false, false }; new types::FundamentalType{ false, types::FundamentalTypeKind::Void } }, false, false };
} }
void FunctionCallExpression::typecheck_preprocess(typecheck::Scope& scope) { void FunctionCallExpression::typecheck_preprocess(typecheck::Scope& scope) {
@ -275,7 +275,7 @@ namespace AST {
if (expr_ty->m_kind != types::TypeKind::Function) { if (expr_ty->m_kind != types::TypeKind::Function) {
state.errors.push_back(CompileError("Tried calling a non-function", this->m_meta)); state.errors.push_back(CompileError("Tried calling a non-function", this->m_meta));
return { std::shared_ptr<types::Type> { return { std::shared_ptr<types::Type> {
new types::FundamentalType{ types::FundamentalTypeKind::Void } new types::FundamentalType{ false, types::FundamentalTypeKind::Void }
}, false, false }; }, false, false };
} }
@ -324,6 +324,7 @@ namespace AST {
+ expr_ty->formatted() + "to type " + this->m_ty->formatted() + expr_ty->formatted() + "to type " + this->m_ty->formatted()
+ " is not permitted", this->m_meta)); + " is not permitted", this->m_meta));
return { std::shared_ptr<types::Type> { new types::FundamentalType{ return { std::shared_ptr<types::Type> { new types::FundamentalType{
false,
types::FundamentalTypeKind::Void types::FundamentalTypeKind::Void
} }, false, false }; } }, false, false };
} }
@ -339,7 +340,7 @@ namespace AST {
) { ) {
auto expr_ty = this->m_expr->typecheck(state, scope, {}).type; auto expr_ty = this->m_expr->typecheck(state, scope, {}).type;
return { std::shared_ptr<types::Type> { return { std::shared_ptr<types::Type> {
new types::PointerType{ expr_ty } new types::PointerType{ false, expr_ty }
}, false, false }; }, false, false };
} }
@ -357,7 +358,7 @@ namespace AST {
state.errors.push_back( state.errors.push_back(
CompileError("Tried to deref " + expr_ty.type->formatted(), this->m_meta)); CompileError("Tried to deref " + expr_ty.type->formatted(), this->m_meta));
return { std::shared_ptr<types::Type> { return { std::shared_ptr<types::Type> {
new types::FundamentalType{ types::FundamentalTypeKind::Void } new types::FundamentalType{ false, types::FundamentalTypeKind::Void }
}, false, expr_ty.lvalue }; }, false, expr_ty.lvalue };
} }
auto ptr_ty = dynamic_cast<types::PointerType*>(expr_ty.type.get()); auto ptr_ty = dynamic_cast<types::PointerType*>(expr_ty.type.get());
@ -378,7 +379,7 @@ namespace AST {
state.errors.push_back( state.errors.push_back(
CompileError("Tried to index " + expr_ty.type->formatted(), this->m_meta)); CompileError("Tried to index " + expr_ty.type->formatted(), this->m_meta));
return { std::shared_ptr<types::Type> { return { std::shared_ptr<types::Type> {
new types::FundamentalType{ types::FundamentalTypeKind::Void } new types::FundamentalType{ false, types::FundamentalTypeKind::Void }
}, false, expr_ty.lvalue }; }, false, expr_ty.lvalue };
} }
if (expr_ty.type->m_kind == types::TypeKind::Pointer) { if (expr_ty.type->m_kind == types::TypeKind::Pointer) {
@ -392,7 +393,7 @@ namespace AST {
// Default return type // Default return type
return { std::shared_ptr<types::Type> { return { std::shared_ptr<types::Type> {
new types::FundamentalType{ types::FundamentalTypeKind::Void } new types::FundamentalType{ false, types::FundamentalTypeKind::Void }
}, false, expr_ty.lvalue }; }, false, expr_ty.lvalue };
} }
@ -410,7 +411,7 @@ namespace AST {
state.errors.push_back( state.errors.push_back(
CompileError("Tried to access " + expr_ty.type->formatted() + "." + this->m_field, this->m_meta)); CompileError("Tried to access " + expr_ty.type->formatted() + "." + this->m_field, this->m_meta));
return { std::shared_ptr<types::Type> { return { std::shared_ptr<types::Type> {
new types::FundamentalType{ types::FundamentalTypeKind::Void } new types::FundamentalType{ false, types::FundamentalTypeKind::Void }
}, false, expr_ty.lvalue }; }, false, expr_ty.lvalue };
} }
@ -423,13 +424,13 @@ namespace AST {
} }
state.errors.push_back(CompileError("No such field", this->m_meta)); state.errors.push_back(CompileError("No such field", this->m_meta));
return { std::shared_ptr<types::Type> { return { std::shared_ptr<types::Type> {
new types::FundamentalType{ types::FundamentalTypeKind::Void } new types::FundamentalType{ false, types::FundamentalTypeKind::Void }
}, false, expr_ty.lvalue }; }, false, expr_ty.lvalue };
} }
state.errors.push_back(CompileError("Cannot access fields of opaque struct", this->m_meta)); state.errors.push_back(CompileError("Cannot access fields of opaque struct", this->m_meta));
return { std::shared_ptr<types::Type> { return { std::shared_ptr<types::Type> {
new types::FundamentalType{ types::FundamentalTypeKind::Void } new types::FundamentalType{ false, types::FundamentalTypeKind::Void }
}, false, expr_ty.lvalue }; }, false, expr_ty.lvalue };
} }
@ -499,7 +500,7 @@ namespace AST {
} }
else { else {
return { std::shared_ptr<types::Type> { return { std::shared_ptr<types::Type> {
new types::FundamentalType{ types::FundamentalTypeKind::Void } new types::FundamentalType{ false, types::FundamentalTypeKind::Void }
}, true, false }; }, true, false };
} }
@ -511,7 +512,7 @@ namespace AST {
if (this->m_expressions.size() == 0) { if (this->m_expressions.size() == 0) {
this->m_ty = std::shared_ptr<types::Type>{ this->m_ty = std::shared_ptr<types::Type>{
new types::ArrayType{ new types::ArrayType{
std::make_shared<types::FundamentalType>(types::FundamentalTypeKind::Void), std::make_shared<types::FundamentalType>(true, types::FundamentalTypeKind::Void),
0, 0,
true true
} }
@ -585,7 +586,7 @@ namespace AST {
void IfStatement::typecheck(typecheck::State& state, typecheck::Scope& scope) { void IfStatement::typecheck(typecheck::State& state, typecheck::Scope& scope) {
auto bool_ty = std::shared_ptr<types::Type>{ auto bool_ty = std::shared_ptr<types::Type>{
new types::FundamentalType{ types::FundamentalTypeKind::Bool } }; new types::FundamentalType{ false, types::FundamentalTypeKind::Bool } };
auto expr_ty = this->m_condition->typecheck(state, scope, bool_ty).type; auto expr_ty = this->m_condition->typecheck(state, scope, bool_ty).type;
auto check_res = check_type(state, expr_ty, bool_ty); auto check_res = check_type(state, expr_ty, bool_ty);
@ -617,7 +618,7 @@ namespace AST {
param_tys.push_back(param.second); param_tys.push_back(param.second);
} }
auto function_ty = new types::FunctionType{ return_ty, param_tys, this->m_is_vararg }; auto function_ty = new types::FunctionType{ true, return_ty, param_tys, this->m_is_vararg };
scope.symbols[this->m_name] = std::shared_ptr<types::Type>{ function_ty }; scope.symbols[this->m_name] = std::shared_ptr<types::Type>{ function_ty };
typecheck::Scope inner{ scope }; typecheck::Scope inner{ scope };

View File

@ -27,7 +27,9 @@ namespace types {
class Type { class Type {
public: public:
TypeKind m_kind; TypeKind m_kind;
Type(TypeKind kind) : m_kind{ kind } {} bool m_const;
Type(TypeKind kind, bool is_const) : m_kind{ kind }, m_const{ is_const } {}
virtual ~Type() = default; virtual ~Type() = default;
virtual std::string formatted() = 0; virtual std::string formatted() = 0;
virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) = 0; virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) = 0;
@ -40,7 +42,7 @@ namespace types {
class FundamentalType : public Type { class FundamentalType : public Type {
public: public:
FundamentalTypeKind m_ty; FundamentalTypeKind m_ty;
FundamentalType(FundamentalTypeKind kind) : Type(TypeKind::Fundamental), m_ty{ kind } {} FundamentalType(bool is_const, FundamentalTypeKind kind) : Type(TypeKind::Fundamental, is_const), m_ty{ kind } {}
virtual ~FundamentalType() override = default; virtual ~FundamentalType() override = default;
virtual std::string formatted() override; virtual std::string formatted() override;
virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override; virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override;
@ -55,8 +57,8 @@ namespace types {
std::shared_ptr<Type> m_ret_ty; std::shared_ptr<Type> m_ret_ty;
std::vector<std::shared_ptr<Type>> m_param_tys; std::vector<std::shared_ptr<Type>> m_param_tys;
bool m_vararg; bool m_vararg;
FunctionType(std::shared_ptr<Type> ret_ty, std::vector<std::shared_ptr<Type>> param_tys, bool vararg) FunctionType(bool is_const, std::shared_ptr<Type> ret_ty, std::vector<std::shared_ptr<Type>> param_tys, bool vararg)
: Type(TypeKind::Function) : Type(TypeKind::Function, is_const)
, m_ret_ty{ std::move(ret_ty) } , m_ret_ty{ std::move(ret_ty) }
, m_param_tys{ std::move(param_tys) } , m_param_tys{ std::move(param_tys) }
, m_vararg{ vararg } { , m_vararg{ vararg } {
@ -73,8 +75,8 @@ namespace types {
public: public:
std::shared_ptr<Type> m_inner; std::shared_ptr<Type> m_inner;
PointerType(std::shared_ptr<Type> inner) PointerType(bool is_const, std::shared_ptr<Type> inner)
: Type(TypeKind::Pointer), m_inner{ std::move(inner) } { : Type(TypeKind::Pointer, is_const), m_inner{ std::move(inner) } {
} }
virtual ~PointerType() override = default; virtual ~PointerType() override = default;
virtual std::string formatted() override; virtual std::string formatted() override;
@ -90,7 +92,7 @@ namespace types {
bool m_raw; bool m_raw;
ArrayType(std::shared_ptr<Type> inner, uint32_t size, bool raw) ArrayType(std::shared_ptr<Type> inner, uint32_t size, bool raw)
: Type(TypeKind::Array), m_inner{ std::move(inner) }, m_size{ size }, m_raw{ raw } { : Type(TypeKind::Array, true), m_inner{ std::move(inner) }, m_size{ size }, m_raw{ raw } {
} }
virtual ~ArrayType() override = default; virtual ~ArrayType() override = default;
virtual std::string formatted() override; virtual std::string formatted() override;
@ -109,8 +111,8 @@ namespace types {
bool m_is_def; bool m_is_def;
uint32_t m_id; uint32_t m_id;
StructType(std::optional<std::string> name, std::optional<std::vector<StructField>> fields, bool is_ref, bool is_def, uint32_t id) StructType(bool is_const, std::optional<std::string> name, std::optional<std::vector<StructField>> fields, bool is_ref, bool is_def, uint32_t id)
: Type(TypeKind::Struct), m_name{ name }, m_fields{ fields }, m_is_ref{ is_ref }, m_is_def{ is_def }, m_id{ id } { : Type(TypeKind::Struct, is_const), m_name{ name }, m_fields{ fields }, m_is_ref{ is_ref }, m_is_def{ is_def }, m_id{ id } {
} }
virtual ~StructType() override = default; virtual ~StructType() override = default;
virtual std::string formatted() override; virtual std::string formatted() override;
@ -119,21 +121,6 @@ namespace types {
virtual uint32_t size() override; virtual uint32_t size() override;
}; };
// class StructRef : public Type {
// public:
// std::string m_name;
// std::shared_ptr<types::Type> m_referred;
// StructRef(std::string name, std::shared_ptr<types::Type> referred)
// : Type(TypeKind::StructRef), m_name{ name }, m_referred{ referred } {
// }
// virtual ~StructRef() override = default;
// virtual std::string formatted() override;
// virtual llvm::Type* codegen(codegen::Builder& builder, codegen::TypeMap& structs) override;
// virtual std::pair<llvm::Value*, std::shared_ptr<Type>> load(codegen::Builder& builder, llvm::Value* ptr, codegen::TypeMap& structs) 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);
} }

2
test.c
View File

@ -6,7 +6,7 @@ int fibonacci(int n) {
return fibonacci(n - 1) + fibonacci(n - 2); return fibonacci(n - 1) + fibonacci(n - 2);
} }
void change_first(char otus[]) { void change_first(char* otus) {
otus[0] = 115; otus[0] = 115;
} }