diff --git a/samples/test.brc b/samples/test.brc index 2862269..823e89e 100644 --- a/samples/test.brc +++ b/samples/test.brc @@ -12,7 +12,8 @@ User blob main fun -> u32 us User - us<- 5 + us.num1 <- 5 + us.num2 <- 4 ret 0 ; \ No newline at end of file diff --git a/src/Compiler/ModuleBuilder.cpp b/src/Compiler/ModuleBuilder.cpp index 8c1f0f0..09cae8f 100644 --- a/src/Compiler/ModuleBuilder.cpp +++ b/src/Compiler/ModuleBuilder.cpp @@ -222,11 +222,11 @@ void ModuleBuilder::buildVarDeclaration(shared_ptr statement) } void ModuleBuilder::buildAssignment(shared_ptr statement) { - llvm::AllocaInst *alloca = getAlloca(statement->getName()); + llvm::AllocaInst *alloca = getAlloca(statement->getIdentifier()); if (alloca == nullptr) return; - llvm::Value *value = valueForExpression(statement->getExpression()); + llvm::Value *value = valueForExpression(statement->getValueExpression()); switch (statement->getAssignmentKind()) { case StatementAssignmentKind::VARIABLE: { @@ -240,7 +240,7 @@ void ModuleBuilder::buildAssignment(shared_ptr statement) { indexValue }; llvm::ArrayType *type = (llvm::ArrayType *)alloca->getAllocatedType(); - llvm::Value *elementPtr = builder->CreateGEP(type, alloca, index, format("{}[]", statement->getName())); + llvm::Value *elementPtr = builder->CreateGEP(type, alloca, index, format("{}[]", statement->getIdentifier())); builder->CreateStore(value, elementPtr); break; @@ -255,7 +255,7 @@ void ModuleBuilder::buildAssignment(shared_ptr statement) { builder->getInt32(0), builder->getInt32(*memberIndex) }; - llvm::Value *elementPtr = builder->CreateGEP(structType, alloca, index); + llvm::Value *elementPtr = builder->CreateGEP(structType, alloca, index, format("{}.{}", statement->getIdentifier(), statement->getMemberName())); builder->CreateStore(value, elementPtr); break; } diff --git a/src/Lexer/Lexer.cpp b/src/Lexer/Lexer.cpp index 56fccf4..843cb4f 100644 --- a/src/Lexer/Lexer.cpp +++ b/src/Lexer/Lexer.cpp @@ -161,6 +161,10 @@ shared_ptr Lexer::nextToken() { if (token != nullptr) return token; + token = match(TokenKind::DOT, ".", false); + if (token != nullptr) + return token; + // arithmetic token = match(TokenKind::PLUS, "+", false); if (token != nullptr) @@ -573,6 +577,7 @@ bool Lexer::isSeparator(int index) { case ' ': case '\t': case '\n': + case '.': return true; default: return false; diff --git a/src/Lexer/Token.h b/src/Lexer/Token.h index 5e6ad36..e7b5b75 100644 --- a/src/Lexer/Token.h +++ b/src/Lexer/Token.h @@ -28,6 +28,7 @@ enum class TokenKind { SEMICOLON, LEFT_ARROW, RIGHT_ARROW, + DOT, FUNCTION, RAW_FUNCTION, diff --git a/src/Logger.cpp b/src/Logger.cpp index 5ffe5ee..76a3b37 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -74,6 +74,8 @@ string Logger::toString(shared_ptr token) { return "←"; case TokenKind::RIGHT_ARROW: return "→"; + case TokenKind::DOT: + return "."; case TokenKind::BOOL: return "BOOL(" + token->getLexme() + ")"; @@ -165,6 +167,8 @@ string Logger::toString(TokenKind tokenKind) { return "←"; case TokenKind::RIGHT_ARROW: return "→"; + case TokenKind::DOT: + return "."; case TokenKind::BOOL: return "LITERAL(BOOLEAN)"; @@ -329,10 +333,14 @@ string Logger::toString(shared_ptr statement) { } string Logger::toString(shared_ptr statement) { - if (statement->getIndexExpression() != nullptr) - return format("{}[{}] <- {}", statement->getName(), toString(statement->getIndexExpression()), toString(statement->getExpression())); - else - return format("{} <- {}", statement->getName(), toString(statement->getExpression())); + switch (statement->getAssignmentKind()) { + case StatementAssignmentKind::VARIABLE: + return format("{} <- {}", statement->getIdentifier(), toString(statement->getValueExpression())); + case StatementAssignmentKind::DATA: + return format("{}[{}] <- {}", statement->getIdentifier(), toString(statement->getIndexExpression()), toString(statement->getValueExpression())); + case StatementAssignmentKind::BLOB: + return format("{}.{} <- {}", statement->getIdentifier(), statement->getMemberName(), toString(statement->getValueExpression())); + } } string Logger::toString(shared_ptr statement) { diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 05f8484..3e939dd 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -476,25 +476,14 @@ shared_ptr Parser::matchStatementBlock(vector terminalToke } shared_ptr Parser::matchStatementAssignment() { - string identifier; - shared_ptr indexExpression; - shared_ptr expression; + ParseeResultsGroup resultsGroup; - ParseeResultsGroup resultsGroup = parseeResultsGroupForParseeGroup( + // variable + resultsGroup = parseeResultsGroupForParseeGroup( ParseeGroup( { // identifier Parsee::tokenParsee(TokenKind::IDENTIFIER, true, true, false), - // index expression - Parsee::groupParsee( - ParseeGroup( - { - Parsee::tokenParsee(TokenKind::LEFT_SQUARE_BRACKET, true, false, false), - Parsee::expressionParsee(true, true, true), - Parsee::tokenParsee(TokenKind::RIGHT_SQUARE_BRACKET, true, false, true) - } - ), false, true, false - ), // expression Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false, false), Parsee::expressionParsee(true, true, true) @@ -502,19 +491,78 @@ shared_ptr Parser::matchStatementAssignment() { ) ); - if (resultsGroup.getKind() != ParseeResultsGroupKind::SUCCESS) - return nullptr; + switch (resultsGroup.getKind()) { + case ParseeResultsGroupKind::SUCCESS: { + string identifier = resultsGroup.getResults().at(0).getToken()->getLexme(); + shared_ptr valueExpression = resultsGroup.getResults().at(1).getExpression(); + return StatementAssignment::variableAssignment(identifier, valueExpression); + } + case ParseeResultsGroupKind::NO_MATCH: + break; + case ParseeResultsGroupKind::FAILURE: + return nullptr; + } - int i = 0; - // identifier - identifier = resultsGroup.getResults().at(i++).getToken()->getLexme(); - // index expression - if (i < resultsGroup.getResults().size()-1) - indexExpression = resultsGroup.getResults().at(i++).getExpression(); - // expression - expression = resultsGroup.getResults().at(i).getExpression(); + // 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), + // expression + Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false, false), + Parsee::expressionParsee(true, true, true) + } + ) + ); - return make_shared(identifier, indexExpression, expression); + 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 valueExpression = resultsGroup.getResults().at(2).getExpression(); + return StatementAssignment::dataAssignment(identifier, indexExpression, valueExpression); + } + case ParseeResultsGroupKind::NO_MATCH: + break; + case ParseeResultsGroupKind::FAILURE: + return nullptr; + } + + // 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), + // expression + Parsee::tokenParsee(TokenKind::LEFT_ARROW, true, false, false), + Parsee::expressionParsee(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(); + shared_ptr valueExpression = resultsGroup.getResults().at(2).getExpression(); + return StatementAssignment::blobAssignment(identifier, memberName, valueExpression); + } + case ParseeResultsGroupKind::NO_MATCH: + break; + case ParseeResultsGroupKind::FAILURE: + return nullptr; + } + + return nullptr; } shared_ptr Parser::matchStatementReturn() { diff --git a/src/Parser/Statement/StatementAssignment.cpp b/src/Parser/Statement/StatementAssignment.cpp index c63e13d..51722a7 100644 --- a/src/Parser/Statement/StatementAssignment.cpp +++ b/src/Parser/Statement/StatementAssignment.cpp @@ -1,24 +1,50 @@ #include "StatementAssignment.h" -StatementAssignment::StatementAssignment(string name, shared_ptr indexExpression, shared_ptr expression): -Statement(StatementKind::ASSIGNMENT), name(name), indexExpression(indexExpression), expression(expression) { } +StatementAssignment::StatementAssignment(): +Statement(StatementKind::ASSIGNMENT) { } + +shared_ptr StatementAssignment::variableAssignment(string identifier, shared_ptr valueExpression) { + shared_ptr statement = make_shared(); + statement->assignmentKind = StatementAssignmentKind::VARIABLE; + statement->identifier = identifier; + statement->valueExpression = valueExpression; + return statement; +} + +shared_ptr StatementAssignment::dataAssignment(string identifier, shared_ptr indexExpression, shared_ptr valueExpression) { + shared_ptr statement = make_shared(); + statement->assignmentKind = StatementAssignmentKind::DATA; + statement->identifier = identifier; + statement->indexExpression = indexExpression; + statement->valueExpression = valueExpression; + return statement; +} + +shared_ptr StatementAssignment::blobAssignment(string identifier, string memberName, shared_ptr valueExpression) { + shared_ptr statement = make_shared(); + statement->assignmentKind = StatementAssignmentKind::BLOB; + statement->identifier = identifier; + statement->memberName = memberName; + statement->valueExpression = valueExpression; + return statement; +} StatementAssignmentKind StatementAssignment::getAssignmentKind() { return assignmentKind; } -string StatementAssignment::getName() { - return name; +string StatementAssignment::getIdentifier() { + return identifier; } shared_ptr StatementAssignment::getIndexExpression() { return indexExpression; } -shared_ptr StatementAssignment::getExpression() { - return expression; -} - string StatementAssignment::getMemberName() { return memberName; +} + +shared_ptr StatementAssignment::getValueExpression() { + return valueExpression; } \ No newline at end of file diff --git a/src/Parser/Statement/StatementAssignment.h b/src/Parser/Statement/StatementAssignment.h index bc541ae..2d5892c 100644 --- a/src/Parser/Statement/StatementAssignment.h +++ b/src/Parser/Statement/StatementAssignment.h @@ -11,16 +11,19 @@ enum class StatementAssignmentKind { class StatementAssignment: public Statement { private: StatementAssignmentKind assignmentKind; - string name; + string identifier; shared_ptr indexExpression; - shared_ptr expression; string memberName; - -public: - StatementAssignment(string name, shared_ptr indexExpressio, shared_ptr expression); + shared_ptr valueExpression; + + public: + StatementAssignment(); + static shared_ptr variableAssignment(string identifier, shared_ptr expression); + 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(); - string getName(); + string getIdentifier(); shared_ptr getIndexExpression(); - shared_ptr getExpression(); string getMemberName(); + shared_ptr getValueExpression(); }; \ No newline at end of file