From b6c2ff39838524644e1a2c20001e413f7d062d9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Tue, 5 Aug 2025 11:16:50 +0900 Subject: [PATCH] Generate code for custom type --- samples/test.brc | 4 ++-- src/Compiler/ModuleBuilder.cpp | 42 ++++++++++++++++++++++++++++++++++ src/Compiler/ModuleBuilder.h | 6 +++++ src/Logger.cpp | 13 +++++++++++ src/Logger.h | 2 ++ src/Parser/Parser.cpp | 33 +++++++++++++++----------- src/Parser/ValueType.cpp | 27 +++++++++++++++++----- src/Parser/ValueType.h | 8 ++++++- 8 files changed, 113 insertions(+), 22 deletions(-) diff --git a/samples/test.brc b/samples/test.brc index 3aeb90d..001ed1c 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -1,8 +1,8 @@ -User type +User pack ; main fun -> u32 - //user User + user User <- 0 ret 0 ; \ No newline at end of file diff --git a/src/Compiler/ModuleBuilder.cpp b/src/Compiler/ModuleBuilder.cpp index 4fdd0d8..1f877e8 100644 --- a/src/Compiler/ModuleBuilder.cpp +++ b/src/Compiler/ModuleBuilder.cpp @@ -16,6 +16,7 @@ #include "Parser/Statement/StatementFunction.h" #include "Parser/Statement/StatementRawFunction.h" +#include "Parser/Statement/StatementType.h" #include "Parser/Statement/StatementVariable.h" #include "Parser/Statement/StatementAssignment.h" #include "Parser/Statement/StatementReturn.h" @@ -68,6 +69,9 @@ void ModuleBuilder::buildStatement(shared_ptr statement) { case StatementKind::RAW_FUNCTION: buildRawFunction(dynamic_pointer_cast(statement)); break; + case StatementKind::TYPE: + buildType(dynamic_pointer_cast(statement)); + break; case StatementKind::VARIABLE: buildVarDeclaration(dynamic_pointer_cast(statement)); break; @@ -160,6 +164,14 @@ void ModuleBuilder::buildRawFunction(shared_ptr statement) return; } +void ModuleBuilder::buildType(shared_ptr statement) { + llvm::StructType *structType = llvm::StructType::create(*context, statement->getIdentifier()); + vector elements; + structType->setBody(elements, false); + if (!setStruct(statement->getIdentifier(), structType)) + return; +} + void ModuleBuilder::buildVarDeclaration(shared_ptr statement) { if (statement->getValueType()->getKind() == ValueTypeKind::DATA) { vector values = valuesForExpression(statement->getExpression()); @@ -177,6 +189,11 @@ void ModuleBuilder::buildVarDeclaration(shared_ptr statement) builder->CreateStore(values[i], elementPtr); } + } else if (statement->getValueType()->getKind() == ValueTypeKind::TYPE) { + llvm::StructType *type = (llvm::StructType *)typeForValueType(statement->getValueType(), 0); + llvm::AllocaInst *alloca = builder->CreateAlloca(type, nullptr, statement->getName()); + if (!setAlloca(statement->getName(), alloca)) + return; } else { llvm::Value *value = valueForExpression(statement->getExpression()); if (value == nullptr) @@ -671,6 +688,29 @@ llvm::InlineAsm *ModuleBuilder::getRawFun(string name) { return nullptr; } +bool ModuleBuilder::setStruct(string name, llvm::StructType *structType) { + if (scopes.top().structTypeMap[name] != nullptr) { + markError(0, 0, format("Type \"{}\" already defined in scope", name)); + return false; + } + + scopes.top().structTypeMap[name] = structType; + return true; +} + +llvm::StructType *ModuleBuilder::getStructType(string name) { + stack scopes = this->scopes; + + while (!scopes.empty()) { + llvm::StructType *structType = scopes.top().structTypeMap[name]; + if (structType != nullptr) + return structType; + scopes.pop(); + } + + return nullptr; +} + llvm::Type *ModuleBuilder::typeForValueType(shared_ptr valueType, int count) { if (valueType == nullptr) { markError(0, 0, "Missing type"); @@ -699,6 +739,8 @@ llvm::Type *ModuleBuilder::typeForValueType(shared_ptr valueType, int count = valueType->getValueArg(); return llvm::ArrayType::get(typeForValueType(valueType->getSubType(), count), count); } + case ValueTypeKind::TYPE: + return getStructType(valueType->getTypeName()); } } diff --git a/src/Compiler/ModuleBuilder.h b/src/Compiler/ModuleBuilder.h index 872b4ad..71dcd9c 100644 --- a/src/Compiler/ModuleBuilder.h +++ b/src/Compiler/ModuleBuilder.h @@ -29,6 +29,7 @@ enum class ExpressionBinaryOperation; class Statement; class StatementFunction; class StatementRawFunction; +class StatementType; class StatementVariable; class StatementAssignment; class StatementReturn; @@ -43,6 +44,7 @@ typedef struct { map allocaMap; map funMap; map rawFunMap; + map structTypeMap; } Scope; class ModuleBuilder { @@ -69,6 +71,7 @@ private: void buildStatement(shared_ptr statement); void buildFunction(shared_ptr statement); void buildRawFunction(shared_ptr statement); + void buildType(shared_ptr statement); void buildVarDeclaration(shared_ptr statement); void buildAssignment(shared_ptr statement); void buildBlock(shared_ptr statement); @@ -101,6 +104,9 @@ private: bool setRawFun(string name, llvm::InlineAsm *rawFun); llvm::InlineAsm *getRawFun(string name); + bool setStruct(string name, llvm::StructType *structType); + llvm::StructType *getStructType(string name); + llvm::Type *typeForValueType(shared_ptr valueType, int count = 0); void markError(int line, int column, string message); diff --git a/src/Logger.cpp b/src/Logger.cpp index d5ca83d..0ba1a47 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -12,6 +12,7 @@ #include "Parser/Statement/StatementVariable.h" #include "Parser/Statement/StatementFunction.h" #include "Parser/Statement/StatementRawFunction.h" +#include "Parser/Statement/StatementType.h" #include "Parser/Statement/StatementBlock.h" #include "Parser/Statement/StatementAssignment.h" #include "Parser/Statement/StatementReturn.h" @@ -223,6 +224,8 @@ string Logger::toString(shared_ptr valueType) { return "R32"; case ValueTypeKind::DATA: return "[]"; + case ValueTypeKind::TYPE: + return format("TYPE({})", valueType->getTypeName()); } } @@ -236,6 +239,8 @@ string Logger::toString(shared_ptr statement) { return toString(dynamic_pointer_cast(statement)); case StatementKind::RAW_FUNCTION: return toString(dynamic_pointer_cast(statement)); + case StatementKind::TYPE: + return toString(dynamic_pointer_cast(statement)); case StatementKind::BLOCK: return toString(dynamic_pointer_cast(statement)); case StatementKind::ASSIGNMENT: @@ -296,6 +301,14 @@ string Logger::toString(shared_ptr statement) { return text; } +string Logger::toString(shared_ptr statement) { + string text; + + text += format("TYPE(\"{}\"):\n", statement->getIdentifier()); + + return text; +} + string Logger::toString(shared_ptr statement) { string text; diff --git a/src/Logger.h b/src/Logger.h index 72e6746..81521a9 100644 --- a/src/Logger.h +++ b/src/Logger.h @@ -12,6 +12,7 @@ class StatementMetaExternFunction; class StatementVariable; class StatementFunction; class StatementRawFunction; +class StatementType; class StatementBlock; class StatementAssignment; class StatementReturn; @@ -44,6 +45,7 @@ private: static string toString(shared_ptr statement); static string toString(shared_ptr statement); static string toString(shared_ptr statement); + static string toString(shared_ptr statement); static string toString(shared_ptr statement); static string toString(shared_ptr statement); static string toString(shared_ptr statement); diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index b2e8161..4bcacba 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -503,31 +503,38 @@ shared_ptr Parser::matchStatementType() { Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), Parsee::tokenParsee(TokenKind::TYPE, true, false) }, - ParseeGroup( - { - Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true), - Parsee::valueTypeParsee(true) - }, - {} - ) + {} ) ); switch (resultsGroup.getKind()) { case ParseeResultsGroupKind::SUCCESS: identifier = resultsGroup.getResults().at(0).getToken()->getLexme(); - for (int i=1; i> arg; - arg.first = resultsGroup.getResults().at(i).getToken()->getLexme(); - arg.second = resultsGroup.getResults().at(i+1).getValueType(); - variables.push_back(arg); - } + /*for (int i=1; i> arg; + arg.first = resultsGroup.getResults().at(i).getToken()->getLexme(); + arg.second = resultsGroup.getResults().at(i+1).getValueType(); + variables.push_back(arg); + }*/ + break; case ParseeResultsGroupKind::NO_MATCH: case ParseeResultsGroupKind::FAILURE: return nullptr; break; } + // consume new line + if (!tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true)) { + markError(TokenKind::NEW_LINE, {}); + return nullptr; + } + + // closing semicolon + if(!tryMatchingTokenKinds({TokenKind::SEMICOLON}, false, true)) { + markError(TokenKind::SEMICOLON, {}); + return nullptr; + } + return make_shared(identifier, variables); } diff --git a/src/Parser/ValueType.cpp b/src/Parser/ValueType.cpp index 566342b..77bc8d1 100644 --- a/src/Parser/ValueType.cpp +++ b/src/Parser/ValueType.cpp @@ -10,27 +10,38 @@ shared_ptr ValueType::S8 = make_shared(ValueTypeKind::S8, shared_ptr ValueType::S32 = make_shared(ValueTypeKind::S32, nullptr, 0); shared_ptr ValueType::R32 = make_shared(ValueTypeKind::R32, nullptr, 0); +ValueType::ValueType() { } + ValueType::ValueType(ValueTypeKind kind, shared_ptr subType, int valueArg): kind(kind), subType(subType), valueArg(valueArg) { } +shared_ptr ValueType::type(string typeName) { + shared_ptr valueType = make_shared(); + valueType->kind = ValueTypeKind::TYPE; + valueType->typeName = typeName; + return valueType; +} + shared_ptr ValueType::valueTypeForToken(shared_ptr token, shared_ptr subType, int valueArg) { switch (token->getKind()) { case TokenKind::TYPE: { string lexme = token->getLexme(); if (lexme.compare("bool") == 0) - return make_shared(ValueTypeKind::BOOL, subType, valueArg); + return make_shared(ValueTypeKind::BOOL, nullptr, 0); else if (lexme.compare("u8") == 0) - return make_shared(ValueTypeKind::U8, subType, valueArg); + return make_shared(ValueTypeKind::U8, nullptr, 0); else if (lexme.compare("u32") == 0) - return make_shared(ValueTypeKind::U32, subType, valueArg); + return make_shared(ValueTypeKind::U32, nullptr, 0); else if (lexme.compare("s8") == 0) - return make_shared(ValueTypeKind::S8, subType, valueArg); + return make_shared(ValueTypeKind::S8, nullptr, 0); else if (lexme.compare("s32") == 0) - return make_shared(ValueTypeKind::S32, subType, valueArg); + return make_shared(ValueTypeKind::S32, nullptr, 0); else if (lexme.compare("r32") == 0) - return make_shared(ValueTypeKind::R32, subType, valueArg); + return make_shared(ValueTypeKind::R32, nullptr, 0); else if (lexme.compare("data") == 0) return make_shared(ValueTypeKind::DATA, subType, valueArg); + else if (lexme.compare("type") != 0) + return ValueType::type(token->getLexme()); else return nullptr; } @@ -59,4 +70,8 @@ shared_ptr ValueType::getSubType() { int ValueType::getValueArg() { return valueArg; +} + +string ValueType::getTypeName() { + return typeName; } \ No newline at end of file diff --git a/src/Parser/ValueType.h b/src/Parser/ValueType.h index 2b77f2f..6ce36ad 100644 --- a/src/Parser/ValueType.h +++ b/src/Parser/ValueType.h @@ -2,6 +2,7 @@ #define VALUE_TYPE_H #include +#include class Token; @@ -15,7 +16,8 @@ enum class ValueTypeKind { S8, S32, R32, - DATA + DATA, + TYPE }; class ValueType { @@ -23,6 +25,7 @@ private: ValueTypeKind kind; shared_ptr subType; int valueArg; + string typeName; public: static shared_ptr NONE; @@ -34,10 +37,13 @@ public: static shared_ptr R32; static shared_ptr valueTypeForToken(shared_ptr token, shared_ptr subType, int valueArg); + ValueType(); ValueType(ValueTypeKind kind, shared_ptr subType, int valueArg); + static shared_ptr type(string typeName); ValueTypeKind getKind(); shared_ptr getSubType(); int getValueArg(); + string getTypeName(); }; #endif \ No newline at end of file