From 4bab8077af756f2a760a2d074a704fefa3ea7212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Grodzi=C5=84ski?= Date: Mon, 23 Jun 2025 16:08:58 +0900 Subject: [PATCH] Added Expression Block and moved some expressions --- src/Compiler/ModuleBuilder.cpp | 18 +-- src/Compiler/ModuleBuilder.h | 5 +- src/Parser/Expression.cpp | 115 -------------------- src/Parser/Expression.h | 33 +----- src/Parser/Expression/ExpressionBlock.cpp | 19 ++++ src/Parser/Expression/ExpressionBlock.h | 11 ++ src/Parser/Expression/ExpressionIfElse.cpp | 36 ++++++ src/Parser/Expression/ExpressionIfElse.h | 17 +++ src/Parser/Expression/ExpressionLiteral.cpp | 69 ++++++++++++ src/Parser/Expression/ExpressionLiteral.h | 23 ++++ src/Parser/Parser.cpp | 35 ++++-- src/Parser/Parser.h | 1 + src/Parser/Statement/StatementBlock.cpp | 17 +-- src/Parser/Statement/StatementBlock.h | 2 - 14 files changed, 220 insertions(+), 181 deletions(-) create mode 100644 src/Parser/Expression/ExpressionBlock.cpp create mode 100644 src/Parser/Expression/ExpressionBlock.h create mode 100644 src/Parser/Expression/ExpressionIfElse.cpp create mode 100644 src/Parser/Expression/ExpressionIfElse.h create mode 100644 src/Parser/Expression/ExpressionLiteral.cpp create mode 100644 src/Parser/Expression/ExpressionLiteral.h diff --git a/src/Compiler/ModuleBuilder.cpp b/src/Compiler/ModuleBuilder.cpp index 264193d..ccfafa9 100644 --- a/src/Compiler/ModuleBuilder.cpp +++ b/src/Compiler/ModuleBuilder.cpp @@ -1,5 +1,8 @@ #include "ModuleBuilder.h" +#include "Parser/Expression/ExpressionLiteral.h" +#include "Parser/Expression/ExpressionIfElse.h" + #include "Parser/Statement/StatementExpression.h" #include "Parser/Statement/StatementBlock.h" #include "Parser/Statement/StatementFunction.h" @@ -100,11 +103,8 @@ void ModuleBuilder::buildVarDeclaration(shared_ptr statement) } void ModuleBuilder::buildBlock(shared_ptr statement) { - for (shared_ptr &innerStatement : statement->getStatements()) { + for (shared_ptr &innerStatement : statement->getStatements()) buildStatement(innerStatement); - } - if (statement->getStatementExpression() != nullptr) - buildStatement(statement->getStatementExpression()); } void ModuleBuilder::buildReturn(shared_ptr statement) { @@ -274,8 +274,9 @@ llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr expressi // Then builder->SetInsertPoint(thenBlock); - llvm::Value *thenValue = valueForExpression(expression->getThenBlock()->getStatementExpression()->getExpression()); - buildStatement(expression->getThenBlock()); + //llvm::Value *thenValue = valueForExpression(expression->getThenBlock()->getStatementExpression()->getExpression()); + llvm::Value *thenValue = llvm::UndefValue::get(typeVoid); + //buildStatement(expression->getThenBlock()); builder->CreateBr(mergeBlock); thenBlock = builder->GetInsertBlock(); @@ -285,8 +286,9 @@ llvm::Value *ModuleBuilder::valueForIfElse(shared_ptr expressi llvm::Value *elseValue = nullptr; if (expression->getElseBlock() != nullptr) { valuesCount++; - elseValue = valueForExpression(expression->getElseBlock()->getStatementExpression()->getExpression()); - buildStatement(expression->getElseBlock()); + //elseValue = valueForExpression(expression->getElseBlock()->getStatementExpression()->getExpression()); + llvm::Value *elseValue = llvm::UndefValue::get(typeVoid); + //buildStatement(expression->getElseBlock()); } builder->CreateBr(mergeBlock); elseBlock = builder->GetInsertBlock(); diff --git a/src/Compiler/ModuleBuilder.h b/src/Compiler/ModuleBuilder.h index c48818f..6506c18 100644 --- a/src/Compiler/ModuleBuilder.h +++ b/src/Compiler/ModuleBuilder.h @@ -13,10 +13,13 @@ #include "Parser/Expression.h" #include "Parser/Statement/Statement.h" +class ExpressionLiteral; +class ExpressionIfElse; + class StatementBlock; +class StatementReturn; class StatementFunction; class StatementVariable; -class StatementReturn; class StatementMetaExternFunction; using namespace std; diff --git a/src/Parser/Expression.cpp b/src/Parser/Expression.cpp index f25a6f6..9cd632a 100644 --- a/src/Parser/Expression.cpp +++ b/src/Parser/Expression.cpp @@ -124,71 +124,6 @@ string ExpressionBinary::toString(int indent) { } } -// -// ExpressionLiteral -ExpressionLiteral::ExpressionLiteral(shared_ptr token): -Expression(ExpressionKind::LITERAL, ValueType::NONE) { - switch (token->getKind()) { - case TokenKind::BOOL: - boolValue = token->getLexme().compare("true") == 0; - valueType = ValueType::BOOL; - break; - case TokenKind::INTEGER_DEC: { - string numString = token->getLexme(); - erase(numString, '_'); - sint32Value = stoi(numString, nullptr, 10); - valueType = ValueType::SINT32; - break; - } - case TokenKind::INTEGER_HEX: { - string numString = token->getLexme(); - erase(numString, '_'); - sint32Value = stoi(numString, nullptr, 16); - valueType = ValueType::SINT32; - break; - } - case TokenKind::INTEGER_BIN: { - string numString = token->getLexme(); - erase(numString, '_'); - numString = numString.substr(2, numString.size()-1); - sint32Value = stoi(numString, nullptr, 2); - valueType = ValueType::SINT32; - break; - } - case TokenKind::REAL: - real32Value = stof(token->getLexme()); - valueType = ValueType::REAL32; - break; - default: - exit(1); - } -} - -bool ExpressionLiteral::getBoolValue() { - return boolValue; -} - -int32_t ExpressionLiteral::getSint32Value() { - return sint32Value; -} - -float ExpressionLiteral::getReal32Value() { - return real32Value; -} - -string ExpressionLiteral::toString(int indent) { - switch (valueType) { - case ValueType::NONE: - return "NONE"; - case ValueType::BOOL: - return boolValue ? "true" : "false"; - case ValueType::SINT32: - return to_string(sint32Value); - case ValueType::REAL32: - return to_string(real32Value); - } -} - // // ExpressionGrouping ExpressionGrouping::ExpressionGrouping(shared_ptr expression): @@ -203,56 +138,6 @@ string ExpressionGrouping::toString(int indent) { return "( " + expression->toString(0) + " )"; } -// -// ExpressionIfElse -ExpressionIfElse::ExpressionIfElse(shared_ptr condition, shared_ptr thenBlock, shared_ptr elseBlock): -Expression(ExpressionKind::IF_ELSE, ValueType::NONE), condition(condition), thenBlock(thenBlock), elseBlock(elseBlock) { - // Condition must evaluate to bool - if (condition->getValueType() != ValueType::BOOL) - exit(1); - - // Return types must match - shared_ptr thenStatementExpression = thenBlock->getStatementExpression(); - shared_ptr thenExpression = thenStatementExpression != nullptr ? thenStatementExpression->getExpression() : nullptr; - shared_ptr elseStatementExpression = elseBlock != nullptr ? elseBlock->getStatementExpression() : nullptr; - shared_ptr elseExpression = elseStatementExpression != nullptr ? elseStatementExpression->getExpression() : nullptr; - if (thenExpression != nullptr && elseExpression != nullptr && thenExpression->getValueType() != elseExpression->getValueType()) - exit(1); - - // get type or default to void - valueType = thenExpression ? thenExpression->getValueType() : ValueType::NONE; -} - -shared_ptr ExpressionIfElse::getCondition() { - return condition; -} - -shared_ptr ExpressionIfElse::getThenBlock() { - return thenBlock; -} - -shared_ptr ExpressionIfElse::getElseBlock() { - return elseBlock; -} - -string ExpressionIfElse::toString(int indent) { - string value; - value += "IF(" + condition->toString(0) + "):\n"; - - value += thenBlock->toString(indent+1); - if (elseBlock != nullptr) { - for (int ind=0; indtoString(indent+1); - } - for (int ind=0; ind token); - bool getBoolValue(); - int32_t getSint32Value(); - float getReal32Value(); - string toString(int indent) override; -}; - // // ExpressionGrouping class ExpressionGrouping: public Expression { @@ -96,22 +81,6 @@ public: string toString(int indent) override; }; -// -// ExpressionIfElse -class ExpressionIfElse: public Expression { -private: - shared_ptr condition; - shared_ptr thenBlock; - shared_ptr elseBlock; - -public: - ExpressionIfElse(shared_ptr condition, shared_ptr thenBlock, shared_ptr elseBlock); - shared_ptr getCondition(); - shared_ptr getThenBlock(); - shared_ptr getElseBlock(); - string toString(int indent) override; -}; - // // ExpressionVar class ExpressionVar: public Expression { diff --git a/src/Parser/Expression/ExpressionBlock.cpp b/src/Parser/Expression/ExpressionBlock.cpp new file mode 100644 index 0000000..2c634e9 --- /dev/null +++ b/src/Parser/Expression/ExpressionBlock.cpp @@ -0,0 +1,19 @@ +#include "ExpressionBlock.h" + +#include "Parser/Expression/ExpressionLiteral.h" +#include "Parser/Statement/StatementExpression.h" + +ExpressionBlock::ExpressionBlock(vector> statements): +Expression(ExpressionKind::BLOCK, ValueType::NONE), statements(statements) { + if (!statements.empty() && statements.back()->getKind() == StatementKind::EXPRESSION) { + resultExpression = dynamic_pointer_cast(statements.back()); + this->statements.pop_back(); + valueType = resultExpression->getExpression()->getValueType(); + } else { + resultExpression = make_shared(ExpressionLiteral::none); + } +} + +string ExpressionBlock::toString(int indent) { + return ""; +} \ No newline at end of file diff --git a/src/Parser/Expression/ExpressionBlock.h b/src/Parser/Expression/ExpressionBlock.h new file mode 100644 index 0000000..5c6161c --- /dev/null +++ b/src/Parser/Expression/ExpressionBlock.h @@ -0,0 +1,11 @@ +#include "Parser/Expression.h" + +class ExpressionBlock: public Expression { +private: + vector> statements; + shared_ptr resultExpression; + +public: + ExpressionBlock(vector> statements); + string toString(int indent) override; +}; \ No newline at end of file diff --git a/src/Parser/Expression/ExpressionIfElse.cpp b/src/Parser/Expression/ExpressionIfElse.cpp new file mode 100644 index 0000000..91057be --- /dev/null +++ b/src/Parser/Expression/ExpressionIfElse.cpp @@ -0,0 +1,36 @@ +#include "ExpressionIfElse.h" + +#include "Parser/Expression/ExpressionBlock.h" + +ExpressionIfElse::ExpressionIfElse(shared_ptr condition, shared_ptr thenBlock, shared_ptr elseBlock): +Expression(ExpressionKind::IF_ELSE, ValueType::NONE), condition(condition), thenBlock(thenBlock), elseBlock(elseBlock) { } + +shared_ptr ExpressionIfElse::getCondition() { + return condition; +} + +shared_ptr ExpressionIfElse::getThenBlock() { + return thenBlock; +} + +shared_ptr ExpressionIfElse::getElseBlock() { + return elseBlock; +} + +string ExpressionIfElse::toString(int indent) { + string value; + value += "IF(" + condition->toString(0) + "):\n"; + + value += thenBlock->toString(indent+1); + if (elseBlock != nullptr) { + for (int ind=0; indtoString(indent+1); + } + for (int ind=0; ind condition; + shared_ptr thenBlock; + shared_ptr elseBlock; + +public: + ExpressionIfElse(shared_ptr condition, shared_ptr thenBlock, shared_ptr elseBlock); + shared_ptr getCondition(); + shared_ptr getThenBlock(); + shared_ptr getElseBlock(); + string toString(int indent) override; +}; \ No newline at end of file diff --git a/src/Parser/Expression/ExpressionLiteral.cpp b/src/Parser/Expression/ExpressionLiteral.cpp new file mode 100644 index 0000000..815d6c9 --- /dev/null +++ b/src/Parser/Expression/ExpressionLiteral.cpp @@ -0,0 +1,69 @@ +#include "ExpressionLiteral.h" + +shared_ptr ExpressionLiteral::none; + +ExpressionLiteral::ExpressionLiteral(): +Expression(ExpressionKind::LITERAL, ValueType::NONE) { } + +ExpressionLiteral::ExpressionLiteral(shared_ptr token): +Expression(ExpressionKind::LITERAL, ValueType::NONE) { + switch (token->getKind()) { + case TokenKind::BOOL: + boolValue = token->getLexme().compare("true") == 0; + valueType = ValueType::BOOL; + break; + case TokenKind::INTEGER_DEC: { + string numString = token->getLexme(); + erase(numString, '_'); + sint32Value = stoi(numString, nullptr, 10); + valueType = ValueType::SINT32; + break; + } + case TokenKind::INTEGER_HEX: { + string numString = token->getLexme(); + erase(numString, '_'); + sint32Value = stoi(numString, nullptr, 16); + valueType = ValueType::SINT32; + break; + } + case TokenKind::INTEGER_BIN: { + string numString = token->getLexme(); + erase(numString, '_'); + numString = numString.substr(2, numString.size()-1); + sint32Value = stoi(numString, nullptr, 2); + valueType = ValueType::SINT32; + break; + } + case TokenKind::REAL: + real32Value = stof(token->getLexme()); + valueType = ValueType::REAL32; + break; + default: + exit(1); + } +} + +bool ExpressionLiteral::getBoolValue() { + return boolValue; +} + +int32_t ExpressionLiteral::getSint32Value() { + return sint32Value; +} + +float ExpressionLiteral::getReal32Value() { + return real32Value; +} + +string ExpressionLiteral::toString(int indent) { + switch (valueType) { + case ValueType::NONE: + return "NONE"; + case ValueType::BOOL: + return boolValue ? "true" : "false"; + case ValueType::SINT32: + return to_string(sint32Value); + case ValueType::REAL32: + return to_string(real32Value); + } +} \ No newline at end of file diff --git a/src/Parser/Expression/ExpressionLiteral.h b/src/Parser/Expression/ExpressionLiteral.h new file mode 100644 index 0000000..8f60568 --- /dev/null +++ b/src/Parser/Expression/ExpressionLiteral.h @@ -0,0 +1,23 @@ +#include "Parser/Expression.h" + +#include + +using namespace std; + +class ExpressionLiteral: public Expression { +private: + bool boolValue; + int32_t sint32Value; + float real32Value; + + ExpressionLiteral(); + +public: + static shared_ptr none; + + ExpressionLiteral(shared_ptr token); + bool getBoolValue(); + int32_t getSint32Value(); + float getReal32Value(); + string toString(int indent) override; +}; \ No newline at end of file diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 323719f..36d37dc 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -1,5 +1,9 @@ #include "Parser.h" +#include "Parser/Expression/ExpressionLiteral.h" +#include "Parser/Expression/ExpressionIfElse.h" +#include "Parser/Expression/ExpressionBlock.h" + #include "Parser/Statement/StatementExpression.h" #include "Parser/Statement/StatementBlock.h" #include "Parser/Statement/StatementReturn.h" @@ -166,7 +170,6 @@ shared_ptr Parser::matchStatementBlock(vector terminalToke currentIndex--; } - return make_shared(statements); } @@ -414,29 +417,29 @@ shared_ptr Parser::matchExpressionIfElse() { tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); // Match then block - shared_ptr thenBlock = matchStatementBlock({TokenKind::COLON, TokenKind::SEMICOLON}, false); + shared_ptr thenBlock = matchExpressionBlock({TokenKind::COLON, TokenKind::SEMICOLON}, false); if (thenBlock == nullptr) return matchExpressionInvalid(); else if (!thenBlock->isValid()) - return matchExpressionInvalid(); // FIXME + return thenBlock; // Match else block. Then and else block are separated by ':' - shared_ptr elseBlock; + shared_ptr elseBlock; if (tryMatchingTokenKinds({TokenKind::COLON}, true, true)) { bool isSingleLine = !tryMatchingTokenKinds({TokenKind::NEW_LINE}, true, true); vector terminalTokens = {TokenKind::SEMICOLON, TokenKind::COMMA, TokenKind::RIGHT_PAREN}; if (isSingleLine) terminalTokens.push_back(TokenKind::NEW_LINE); - elseBlock = matchStatementBlock(terminalTokens, false); + elseBlock = matchExpressionBlock(terminalTokens, false); if (elseBlock == nullptr) return matchExpressionInvalid(); else if (!elseBlock->isValid()) - return matchExpressionInvalid(); // FIXME + return elseBlock; } tryMatchingTokenKinds({TokenKind::SEMICOLON}, true, true); - return make_shared(condition, dynamic_pointer_cast(thenBlock), dynamic_pointer_cast(elseBlock)); + return make_shared(condition, dynamic_pointer_cast(thenBlock), dynamic_pointer_cast(elseBlock)); } shared_ptr Parser::matchExpressionVar() { @@ -473,6 +476,24 @@ shared_ptr Parser::matchExpressionCall() { return make_shared(identifierToken->getLexme(), argumentExpressions); } +shared_ptr Parser::matchExpressionBlock(vector terminalTokenKinds, bool shouldConsumeTerminal) { + vector> statements; + + bool hasNewLineTerminal = find(terminalTokenKinds.begin(), terminalTokenKinds.end(), TokenKind::NEW_LINE) != terminalTokenKinds.end(); + while (!tryMatchingTokenKinds(terminalTokenKinds, false, shouldConsumeTerminal)) { + shared_ptr statement = nextStatement(); + if (statement == nullptr || !statement->isValid()) + return matchExpressionInvalid(); + else + statements.push_back(statement); + + if (hasNewLineTerminal && tokens.at(currentIndex-1)->getKind() == TokenKind::NEW_LINE) + currentIndex--; + } + + return make_shared(statements); +} + shared_ptr Parser::matchExpressionInvalid() { return make_shared(tokens.at(currentIndex)); } diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index 8ac7780..48a5f5b 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -40,6 +40,7 @@ private: shared_ptr matchExpressionIfElse(); shared_ptr matchExpressionVar(); shared_ptr matchExpressionCall(); + shared_ptr matchExpressionBlock(vector terminalTokenKinds, bool shouldConsumeTerminal); shared_ptr matchExpressionInvalid(); bool tryMatchingTokenKinds(vector kinds, bool shouldMatchAll, bool shouldAdvance); diff --git a/src/Parser/Statement/StatementBlock.cpp b/src/Parser/Statement/StatementBlock.cpp index 960f7c3..3c8839b 100644 --- a/src/Parser/Statement/StatementBlock.cpp +++ b/src/Parser/Statement/StatementBlock.cpp @@ -3,21 +3,12 @@ #include "Parser/Statement/StatementExpression.h" StatementBlock::StatementBlock(vector> statements): -Statement(StatementKind::BLOCK), statements(statements) { - if (!statements.empty() && statements.back()->getKind() == StatementKind::EXPRESSION) { - statementExpression = dynamic_pointer_cast(statements.back()); - this->statements.pop_back(); - } -} +Statement(StatementKind::BLOCK), statements(statements) { } vector> StatementBlock::getStatements() { return statements; } -shared_ptr StatementBlock::getStatementExpression() { - return statementExpression; -} - string StatementBlock::toString(int indent) { string value; for (int i=0; itoString(indent); } - if (statementExpression != nullptr) { - for (int ind=0; indtoString(indent); - } for (int ind=0; ind> statements; - shared_ptr statementExpression; public: StatementBlock(vector> statements); vector> getStatements(); - shared_ptr getStatementExpression(); string toString(int indent) override; }; \ No newline at end of file