From d159b81c465f81b9e738598a6755c878f08f2cb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Tue, 12 Aug 2025 13:01:48 +0900 Subject: [PATCH] Read member --- samples/test.brc | 2 + src/Compiler/ModuleBuilder.cpp | 46 ++++++---- src/Compiler/ModuleBuilder.h | 2 +- src/Logger.cpp | 13 +-- src/Parser/Expression/ExpressionVariable.cpp | 39 ++++++++- src/Parser/Expression/ExpressionVariable.h | 20 ++++- src/Parser/Parser.cpp | 88 ++++++++++++++++---- src/Parser/Statement/StatementAssignment.h | 4 +- 8 files changed, 170 insertions(+), 44 deletions(-) diff --git a/samples/test.brc b/samples/test.brc index 823e89e..7e1eaf1 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -15,5 +15,7 @@ main fun -> u32 us.num1 <- 5 us.num2 <- 4 + num3 s32 <- us.num1 + 13 + ret 0 ; \ No newline at end of file diff --git a/src/Compiler/ModuleBuilder.cpp b/src/Compiler/ModuleBuilder.cpp index 09cae8f..2074995 100644 --- a/src/Compiler/ModuleBuilder.cpp +++ b/src/Compiler/ModuleBuilder.cpp @@ -365,7 +365,7 @@ llvm::Value *ModuleBuilder::valueForExpression(shared_ptr expression case ExpressionKind::IF_ELSE: return valueForIfElse(dynamic_pointer_cast(expression)); case ExpressionKind::VAR: - return valueForVar(dynamic_pointer_cast(expression)); + return valueForVariable(dynamic_pointer_cast(expression)); case ExpressionKind::CALL: return valueForCall(dynamic_pointer_cast(expression)); default: @@ -435,6 +435,8 @@ llvm::Value *ModuleBuilder::valueForBinary(shared_ptr expressi return valueForBinarySignedInteger(expression->getOperation(), leftValue, rightValue); } else if (type == typeR32) { return valueForBinaryReal(expression->getOperation(), leftValue, rightValue); + } else { // FIXME (we have missing value types) + return valueForBinarySignedInteger(expression->getOperation(), leftValue, rightValue); } markError(0, 0, "Unexpected operation"); @@ -606,23 +608,39 @@ llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr expressi } } -llvm::Value *ModuleBuilder::valueForVar(shared_ptr expression) { - llvm::AllocaInst *alloca = getAlloca(expression->getName()); +llvm::Value *ModuleBuilder::valueForVariable(shared_ptr expression) { + llvm::AllocaInst *alloca = getAlloca(expression->getIdentifier()); if (alloca == nullptr) return nullptr; - if (expression->getIndexExpression()) { - llvm::Value *indexValue = valueForExpression(expression->getIndexExpression()); - llvm::Value *index[] = { - builder->getInt32(0), - indexValue - }; - llvm::ArrayType *type = (llvm::ArrayType *)alloca->getAllocatedType(); - llvm::Value *elementPtr = builder->CreateGEP(type, alloca, index, format("{}[]", expression->getName())); + switch (expression->getVariableKind()) { + case ExpressionVariableKind::SIMPLE: { + return builder->CreateLoad(alloca->getAllocatedType(), alloca, expression->getIdentifier()); + } + case ExpressionVariableKind::DATA: { + llvm::Value *indexValue = valueForExpression(expression->getIndexExpression()); + llvm::Value *index[] = { + builder->getInt32(0), + indexValue + }; + llvm::ArrayType *type = (llvm::ArrayType *)alloca->getAllocatedType(); + llvm::Value *elementPtr = builder->CreateGEP(type, alloca, index, format("{}[]", expression->getIdentifier())); - return builder->CreateLoad(type->getArrayElementType(), elementPtr); - } else { - return builder->CreateLoad(alloca->getAllocatedType(), alloca, expression->getName()); + return builder->CreateLoad(type->getArrayElementType(), elementPtr); + } + case ExpressionVariableKind::BLOB: { + llvm::StructType *structType = (llvm::StructType *)alloca->getAllocatedType(); + string structName = string(structType->getName()); + optional memberIndex = getMemberIndex(structName, expression->getMemberName()); + if (!memberIndex) + return nullptr; + llvm::Value *index[] = { + builder->getInt32(0), + builder->getInt32(*memberIndex) + }; + llvm::Value *elementPtr = builder->CreateGEP(structType, alloca, index, format("{}.{}", expression->getIdentifier(), expression->getMemberName())); + return builder->CreateLoad(structType->getElementType(*memberIndex), elementPtr); + } } } diff --git a/src/Compiler/ModuleBuilder.h b/src/Compiler/ModuleBuilder.h index dcf55b3..43d3eb7 100644 --- a/src/Compiler/ModuleBuilder.h +++ b/src/Compiler/ModuleBuilder.h @@ -93,7 +93,7 @@ private: llvm::Value *valueForBinaryReal(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue); llvm::Value *valueForUnary(shared_ptr expression); llvm::Value *valueForIfElse(shared_ptr expression); - llvm::Value *valueForVar(shared_ptr expression); + llvm::Value *valueForVariable(shared_ptr expression); llvm::Value *valueForCall(shared_ptr expression); bool setAlloca(string name, llvm::AllocaInst *alloca); diff --git a/src/Logger.cpp b/src/Logger.cpp index 76a3b37..3e5aeeb 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -454,11 +454,14 @@ string Logger::toString(shared_ptr expression) { } string Logger::toString(shared_ptr expression) { - string text = format("VAR({}", expression->getName()); - if (expression->getIndexExpression() != nullptr) - text += format("|{}", toString(expression->getIndexExpression())); - text += ")"; - return text; + switch (expression->getVariableKind()) { + case ExpressionVariableKind::SIMPLE: + return format("VAR({})", expression->getIdentifier()); + case ExpressionVariableKind::DATA: + return format("VAR({}|{})", expression->getIdentifier(), toString(expression->getIndexExpression())); + case ExpressionVariableKind::BLOB: + return format("VAR({}.{})", expression->getIdentifier(), expression->getMemberName()); + } } string Logger::toString(shared_ptr expression) { diff --git a/src/Parser/Expression/ExpressionVariable.cpp b/src/Parser/Expression/ExpressionVariable.cpp index 61a03e2..6bb7423 100644 --- a/src/Parser/Expression/ExpressionVariable.cpp +++ b/src/Parser/Expression/ExpressionVariable.cpp @@ -1,12 +1,43 @@ #include "ExpressionVariable.h" -ExpressionVariable::ExpressionVariable(string name, shared_ptr indexExpression): -Expression(ExpressionKind::VAR, nullptr), name(name), indexExpression(indexExpression) { } +shared_ptr ExpressionVariable::simpleVariable(string identifier) { + shared_ptr expression = make_shared(); + expression->variableKind = ExpressionVariableKind::SIMPLE; + expression->identifier = identifier; + return expression; +} -string ExpressionVariable::getName() { - return name; +shared_ptr ExpressionVariable::dataVariable(string identifier, shared_ptr indexExpression) { + shared_ptr expression = make_shared(); + expression->variableKind = ExpressionVariableKind::DATA; + expression->identifier = identifier; + expression->indexExpression = indexExpression; + return expression; +} + +shared_ptr ExpressionVariable::blobVariable(string identifier, string memberName) { + shared_ptr expression = make_shared(); + expression->variableKind = ExpressionVariableKind::BLOB; + expression->identifier = identifier; + expression->memberName = memberName; + return expression; +} + +ExpressionVariable::ExpressionVariable(): +Expression(ExpressionKind::VAR, nullptr) { } + +ExpressionVariableKind ExpressionVariable::getVariableKind() { + return variableKind; +} + +string ExpressionVariable::getIdentifier() { + return identifier; } shared_ptr ExpressionVariable::getIndexExpression() { return indexExpression; } + +string ExpressionVariable::getMemberName() { + return memberName; +} \ No newline at end of file diff --git a/src/Parser/Expression/ExpressionVariable.h b/src/Parser/Expression/ExpressionVariable.h index 5835d9a..7a1f255 100644 --- a/src/Parser/Expression/ExpressionVariable.h +++ b/src/Parser/Expression/ExpressionVariable.h @@ -1,12 +1,26 @@ #include "Parser/Expression/Expression.h" +enum class ExpressionVariableKind { + SIMPLE, + DATA, + BLOB +}; + class ExpressionVariable: public Expression { private: - string name; + ExpressionVariableKind variableKind; + string identifier; shared_ptr indexExpression; + string memberName; public: - ExpressionVariable(string name, shared_ptr indexExpression); - string getName(); + static shared_ptr simpleVariable(string identifer); + static shared_ptr dataVariable(string identifier, shared_ptr indexExpression); + static shared_ptr blobVariable(string identifier, string memberName); + + ExpressionVariable(); + ExpressionVariableKind getVariableKind(); + string getIdentifier(); shared_ptr getIndexExpression(); + string getMemberName(); }; \ No newline at end of file diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 3e939dd..f67480e 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -478,7 +478,7 @@ shared_ptr Parser::matchStatementBlock(vector terminalToke shared_ptr Parser::matchStatementAssignment() { ParseeResultsGroup resultsGroup; - // variable + // simple resultsGroup = parseeResultsGroupForParseeGroup( ParseeGroup( { @@ -523,7 +523,7 @@ shared_ptr Parser::matchStatementAssignment() { switch (resultsGroup.getKind()) { case ParseeResultsGroupKind::SUCCESS: { string identifier = resultsGroup.getResults().at(0).getToken()->getLexme(); - shared_ptr indexExpression = indexExpression = resultsGroup.getResults().at(1).getExpression(); + shared_ptr indexExpression = resultsGroup.getResults().at(1).getExpression(); shared_ptr valueExpression = resultsGroup.getResults().at(2).getExpression(); return StatementAssignment::dataAssignment(identifier, indexExpression, valueExpression); } @@ -813,23 +813,81 @@ shared_ptr Parser::matchExpressionArrayLiteral() { } shared_ptr Parser::matchExpressionVariable() { - if (!tryMatchingTokenKinds({TokenKind::IDENTIFIER}, true, false)) - return nullptr; - shared_ptr idToken = tokens.at(currentIndex++); - shared_ptr indexExpression; + ParseeResultsGroup resultsGroup; - if (tryMatchingTokenKinds({TokenKind::LEFT_SQUARE_BRACKET}, true, true)) { - indexExpression = nextExpression(); - if (indexExpression == nullptr) - return nullptr; + // data + resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + // identifier + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false), + // index expression + Parsee::tokenParsee(TokenKind::LEFT_SQUARE_BRACKET, true, false, false), + Parsee::expressionParsee(true, true, true), + Parsee::tokenParsee(TokenKind::RIGHT_SQUARE_BRACKET, true, false, true) + } + ) + ); - if (!tryMatchingTokenKinds({TokenKind::RIGHT_SQUARE_BRACKET}, true, true)) { - markError(TokenKind::RIGHT_SQUARE_BRACKET, {}); - return nullptr; + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: { + string identifier = resultsGroup.getResults().at(0).getToken()->getLexme(); + shared_ptr indexExpression = indexExpression = resultsGroup.getResults().at(1).getExpression(); + return ExpressionVariable::dataVariable(identifier, indexExpression); } + case ParseeResultsGroupKind::NO_MATCH: + break; + case ParseeResultsGroupKind::FAILURE: + return nullptr; } - - return make_shared(idToken->getLexme(), indexExpression); + + // blob + resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + // identifier + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false), + // member name + Parsee::tokenParsee(TokenKind::DOT, true, false, false), + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, true) + } + ) + ); + + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: { + string identifier = resultsGroup.getResults().at(0).getToken()->getLexme(); + string memberName = resultsGroup.getResults().at(1).getToken()->getLexme(); + return ExpressionVariable::blobVariable(identifier, memberName); + } + case ParseeResultsGroupKind::NO_MATCH: + break; + case ParseeResultsGroupKind::FAILURE: + return nullptr; + } + + // simple + resultsGroup = parseeResultsGroupForParseeGroup( + ParseeGroup( + { + // identifier + Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false) + } + ) + ); + + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: { + string identifier = resultsGroup.getResults().at(0).getToken()->getLexme(); + return ExpressionVariable::simpleVariable(identifier); + } + case ParseeResultsGroupKind::NO_MATCH: + break; + case ParseeResultsGroupKind::FAILURE: + return nullptr; + } + + return nullptr; } shared_ptr Parser::matchExpressionCall() { diff --git a/src/Parser/Statement/StatementAssignment.h b/src/Parser/Statement/StatementAssignment.h index 2d5892c..110ee4c 100644 --- a/src/Parser/Statement/StatementAssignment.h +++ b/src/Parser/Statement/StatementAssignment.h @@ -16,9 +16,9 @@ private: string memberName; shared_ptr valueExpression; - public: +public: StatementAssignment(); - static shared_ptr variableAssignment(string identifier, shared_ptr expression); + static shared_ptr variableAssignment(string identifier, shared_ptr valueExpression); static shared_ptr dataAssignment(string identifier, shared_ptr indexExpression, shared_ptr valueExpression); static shared_ptr blobAssignment(string identifier, string memberName, shared_ptr valueExpression); StatementAssignmentKind getAssignmentKind();