diff --git a/src/codegen.cpp b/src/codegen.cpp index 6a62a71..c8f8b7f 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -283,8 +283,6 @@ namespace AST { } } 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 auto arr_ty = dynamic_cast(ptr_ty->m_inner.get()); auto gep_value = builder.builder->CreateGEP(arr_ty->m_inner->codegen(builder, scope.structs), value.value, idx_list, "GEP"); diff --git a/src/main.cpp b/src/main.cpp index db3b9f8..490c78a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -165,7 +165,7 @@ std::optional compile(std::string_view in_filename) { builder.mod->print(llvm_ir_dest, nullptr); llvm_ir_dest.flush(); - std::cout << llvm_ir_string << std::endl; + // std::cout << llvm_ir_string << std::endl; // Print output to obj-file std::error_code EC; diff --git a/src/parsing.cpp b/src/parsing.cpp index 255860f..a1f6a9f 100644 --- a/src/parsing.cpp +++ b/src/parsing.cpp @@ -7,30 +7,80 @@ namespace parsing { namespace { Result, std::string> parse_expression(token::TokenStream& stream, Scope& scope); - Result, std::string> parse_type(token::TokenStream& stream, Scope&) { + Result, std::string> parse_type(token::TokenStream& stream, Scope& scope) { token::TokenStream inner{ stream }; try { 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 returned{}; - if (type_name == "int") { - auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Int }; - returned = std::shared_ptr{ ty }; - } - else if (type_name == "char") { - auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Char }; - returned = std::shared_ptr{ ty }; - } - else if (type_name == "void") { - auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Void }; - returned = std::shared_ptr{ ty }; + if (token.content == "struct") { + std::optional struct_name{}; + + if (inner.peek().type == token::Type::Ident) { + struct_name = inner.expect(token::Type::Ident).content; + } + + std::optional> maybe_fields{}; + + if (inner.peek().content == "{") { + std::vector 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(original_ty.get()); + auto ty = new types::StructType{ struct_name, original_struct_ty->m_fields, true }; + returned = std::shared_ptr{ ty }; + } + else { + auto ty = new types::StructType{ struct_name, maybe_fields, false }; + returned = std::shared_ptr{ ty }; + } } 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{ ty }; + } + else if (type_name == "char") { + auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Char }; + returned = std::shared_ptr{ ty }; + } + else if (type_name == "void") { + auto ty = new types::FundamentalType{ types::FundamentalTypeKind::Void }; + returned = std::shared_ptr{ ty }; + } + else { + throw std::runtime_error("Expected type name, got " + type_name); + } } while (inner.peek().type == token::Type::Symbol && inner.peek().content == "*") { @@ -432,7 +482,6 @@ namespace parsing { if (inner.peek().type == token::Type::Ident) { param_name = inner.expect(token::Type::Ident).content; - std::cout << inner.peek().formatted() << std::endl; auto postfix = parse_array_postfix(inner, true, scope); while (postfix.ok()) { auto array_postfix = postfix.unwrap(); @@ -498,6 +547,7 @@ namespace parsing { auto before_meta = inner.metadata(); try { auto ty = parse_type(inner, scope).unwrap(); + inner.expect(token::Type::Symbol, ";"); stream.m_position = inner.m_position; auto tl_typedef = new AST::TopLevelTypedef{