From 18dd7d05d41b07b8c73276ca4410666e657f136e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Mon, 7 Jul 2025 14:53:56 +0900 Subject: [PATCH] Lex and parse array expression --- src/Compiler/ModuleBuilder.cpp | 22 +++++++++++++ src/Compiler/ModuleBuilder.h | 2 ++ src/Lexer/Lexer.cpp | 10 ++++++ src/Lexer/Token.h | 2 ++ src/Logger.cpp | 19 +++++++++++ src/Logger.h | 2 ++ src/Parser/Expression/Expression.h | 1 + .../Expression/ExpressionArrayLiteral.cpp | 8 +++++ .../Expression/ExpressionArrayLiteral.h | 15 +++++++++ src/Parser/Expression/ExpressionLiteral.h | 9 ++++-- src/Parser/Parser.cpp | 32 ++++++++++++++++--- src/Parser/Parser.h | 1 + 12 files changed, 117 insertions(+), 6 deletions(-) create mode 100644 src/Parser/Expression/ExpressionArrayLiteral.cpp create mode 100644 src/Parser/Expression/ExpressionArrayLiteral.h diff --git a/src/Compiler/ModuleBuilder.cpp b/src/Compiler/ModuleBuilder.cpp index 5777fe5..244049f 100644 --- a/src/Compiler/ModuleBuilder.cpp +++ b/src/Compiler/ModuleBuilder.cpp @@ -6,6 +6,7 @@ #include "Parser/Expression/ExpressionGrouping.h" #include "Parser/Expression/ExpressionLiteral.h" +#include "Parser/Expression/ExpressionArrayLiteral.h" #include "Parser/Expression/ExpressionVariable.h" #include "Parser/Expression/ExpressionCall.h" #include "Parser/Expression/ExpressionIfElse.h" @@ -132,6 +133,21 @@ void ModuleBuilder::buildVarDeclaration(shared_ptr statement) if (!setAlloca(statement->getName(), alloca)) return; builder->CreateStore(value, alloca); + + /*auto *aType = llvm::ArrayType::get(typeSint32, 7); + llvm::AllocaInst *allocaArr = builder->CreateAlloca(aType, nullptr, statement->getName() + "_Arr"); + + //llvm::AllocaInst *allocaBrr = builder->CreateAlloca(typeSint32, nullptr, statement->getName() + "_Arr"); + vector values; + auto *bType = llvm::ArrayType::get(typeSint32, 9); + for (int i=0; i<9; i++) { + llvm::Constant *cnst = llvm::ConstantInt::get(typeSint32, i, true); + values.push_back(cnst); + } + llvm::Constant *ar = (llvm::ConstantArray *)llvm::ConstantArray::get(bType, values); + //auto vAr = ar->getAggregateElement(0); + llvm::AllocaInst *arAlloca = builder->CreateAlloca(bType, nullptr, "arBtype"); + builder->CreateStore(ar, arAlloca);*/ } void ModuleBuilder::buildAssignment(shared_ptr statement) { @@ -234,6 +250,8 @@ llvm::Value *ModuleBuilder::valueForExpression(shared_ptr expression switch (expression->getKind()) { case ExpressionKind::LITERAL: return valueForLiteral(dynamic_pointer_cast(expression)); + case ExpressionKind::ARRAY_LITERAL: + return valueForArrayLiteral(dynamic_pointer_cast(expression)); case ExpressionKind::GROUPING: return valueForExpression(dynamic_pointer_cast(expression)->getExpression()); case ExpressionKind::BINARY: @@ -266,6 +284,10 @@ llvm::Value *ModuleBuilder::valueForLiteral(shared_ptr expres } } +llvm::Value *ModuleBuilder::valueForArrayLiteral(shared_ptr expression) { + return nullptr; +} + llvm::Value *ModuleBuilder::valueForGrouping(shared_ptr expression) { return valueForExpression(expression->getExpression()); } diff --git a/src/Compiler/ModuleBuilder.h b/src/Compiler/ModuleBuilder.h index ddc70df..ceccd92 100644 --- a/src/Compiler/ModuleBuilder.h +++ b/src/Compiler/ModuleBuilder.h @@ -17,6 +17,7 @@ class ValueType; class Expression; class ExpressionGrouping; class ExpressionLiteral; +class ExpressionArrayLiteral; class ExpressionVariable; class ExpressionCall; class ExpressionIfElse; @@ -70,6 +71,7 @@ private: llvm::Value *valueForExpression(shared_ptr expression); llvm::Value *valueForLiteral(shared_ptr expression); + llvm::Value *valueForArrayLiteral(shared_ptr expression); llvm::Value *valueForGrouping(shared_ptr expression); llvm::Value *valueForBinary(shared_ptr expression); llvm::Value *valueForBinaryBool(ExpressionBinaryOperation operation, llvm::Value *leftValue, llvm::Value *rightValue); diff --git a/src/Lexer/Lexer.cpp b/src/Lexer/Lexer.cpp index 8d4ec3a..8e6d246 100644 --- a/src/Lexer/Lexer.cpp +++ b/src/Lexer/Lexer.cpp @@ -126,6 +126,14 @@ shared_ptr Lexer::nextToken() { if (token != nullptr) return token; + token = match(TokenKind::LEFT_SQUARE_BRACKET, "[", false); + if (token != nullptr) + return token; + + token = match(TokenKind::RIGHT_SQUARE_BRACKET, "]", false); + if (token != nullptr) + return token; + token = match(TokenKind::COMMA, ",", false); if (token != nullptr) return token; @@ -472,6 +480,8 @@ bool Lexer::isSeparator(int index) { case '>': case '(': case ')': + case '[': + case ']': case ',': case ':': case ';': diff --git a/src/Lexer/Token.h b/src/Lexer/Token.h index 1987b11..7c15be1 100644 --- a/src/Lexer/Token.h +++ b/src/Lexer/Token.h @@ -21,6 +21,8 @@ enum class TokenKind { LEFT_PAREN, RIGHT_PAREN, + LEFT_SQUARE_BRACKET, + RIGHT_SQUARE_BRACKET, COMMA, COLON, SEMICOLON, diff --git a/src/Logger.cpp b/src/Logger.cpp index b776a35..84c1e7a 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -23,6 +23,7 @@ #include "Parser/Expression/ExpressionVariable.h" #include "Parser/Expression/ExpressionGrouping.h" #include "Parser/Expression/ExpressionLiteral.h" +#include "Parser/Expression/ExpressionArrayLiteral.h" #include "Parser/Expression/ExpressionCall.h" #include "Parser/Expression/ExpressionBlock.h" @@ -56,6 +57,10 @@ string Logger::toString(shared_ptr token) { return "("; case TokenKind::RIGHT_PAREN: return ")"; + case TokenKind::LEFT_SQUARE_BRACKET: + return "["; + case TokenKind::RIGHT_SQUARE_BRACKET: + return "]"; case TokenKind::COMMA: return ","; case TokenKind::COLON: @@ -308,6 +313,8 @@ string Logger::toString(shared_ptr expression) { return toString(dynamic_pointer_cast(expression)); case ExpressionKind::LITERAL: return toString(dynamic_pointer_cast(expression)); + case ExpressionKind::ARRAY_LITERAL: + return toString(dynamic_pointer_cast(expression)); case ExpressionKind::CALL: return toString(dynamic_pointer_cast(expression)); case ExpressionKind::BLOCK: @@ -382,6 +389,18 @@ string Logger::toString(shared_ptr expression) { } } +string Logger::toString(shared_ptr expression) { + string text; + text += "["; + for (int i=0; igetExpressions().size(); i++) { + text += toString(expression->getExpressions().at(i)); + if (i < expression->getExpressions().size() - 1) + text += ", "; + } + text += "]"; + return text; +} + string Logger::toString(shared_ptr expression) { string argsString; for (int i = 0; i < expression->getArgumentExpressions().size(); i++) { diff --git a/src/Logger.h b/src/Logger.h index 0ffcdff..d5f1eba 100644 --- a/src/Logger.h +++ b/src/Logger.h @@ -23,6 +23,7 @@ class ExpressionIfElse; class ExpressionVariable; class ExpressionGrouping; class ExpressionLiteral; +class ExpressionArrayLiteral; class ExpressionCall; class ExpressionBlock; @@ -52,6 +53,7 @@ private: static string toString(shared_ptr expression); static string toString(shared_ptr expression); static string toString(shared_ptr expression); + static string toString(shared_ptr expression); static string toString(shared_ptr expression); static string toString(shared_ptr expression); diff --git a/src/Parser/Expression/Expression.h b/src/Parser/Expression/Expression.h index 249f606..66bd170 100644 --- a/src/Parser/Expression/Expression.h +++ b/src/Parser/Expression/Expression.h @@ -10,6 +10,7 @@ using namespace std; enum class ExpressionKind { LITERAL, + ARRAY_LITERAL, GROUPING, BINARY, IF_ELSE, diff --git a/src/Parser/Expression/ExpressionArrayLiteral.cpp b/src/Parser/Expression/ExpressionArrayLiteral.cpp new file mode 100644 index 0000000..2e6a7e5 --- /dev/null +++ b/src/Parser/Expression/ExpressionArrayLiteral.cpp @@ -0,0 +1,8 @@ +#include "ExpressionArrayLiteral.h" + +ExpressionArrayLiteral::ExpressionArrayLiteral(vector> expressions): +Expression(ExpressionKind::ARRAY_LITERAL, nullptr), expressions(expressions) { } + +vector> ExpressionArrayLiteral::getExpressions() { + return expressions; +} \ No newline at end of file diff --git a/src/Parser/Expression/ExpressionArrayLiteral.h b/src/Parser/Expression/ExpressionArrayLiteral.h new file mode 100644 index 0000000..ae56585 --- /dev/null +++ b/src/Parser/Expression/ExpressionArrayLiteral.h @@ -0,0 +1,15 @@ +#ifndef EXPRESSION_ARRAY_LITERAL_H +#define EXPRESSION_ARRAY_LITERAL_H + +#include "Expression.h" + +class ExpressionArrayLiteral: public Expression { +private: + vector> expressions; + +public: + ExpressionArrayLiteral(vector> expressions); + vector> getExpressions(); +}; + +#endif \ No newline at end of file diff --git a/src/Parser/Expression/ExpressionLiteral.h b/src/Parser/Expression/ExpressionLiteral.h index 0a9dfb2..a693cd0 100644 --- a/src/Parser/Expression/ExpressionLiteral.h +++ b/src/Parser/Expression/ExpressionLiteral.h @@ -1,4 +1,7 @@ -#include "Parser/Expression/Expression.h" +#ifndef EXPRESSION_LITERAL_H +#define EXPRESSION_LITERAL_H + +#include "Expression.h" class ExpressionLiteral: public Expression { private: @@ -12,4 +15,6 @@ public: bool getBoolValue(); int32_t getSint32Value(); float getReal32Value(); -}; \ No newline at end of file +}; + +#endif \ No newline at end of file diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 979b15c..3ac67ca 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -8,6 +8,7 @@ #include "Parser/Expression/ExpressionGrouping.h" #include "Parser/Expression/ExpressionLiteral.h" +#include "Parser/Expression/ExpressionArrayLiteral.h" #include "Parser/Expression/ExpressionVariable.h" #include "Parser/Expression/ExpressionCall.h" #include "Parser/Expression/ExpressionIfElse.h" @@ -261,10 +262,8 @@ shared_ptr Parser::matchStatementBlock(vector terminalToke break; // except new line - if (statement != nullptr && !tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true)) { + if (statement != nullptr && !tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true)) markError(TokenKind::NEW_LINE, {}); - return nullptr; - } } return make_shared(statements); @@ -446,6 +445,10 @@ shared_ptr Parser::matchPrimary() { if (expression != nullptr) return expression; + expression = matchExpressionArrayLiteral(); + if (expression != nullptr) + return expression; + expression = matchExpressionCall(); if (expression != nullptr) return expression; @@ -458,7 +461,6 @@ shared_ptr Parser::matchPrimary() { } shared_ptr Parser::matchExpressionGrouping() { - shared_ptr token = tokens.at(currentIndex); if (tryMatchingTokenKinds({TokenKind::LEFT_PAREN}, true, true)) { shared_ptr expression = matchTerm(); // has grouped expression failed? @@ -483,6 +485,28 @@ shared_ptr Parser::matchExpressionLiteral() { return nullptr; } +shared_ptr Parser::matchExpressionArrayLiteral() { + if (!tryMatchingTokenKinds({TokenKind::LEFT_SQUARE_BRACKET}, true, true)) + return nullptr; + + vector> expressions; + if (!tryMatchingTokenKinds({TokenKind::RIGHT_SQUARE_BRACKET}, true, true)) { + do { + shared_ptr expression = nextExpression(); + if (expression != nullptr) + expressions.push_back(expression); + } while (tryMatchingTokenKinds({TokenKind::COMMA}, true, true)); + + if (!tryMatchingTokenKinds({TokenKind::RIGHT_SQUARE_BRACKET}, true, true)) { + markError(TokenKind::RIGHT_SQUARE_BRACKET, {}); + return nullptr; + } + } + + + return make_shared(expressions); +} + shared_ptr Parser::matchExpressionVariable() { shared_ptr token = tokens.at(currentIndex); diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index 79dddee..d2db35f 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -40,6 +40,7 @@ private: shared_ptr matchExpressionGrouping(); shared_ptr matchExpressionLiteral(); + shared_ptr matchExpressionArrayLiteral(); shared_ptr matchExpressionVariable(); shared_ptr matchExpressionCall(); shared_ptr matchExpressionIfElse();