Parse struct type
This commit is contained in:
parent
f283149090
commit
94d1c15897
@ -283,8 +283,6 @@ namespace AST {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ptr_ty->m_inner->m_kind == types::TypeKind::Array) {
|
else if (ptr_ty->m_inner->m_kind == types::TypeKind::Array) {
|
||||||
std::cout << ptr_ty->m_inner->formatted() << std::endl;
|
|
||||||
|
|
||||||
// Must be an array otherwise
|
// Must be an array otherwise
|
||||||
auto arr_ty = dynamic_cast<types::ArrayType*>(ptr_ty->m_inner.get());
|
auto arr_ty = dynamic_cast<types::ArrayType*>(ptr_ty->m_inner.get());
|
||||||
auto gep_value = builder.builder->CreateGEP(arr_ty->m_inner->codegen(builder, scope.structs), value.value, idx_list, "GEP");
|
auto gep_value = builder.builder->CreateGEP(arr_ty->m_inner->codegen(builder, scope.structs), value.value, idx_list, "GEP");
|
||||||
|
|||||||
@ -165,7 +165,7 @@ std::optional<CompileOutput> compile(std::string_view in_filename) {
|
|||||||
builder.mod->print(llvm_ir_dest, nullptr);
|
builder.mod->print(llvm_ir_dest, nullptr);
|
||||||
llvm_ir_dest.flush();
|
llvm_ir_dest.flush();
|
||||||
|
|
||||||
std::cout << llvm_ir_string << std::endl;
|
// std::cout << llvm_ir_string << std::endl;
|
||||||
|
|
||||||
// Print output to obj-file
|
// Print output to obj-file
|
||||||
std::error_code EC;
|
std::error_code EC;
|
||||||
|
|||||||
@ -7,30 +7,80 @@ namespace parsing {
|
|||||||
namespace {
|
namespace {
|
||||||
Result<std::unique_ptr<AST::Expression>, std::string> parse_expression(token::TokenStream& stream, Scope& scope);
|
Result<std::unique_ptr<AST::Expression>, std::string> parse_expression(token::TokenStream& stream, Scope& scope);
|
||||||
|
|
||||||
Result<std::shared_ptr<types::Type>, std::string> parse_type(token::TokenStream& stream, 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 {
|
||||||
auto token = inner.expect(token::Type::Ident);
|
auto token = inner.expect(token::Type::Ident);
|
||||||
|
|
||||||
// TODO eventually make this be potentially more than one word
|
|
||||||
std::string type_name = token.content;
|
|
||||||
|
|
||||||
std::shared_ptr<types::Type> returned{};
|
std::shared_ptr<types::Type> returned{};
|
||||||
|
|
||||||
if (type_name == "int") {
|
if (token.content == "struct") {
|
||||||
auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Int };
|
std::optional<std::string> struct_name{};
|
||||||
returned = std::shared_ptr<types::Type>{ ty };
|
|
||||||
}
|
if (inner.peek().type == token::Type::Ident) {
|
||||||
else if (type_name == "char") {
|
struct_name = inner.expect(token::Type::Ident).content;
|
||||||
auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Char };
|
}
|
||||||
returned = std::shared_ptr<types::Type>{ ty };
|
|
||||||
}
|
std::optional<std::vector<types::StructField>> maybe_fields{};
|
||||||
else if (type_name == "void") {
|
|
||||||
auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Void };
|
if (inner.peek().content == "{") {
|
||||||
returned = std::shared_ptr<types::Type>{ ty };
|
std::vector<types::StructField> fields{};
|
||||||
|
|
||||||
|
inner.expect(token::Type::Symbol, "{");
|
||||||
|
|
||||||
|
int counter = 0;
|
||||||
|
while (inner.peek().content != "}") {
|
||||||
|
if (counter++ > 0)
|
||||||
|
inner.expect(token::Type::Symbol, ";");
|
||||||
|
|
||||||
|
auto ty = parse_type(inner, scope);
|
||||||
|
if (!ty.ok())
|
||||||
|
break;
|
||||||
|
|
||||||
|
auto field_name = inner.expect(token::Type::Ident);
|
||||||
|
fields.push_back(types::StructField{ field_name.content, ty.unwrap() });
|
||||||
|
}
|
||||||
|
|
||||||
|
inner.expect(token::Type::Symbol, "}");
|
||||||
|
|
||||||
|
maybe_fields = fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!struct_name && !maybe_fields) {
|
||||||
|
throw std::runtime_error("Struct must have a name or fields!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (struct_name && !maybe_fields && scope.structs.find(*struct_name) != scope.structs.end()) {
|
||||||
|
auto original_ty = scope.structs[*struct_name];
|
||||||
|
auto original_struct_ty = dynamic_cast<types::StructType*>(original_ty.get());
|
||||||
|
auto ty = new types::StructType{ struct_name, original_struct_ty->m_fields, true };
|
||||||
|
returned = std::shared_ptr<types::Type>{ ty };
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
auto ty = new types::StructType{ struct_name, maybe_fields, false };
|
||||||
|
returned = std::shared_ptr<types::Type>{ ty };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw std::runtime_error("Expected type name, got " + type_name);
|
// TODO eventually make this be potentially more than one word
|
||||||
|
std::string type_name = token.content;
|
||||||
|
|
||||||
|
if (type_name == "int") {
|
||||||
|
auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Int };
|
||||||
|
returned = std::shared_ptr<types::Type>{ ty };
|
||||||
|
}
|
||||||
|
else if (type_name == "char") {
|
||||||
|
auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Char };
|
||||||
|
returned = std::shared_ptr<types::Type>{ ty };
|
||||||
|
}
|
||||||
|
else if (type_name == "void") {
|
||||||
|
auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Void };
|
||||||
|
returned = std::shared_ptr<types::Type>{ ty };
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw std::runtime_error("Expected type name, got " + type_name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (inner.peek().type == token::Type::Symbol && inner.peek().content == "*") {
|
while (inner.peek().type == token::Type::Symbol && inner.peek().content == "*") {
|
||||||
@ -432,7 +482,6 @@ namespace parsing {
|
|||||||
if (inner.peek().type == token::Type::Ident) {
|
if (inner.peek().type == token::Type::Ident) {
|
||||||
param_name = inner.expect(token::Type::Ident).content;
|
param_name = inner.expect(token::Type::Ident).content;
|
||||||
|
|
||||||
std::cout << inner.peek().formatted() << std::endl;
|
|
||||||
auto postfix = parse_array_postfix(inner, true, scope);
|
auto postfix = parse_array_postfix(inner, true, scope);
|
||||||
while (postfix.ok()) {
|
while (postfix.ok()) {
|
||||||
auto array_postfix = postfix.unwrap();
|
auto array_postfix = postfix.unwrap();
|
||||||
@ -498,6 +547,7 @@ namespace parsing {
|
|||||||
auto before_meta = inner.metadata();
|
auto before_meta = inner.metadata();
|
||||||
try {
|
try {
|
||||||
auto ty = parse_type(inner, scope).unwrap();
|
auto ty = parse_type(inner, scope).unwrap();
|
||||||
|
inner.expect(token::Type::Symbol, ";");
|
||||||
|
|
||||||
stream.m_position = inner.m_position;
|
stream.m_position = inner.m_position;
|
||||||
auto tl_typedef = new AST::TopLevelTypedef{
|
auto tl_typedef = new AST::TopLevelTypedef{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user