1
0
mirror of synced 2025-01-29 19:17:28 +01:00

patterns: Add multi-variable declarations

This commit is contained in:
WerWolv 2021-08-25 17:54:47 +02:00
parent 9289ebf4c9
commit c053d54d10
3 changed files with 58 additions and 1 deletions

View File

@ -285,6 +285,32 @@ namespace hex::lang {
ASTNode *m_placementOffset;
};
class ASTNodeMultiVariableDecl : public ASTNode {
public:
explicit ASTNodeMultiVariableDecl(std::vector<ASTNode*> variables) : m_variables(std::move(variables)) { }
ASTNodeMultiVariableDecl(const ASTNodeMultiVariableDecl &other) : ASTNode(other) {
for (auto &variable : other.m_variables)
this->m_variables.push_back(variable->clone());
}
~ASTNodeMultiVariableDecl() override {
for (auto &variable : this->m_variables)
delete variable;
}
[[nodiscard]] ASTNode* clone() const override {
return new ASTNodeMultiVariableDecl(*this);
}
[[nodiscard]] std::vector<ASTNode*> getVariables() {
return this->m_variables;
}
private:
std::vector<ASTNode*> m_variables;
};
class ASTNodeStruct : public ASTNode, public Attributable {
public:
ASTNodeStruct() : ASTNode() { }

View File

@ -521,6 +521,14 @@ namespace hex::lang {
} else if (auto varDeclNode = dynamic_cast<ASTNodeVariableDecl*>(statement); varDeclNode != nullptr) {
auto pattern = this->evaluateVariable(varDeclNode);
this->createLocalVariable(varDeclNode->getName(), pattern);
} else if (auto multiVarDeclNode = dynamic_cast<ASTNodeMultiVariableDecl*>(statement); multiVarDeclNode != nullptr) {
for (auto &delc : multiVarDeclNode->getVariables()) {
if (auto varDecl = dynamic_cast<ASTNodeVariableDecl*>(delc); varDecl != nullptr) {
auto pattern = this->evaluateVariable(varDecl);
this->createLocalVariable(varDecl->getName(), pattern);
} else
this->getConsole().abortEvaluation("invalid multi-variable declaration");
}
} else if (auto assignmentNode = dynamic_cast<ASTNodeAssignment*>(statement); assignmentNode != nullptr) {
if (auto numericExpressionNode = dynamic_cast<ASTNodeNumericExpression*>(assignmentNode->getRValue()); numericExpressionNode != nullptr) {
auto value = this->evaluateMathematicalExpression(numericExpressionNode);
@ -677,6 +685,14 @@ namespace hex::lang {
if (auto memberVariableNode = dynamic_cast<ASTNodeVariableDecl*>(node); memberVariableNode != nullptr)
currMembers.push_back(this->evaluateVariable(memberVariableNode));
else if (auto memberMultiVariableNode = dynamic_cast<ASTNodeMultiVariableDecl*>(node); memberMultiVariableNode != nullptr) {
for (auto decl : memberMultiVariableNode->getVariables()) {
if (auto variableDecl = dynamic_cast<ASTNodeVariableDecl*>(decl); variableDecl != nullptr)
currMembers.push_back(this->evaluateVariable(variableDecl));
else
this->getConsole().abortEvaluation("invalid multi-variable declaration");
}
}
else if (auto memberArrayNode = dynamic_cast<ASTNodeArrayVariableDecl*>(node); memberArrayNode != nullptr)
currMembers.push_back(this->evaluateArray(memberArrayNode));
else if (auto memberPointerNode = dynamic_cast<ASTNodePointerVariableDecl*>(node); memberPointerNode != nullptr)

View File

@ -634,7 +634,22 @@ namespace hex::lang {
ASTNode* Parser::parseMemberVariable(ASTNodeTypeDecl *type) {
if (type == nullptr) throwParseError("invalid type used in variable declaration", -1);
return new ASTNodeVariableDecl(getValue<std::string>(-1), type);
if (peek(SEPARATOR_COMMA)) {
std::vector<ASTNode*> variables;
auto variableCleanup = SCOPE_GUARD { for (auto var : variables) delete var; };
do {
variables.push_back(new ASTNodeVariableDecl(getValue<std::string>(-1), type->clone()));
} while (MATCHES(sequence(SEPARATOR_COMMA, IDENTIFIER)));
delete type;
variableCleanup.release();
return new ASTNodeMultiVariableDecl(variables);
} else
return new ASTNodeVariableDecl(getValue<std::string>(-1), type);
}
// (parseType) Identifier[(parseMathematicalExpression)]