From de81d4037f8fbabefcd39ef9a5baafe31f007535 Mon Sep 17 00:00:00 2001 From: IRBorisov <8611739+IRBorisov@users.noreply.github.com> Date: Mon, 6 May 2024 15:02:37 +0300 Subject: [PATCH] Refactor RSLang code readability --- .vscode/settings.json | 10 + ccl/rslang/header/ASTNormalizer.h | 2 +- ccl/rslang/header/RSParserImpl.h | 4 +- .../include/ccl/rslang/RSErrorCodes.hpp | 6 +- ccl/rslang/src/ASTInterpreter.cpp | 232 ++++---- ccl/rslang/src/ASTNormalizer.cpp | 18 +- ccl/rslang/src/AsciiLexerImpl.l | 144 ++--- ccl/rslang/src/ErrorLogger.cpp | 33 +- ccl/rslang/src/Literals.cpp | 17 +- ccl/rslang/src/MathLexerImpl.l | 144 ++--- ccl/rslang/src/NameCollector.cpp | 13 +- ccl/rslang/src/RSGenerator.cpp | 87 +-- ccl/rslang/src/RSParserImpl.cpp | 28 +- ccl/rslang/src/RSParserImpl.y | 4 +- ccl/rslang/src/TypeAuditor.cpp | 498 ++++++++++++------ ccl/rslang/src/ValueAuditor.cpp | 18 +- ccl/rslang/test/src/testTypeAuditor.cpp | 28 +- 17 files changed, 763 insertions(+), 523 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 6ba9f24..d92eebb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -16,6 +16,7 @@ "cmake.ctestArgs": ["--test-dir build", "--output-on-failure"], "cmake.installPrefix": "output", "cSpell.words": [ + "BIGPR", "conanfile", "coredll", "DCMAKE", @@ -23,19 +24,28 @@ "DECART", "Decartian", "defexpr", + "EMPTYSET", + "FORALL", "GNUC", "gtest", "ifdef", + "INTSET", "MSVC", "nlohmann", "noteq", + "NOTEQUAL", + "NOTIN", "notsubset", + "PUNC", "pybind", "pyconcept", "rslang", "setexpr", + "SMALLPR", "struct", "symmdiff", + "SYMMINUS", + "YYABORT", "yylex", "yylval", "YYSTYPE", diff --git a/ccl/rslang/header/ASTNormalizer.h b/ccl/rslang/header/ASTNormalizer.h index 611e266..63ed793 100644 --- a/ccl/rslang/header/ASTNormalizer.h +++ b/ccl/rslang/header/ASTNormalizer.h @@ -30,7 +30,7 @@ public: private: void Quantifier(SyntaxTree::Node& quant); static void EnumDeclaration(SyntaxTree::Node& quant); - void TupleDeclaration(SyntaxTree::Node& declaration, SyntaxTree::Node& predicat); + void TupleDeclaration(SyntaxTree::Node& declaration, SyntaxTree::Node& predicate); void TupleDeclaration(SyntaxTree::Node& target); [[nodiscard]] std::string CreateTupleName(const SyntaxTree::Node& root); diff --git a/ccl/rslang/header/RSParserImpl.h b/ccl/rslang/header/RSParserImpl.h index bdfa186..cfdb725 100644 --- a/ccl/rslang/header/RSParserImpl.h +++ b/ccl/rslang/header/RSParserImpl.h @@ -333,7 +333,7 @@ namespace ccl { namespace rslang { namespace detail { RST_IN = 282, // IN RST_NOTIN = 283, // NOTIN RST_SUBSET = 284, // SUBSET - RST_SUBOR_EQ = 285, // SUBOR_EQ + RST_SUBSET_OR_EQ = 285, // SUBSET_OR_EQ RST_NOTSUBSET = 286, // NOTSUBSET RST_DECART = 287, // DECART RST_UNION = 288, // UNION @@ -412,7 +412,7 @@ namespace ccl { namespace rslang { namespace detail { S_IN = 27, // IN S_NOTIN = 28, // NOTIN S_SUBSET = 29, // SUBSET - S_SUBOR_EQ = 30, // SUBOR_EQ + S_SUBSET_OR_EQ = 30, // SUBSET_OR_EQ S_NOTSUBSET = 31, // NOTSUBSET S_DECART = 32, // DECART S_UNION = 33, // UNION diff --git a/ccl/rslang/include/ccl/rslang/RSErrorCodes.hpp b/ccl/rslang/include/ccl/rslang/RSErrorCodes.hpp index c854cab..fa01bd7 100644 --- a/ccl/rslang/include/ccl/rslang/RSErrorCodes.hpp +++ b/ccl/rslang/include/ccl/rslang/RSErrorCodes.hpp @@ -42,10 +42,10 @@ enum class SemanticEID : uint32_t { invalidProjectionTuple = 0x8811, // Не определена проекция invalidProjectionSet = 0x8812, // Большая проекция определена только для множеств! invalidEnumeration = 0x8813, // Типизация аргументов перечисления не совпадает - ivalidBinding = 0x8814, // Количество переменных в кортеже не соответствует размерности декартова произведения + invalidBinding = 0x8814, // Количество переменных в кортеже не соответствует размерности декартова произведения localOutOfScope = 0x8815, // Использование имени вне области видимости - invalidElementPredicat = 0x8816, // Несоответствие типов для проверки принадлежности - invalidArgsArtity = 0x8818, // Некорректное количество аргументов терм-функции + invalidElementPredicate = 0x8816, // Несоответствие типов для проверки принадлежности + invalidArgsArity = 0x8818, // Некорректное количество аргументов терм-функции invalidArgumentType = 0x8819, // Типизация аргумента не совпадает с объявленной invalidEqualsEmpty = 0x881A, // Сравнение с пустым множеством не множества globalStructure = 0x881C, // Родовая структура должна быть ступенью diff --git a/ccl/rslang/src/ASTInterpreter.cpp b/ccl/rslang/src/ASTInterpreter.cpp index 199f035..d2b328a 100644 --- a/ccl/rslang/src/ASTInterpreter.cpp +++ b/ccl/rslang/src/ASTInterpreter.cpp @@ -3,6 +3,7 @@ #include "NameCollector.h" #include +#include #ifdef _MSC_VER #pragma warning( push ) @@ -94,11 +95,11 @@ private: auto element = parent.EvaluateChild(imperative, 0); if (!element.has_value()) { return false; - } else { - value.ModifyB().AddElement(std::get(element.value())); - incrementIter = true; - return true; } + + value.ModifyB().AddElement(std::get(element.value())); + incrementIter = true; + return true; } [[nodiscard]] bool ProcessBlock() { @@ -188,8 +189,7 @@ void ASTInterpreter::OnError(const ValueEID eid, const StrPos position, std::str std::optional ASTInterpreter::Evaluate(const rslang::SyntaxTree& tree) { Clear(); - if (!NameCollector{ *this }.Visit(tree.Root()) - || !tree.Root().DispatchVisit(*this)) { + if (!NameCollector{ *this }.Visit(tree.Root()) || !tree.Root().DispatchVisit(*this)) { AfterVisit(false); return std::nullopt; } else { @@ -247,46 +247,49 @@ bool ASTInterpreter::ViEmptySet(Cursor /*iter*/) { } bool ASTInterpreter::ViArithmetic(Cursor iter) { - if (const auto val1 = EvaluateChild(iter, 0); !val1.has_value()) { + const auto val1 = EvaluateChild(iter, 0); + if (!val1.has_value()) { return false; - } else if (const auto val2 = EvaluateChild(iter, 1); !val2.has_value()) { + } + const auto val2 = EvaluateChild(iter, 1); + if (!val2.has_value()) { return false; - } else { - const auto op1 = std::get(val1.value()).E().Value(); - const auto op2 = std::get(val2.value()).E().Value(); - switch (iter->id) { - default: - case TokenID::PLUS: - return VisitAndReturn(Factory::Val(op1 + op2)); - case TokenID::MINUS: - return VisitAndReturn(Factory::Val(op1 - op2)); - case TokenID::MULTIPLY: - return VisitAndReturn(Factory::Val(op1 * op2)); - } + } + const auto op1 = std::get(val1.value()).E().Value(); + const auto op2 = std::get(val2.value()).E().Value(); + switch (iter->id) { + default: + case TokenID::PLUS: + return VisitAndReturn(Factory::Val(op1 + op2)); + case TokenID::MINUS: + return VisitAndReturn(Factory::Val(op1 - op2)); + case TokenID::MULTIPLY: + return VisitAndReturn(Factory::Val(op1 * op2)); } } bool ASTInterpreter::ViCard(Cursor iter) { - if (const auto base = EvaluateChild(iter, 0); !base.has_value()) { + const auto base = EvaluateChild(iter, 0); + if (!base.has_value()) { return false; - } else if (const auto size = std::get(base.value()).B().Cardinality(); - size == StructuredData::SET_INFINITY) { + } + const auto size = std::get(base.value()).B().Cardinality(); + if (size == StructuredData::SET_INFINITY) { OnError(ValueEID::typedOverflow, iter->pos.start, std::to_string(StructuredData::SET_INFINITY)); return false; - } else { - return VisitAndReturn(Factory::Val(size)); } + return VisitAndReturn(Factory::Val(size)); } bool ASTInterpreter::ViQuantifier(Cursor iter) { - const auto quantorDomain = ExtractDomain(iter); - if (!quantorDomain.has_value()) { + const auto domain = ExtractDomain(iter); + if (!domain.has_value()) { return false; } const auto varID = *begin(nodeVars[iter.Child(0).get()]); - const auto quantorForAll = iter->id == TokenID::FORALL; - for (const auto& child : quantorDomain->B()) { + const auto isUniversal = iter->id == TokenID::FORALL; + for (const auto& child : domain->B()) { if (++iterationCounter > MAX_ITERATIONS) { OnError(ValueEID::iterationsLimit, iter->pos.start, std::to_string(MAX_ITERATIONS)); return false; @@ -294,46 +297,50 @@ bool ASTInterpreter::ViQuantifier(Cursor iter) { idsData[varID] = child; if (const auto iterationValue = EvaluateChild(iter, 2); !iterationValue.has_value()) { return false; - } else if (std::get(iterationValue.value()) != quantorForAll) { - return VisitAndReturn(!quantorForAll); + } else if (std::get(iterationValue.value()) != isUniversal) { + return VisitAndReturn(!isUniversal); } } - return VisitAndReturn(quantorForAll); + return VisitAndReturn(isUniversal); } std::optional ASTInterpreter::ExtractDomain(Cursor iter) { if (!VisitChild(iter, 1)) { return std::nullopt; - } else { - return std::optional{std::get(curValue)}; } + return std::optional{std::get(curValue)}; } bool ASTInterpreter::ViNegation(Cursor iter) { - if (const auto childValue = EvaluateChild(iter, 0); !childValue.has_value()) { + const auto childValue = EvaluateChild(iter, 0); + if (!childValue.has_value()) { return false; - } else { - return VisitAndReturn(!std::get(childValue.value())); } + return VisitAndReturn(!std::get(childValue.value())); } bool ASTInterpreter::ViLogicBinary(Cursor iter) { - if (const auto val1 = EvaluateChild(iter, 0); !val1.has_value()) { + const auto val1 = EvaluateChild(iter, 0); + if (!val1.has_value()) { return false; - } else if (TryEvaluateFromFirstArg(iter->id, std::get(val1.value()))) { + } + + if (TryEvaluateFromFirstArg(iter->id, std::get(val1.value()))) { return true; - } else if (const auto val2 = EvaluateChild(iter, 1); !val2.has_value()) { + } + + const auto val2 = EvaluateChild(iter, 1); + if (!val2.has_value()) { return false; - } else { - const auto op1 = std::get(val1.value()); - const auto op2 = std::get(val2.value()); - switch (iter->id) { + } + const auto op1 = std::get(val1.value()); + const auto op2 = std::get(val2.value()); + switch (iter->id) { default: case TokenID::AND: curValue = op1 && op2; return true; case TokenID::OR: curValue = op1 || op2; return true; case TokenID::IMPLICATION: curValue = !op1 || op2; return true; - case TokenID::EQUIVALENT: curValue = op1 == op2; return true; - } + case TokenID::EQUIVALENT: curValue = op1 == op2; return true; } } @@ -349,30 +356,34 @@ bool ASTInterpreter::TryEvaluateFromFirstArg(TokenID operation, bool firstArgVal } bool ASTInterpreter::ViEquals(Cursor iter) { - if (const auto val1 = EvaluateChild(iter, 0); !val1.has_value()) { + const auto val1 = EvaluateChild(iter, 0); + if (!val1.has_value()) { return false; - } else if (const auto val2 = EvaluateChild(iter, 1); !val2.has_value()) { - return false; - } else { - return VisitAndReturn((val1 == val2) != (iter->id == TokenID::NOTEQUAL)); } + const auto val2 = EvaluateChild(iter, 1); + if (!val2.has_value()) { + return false; + } + return VisitAndReturn((val1 == val2) != (iter->id == TokenID::NOTEQUAL)); } bool ASTInterpreter::ViOrdering(Cursor iter) { - if (const auto val1 = EvaluateChild(iter, 0); !val1.has_value()) { + const auto val1 = EvaluateChild(iter, 0); + if (!val1.has_value()) { return false; - } else if (const auto val2 = EvaluateChild(iter, 1); !val2.has_value()) { + } + const auto val2 = EvaluateChild(iter, 1); + if (!val2.has_value()) { return false; - } else { - const auto op1 = std::get(val1.value()).E().Value(); - const auto op2 = std::get(val2.value()).E().Value(); - switch (iter->id) { + } + const auto op1 = std::get(val1.value()).E().Value(); + const auto op2 = std::get(val2.value()).E().Value(); + switch (iter->id) { default: case TokenID::GREATER: return VisitAndReturn(op1 > op2); case TokenID::LESSER: return VisitAndReturn(op1 < op2); case TokenID::GREATER_OR_EQ: return VisitAndReturn(op1 >= op2); case TokenID::LESSER_OR_EQ: return VisitAndReturn(op1 <= op2); - } } } @@ -389,9 +400,11 @@ bool ASTInterpreter::ViDeclarative(Cursor iter) { return false; } idsData[varID] = child; - if (const auto predicatValue = EvaluateChild(iter, 2); !predicatValue.has_value()) { + const auto predicatValue = EvaluateChild(iter, 2); + if (!predicatValue.has_value()) { return false; - } else if (std::get(predicatValue.value())) { + } + if (std::get(predicatValue.value())) { result.ModifyB().AddElement(child); } } @@ -402,9 +415,8 @@ bool ASTInterpreter::ViImperative(const Cursor iter) { ImpEvaluator eval{ *this, iter }; if (!eval.Evaluate()) { return false; - } else { - return VisitAndReturn(eval.value); } + return VisitAndReturn(eval.value); } bool ASTInterpreter::ViRecursion(Cursor iter) { @@ -422,9 +434,11 @@ bool ASTInterpreter::ViRecursion(Cursor iter) { idsData[varID] = current; if (iter->id == TokenID::NT_RECURSIVE_FULL) { - if (const auto predicat = EvaluateChild(iter, 2); !predicat.has_value()) { + const auto predicat = EvaluateChild(iter, 2); + if (!predicat.has_value()) { return false; - } else if (!std::get(predicat.value())) { + } + if (!std::get(predicat.value())) { break; } } @@ -451,32 +465,38 @@ bool ASTInterpreter::ViDecart(Cursor iter) { if (std::get(curValue).B().Cardinality() == StructuredData::SET_INFINITY) { OnError(ValueEID::typedOverflow, iter->pos.start, std::to_string(StructuredData::SET_INFINITY)); return false; - } else { - return true; } + return true; } bool ASTInterpreter::ViBoolean(Cursor iter) { - if (const auto childValue = EvaluateChild(iter, 0); !childValue.has_value()) { + const auto childValue = EvaluateChild(iter, 0); + if (!childValue.has_value()) { return false; - } else if (const auto value = std::get(childValue.value()); - (iter.IsRoot() || (iter.Parent().id != TokenID::IN && iter.Parent().id != TokenID::NT_DECLARATIVE_EXPR)) && - value.B().Cardinality() >= StructuredData::BOOL_INFINITY) { - OnError(ValueEID::booleanLimit, iter->pos.start, std::to_string(StructuredData::BOOL_INFINITY)); - return false; - } else { - return VisitAndReturn(Factory::Boolean(value)); } + const auto value = std::get(childValue.value()); + if ( + (iter.IsRoot() || (iter.Parent().id != TokenID::IN && iter.Parent().id != TokenID::NT_DECLARATIVE_EXPR)) && + value.B().Cardinality() >= StructuredData::BOOL_INFINITY + ) { + OnError( + ValueEID::booleanLimit, + iter->pos.start, + std::to_string(StructuredData::BOOL_INFINITY) + ); + return false; + } + return VisitAndReturn(Factory::Boolean(value)); } bool ASTInterpreter::ViTuple(Cursor iter) { std::vector args{}; for (Index child = 0; child < iter.ChildrenCount(); ++child) { - if (const auto childValue = EvaluateChild(iter, child); !childValue.has_value()) { + const auto childValue = EvaluateChild(iter, child); + if (!childValue.has_value()) { return false; - } else { - args.emplace_back(std::get(childValue.value())); } + args.emplace_back(std::get(childValue.value())); } return VisitAndReturn(Factory::Tuple(args)); } @@ -484,32 +504,36 @@ bool ASTInterpreter::ViTuple(Cursor iter) { bool ASTInterpreter::ViSetEnum(Cursor iter) { std::vector args{}; for (Index child = 0; child < iter.ChildrenCount(); ++child) { - if (const auto childValue = EvaluateChild(iter, child); !childValue.has_value()) { + const auto childValue = EvaluateChild(iter, child); + if (!childValue.has_value()) { return false; - } else { - args.emplace_back(std::get(childValue.value())); } + args.emplace_back(std::get(childValue.value())); } return VisitAndReturn(Factory::Set(args)); } bool ASTInterpreter::ViBool(Cursor iter) { - if (const auto childValue = EvaluateChild(iter, 0); !childValue.has_value()) { + const auto childValue = EvaluateChild(iter, 0); + if (!childValue.has_value()) { return false; - } else { - return VisitAndReturn(Factory::Singleton(std::get(childValue.value()))); } + return VisitAndReturn(Factory::Singleton(std::get(childValue.value()))); } bool ASTInterpreter::ViTypedBinary(Cursor iter) { - if (const auto val1 = EvaluateChild(iter, 0); !val1.has_value()) { + const auto val1 = EvaluateChild(iter, 0); + if (!val1.has_value()) { return false; - } else if (const auto val2 = EvaluateChild(iter, 1); !val2.has_value()) { + } + const auto val2 = EvaluateChild(iter, 1); + if (!val2.has_value()) { return false; - } else { - const auto& op1 = std::get(val1.value()); - const auto& op2 = std::get(val2.value()); - switch (iter->id) { + } + + const auto& op1 = std::get(val1.value()); + const auto& op2 = std::get(val2.value()); + switch (iter->id) { default: case TokenID::UNION: return VisitAndReturn(op1.B().Union(op2.B())); case TokenID::INTERSECTION: return VisitAndReturn(op1.B().Intersect(op2.B())); @@ -521,16 +545,15 @@ bool ASTInterpreter::ViTypedBinary(Cursor iter) { case TokenID::SUBSET: return VisitAndReturn(!(op1 == op2) && op1.B().IsSubsetOrEq(op2.B())); case TokenID::NOTSUBSET: return VisitAndReturn(op1 == op2 || !op1.B().IsSubsetOrEq(op2.B())); case TokenID::SUBSET_OR_EQ: return VisitAndReturn(op1.B().IsSubsetOrEq(op2.B())); - } } } bool ASTInterpreter::ViProjectSet(Cursor iter) { - if (const auto childValue = EvaluateChild(iter, 0); !childValue.has_value()) { + const auto childValue = EvaluateChild(iter, 0); + if (!childValue.has_value()) { return false; - } else { - return VisitAndReturn(std::get(childValue.value()).B().Projection(iter->data.ToTuple())); } + return VisitAndReturn(std::get(childValue.value()).B().Projection(iter->data.ToTuple())); } bool ASTInterpreter::ViProjectTuple(Cursor iter) { @@ -562,9 +585,11 @@ bool ASTInterpreter::ViFilter(Cursor iter) { std::vector params{}; params.reserve(size(indicies)); for (Index child = 0; child < iter.ChildrenCount() - 1; ++child) { - if (const auto param = EvaluateChild(iter, child); !param.has_value()) { + const auto param = EvaluateChild(iter, child); + if (!param.has_value()) { return false; - } else if (const auto val = std::get(param.value()); val.B().IsEmpty()) { + } + if (const auto val = std::get(param.value()); val.B().IsEmpty()) { return VisitAndReturn(Factory::EmptySet()); } else { params.emplace_back(val); @@ -588,23 +613,24 @@ bool ASTInterpreter::ViFilter(Cursor iter) { } bool ASTInterpreter::ViReduce(Cursor iter) { - if (const auto childValue = EvaluateChild(iter, 0); !childValue.has_value()) { + const auto childValue = EvaluateChild(iter, 0); + if (!childValue.has_value()) { return false; - } else { - return VisitAndReturn(std::get(childValue.value()).B().Reduce()); } + return VisitAndReturn(std::get(childValue.value()).B().Reduce()); } bool ASTInterpreter::ViDebool(Cursor iter) { - if (const auto childValue = EvaluateChild(iter, 0); !childValue.has_value()) { + const auto childValue = EvaluateChild(iter, 0); + if (!childValue.has_value()) { return false; - } else if (const auto value = std::get(childValue.value()); - value.B().Cardinality() != 1) { + } + const auto value = std::get(childValue.value()); + if (value.B().Cardinality() != 1) { OnError(ValueEID::invalidDebool, iter->pos.start); return false; - } else { - return VisitAndReturn(std::get(childValue.value()).B().Debool()); } + return VisitAndReturn(std::get(childValue.value()).B().Debool()); } std::optional ASTInterpreter::EvaluateChild(Cursor iter, const Index index) { diff --git a/ccl/rslang/src/ASTNormalizer.cpp b/ccl/rslang/src/ASTNormalizer.cpp index 325f3a1..82890ae 100644 --- a/ccl/rslang/src/ASTNormalizer.cpp +++ b/ccl/rslang/src/ASTNormalizer.cpp @@ -57,14 +57,15 @@ void Normalizer::EnumDeclaration(SyntaxTree::Node& quant) { quant(0) = quant(0)(0); } -void Normalizer::TupleDeclaration(SyntaxTree::Node& declaration, - SyntaxTree::Node& predicat) { +void Normalizer::TupleDeclaration( + SyntaxTree::Node& declaration, + SyntaxTree::Node& predicate +) { const auto newName = CreateTupleName(declaration); declaration.RemoveAll(); declaration.token.data = TokenData{ newName }; declaration.token.id = TokenID::ID_LOCAL; - - SubstituteTupleVariables(predicat, newName); + SubstituteTupleVariables(predicate, newName); } void Normalizer::TupleDeclaration(SyntaxTree::Node& target) { @@ -116,7 +117,8 @@ std::string Normalizer::CreateTupleName(const SyntaxTree::Node& root) { void Normalizer::SubstituteTupleVariables(SyntaxTree::Node& target, const std::string& newName) { for (Index child = 0; child < target.ChildrenCount(); ++child) { if (target(child).token.id == TokenID::ID_LOCAL) { - if (const auto& localName = target(child).token.data.ToText(); tuples.contains(localName)) { + const auto& localName = target(child).token.data.ToText(); + if (tuples.contains(localName)) { const auto& indexes = tuples.at(localName); target(child).token.data = TokenData{ newName }; for (const auto prIndex : indexes) { @@ -164,12 +166,14 @@ void Normalizer::SubstituteArgs(SyntaxTree::Node& target, const StrRange pos) { SubstituteArgs(target(child), pos); } } else { - if (const auto& localName = target.token.ToString(); nodes.contains(localName)) { + const auto& localName = target.token.ToString(); + if (nodes.contains(localName)) { target = *nodes.at(localName); } else { const auto& oldName = target.token.ToString(); std::string newName{}; - if (const auto iter = nameSubstitutes.find(oldName); iter == std::end(nameSubstitutes)) { + const auto iter = nameSubstitutes.find(oldName); + if (iter == std::end(nameSubstitutes)) { ++localVarBase; newName = R"(__var)" + std::to_string(localVarBase); nameSubstitutes.insert(make_pair(oldName, newName)); diff --git a/ccl/rslang/src/AsciiLexerImpl.l b/ccl/rslang/src/AsciiLexerImpl.l index 3974113..d5b7637 100644 --- a/ccl/rslang/src/AsciiLexerImpl.l +++ b/ccl/rslang/src/AsciiLexerImpl.l @@ -23,97 +23,99 @@ public: [[nodiscard]] StrRange Range() const { // Note: returning byte position, not code point! Assume input is ASCII - return StrRange{ static_cast(matcher().first()), - static_cast(matcher().last()) }; + return StrRange{ + static_cast(matcher().first()), + static_cast(matcher().last()) + }; } %} -ws [ \t\r\n]+ -digit [0-9] -upper [A-Z] -lower [a-z] -alpha ({upper}|{lower}) -alnum (_|{digit}|{alpha}) +ws [ \t\r\n]+ +digit [0-9] +upper [A-Z] +lower [a-z] +alpha ({upper}|{lower}) +alnum (_|{digit}|{alpha}) number {digit}+ -index {number}(,{number})* +index {number}(,{number})* -global_id [||{upper}--[B]]{alnum}* +global_id [||{upper}--[B]]{alnum}* local_id (_|{lower}){alnum}* %% -"\A" { return TokenID::FORALL; } -"\E" { return TokenID::EXISTS; } +"\A" { return TokenID::FORALL; } +"\E" { return TokenID::EXISTS; } -"\neg" { return TokenID::NOT; } -"\and" { return TokenID::AND; } -"\or" { return TokenID::OR; } -"\impl" { return TokenID::IMPLICATION; } -"\equiv" { return TokenID::EQUIVALENT; } +"\neg" { return TokenID::NOT; } +"\and" { return TokenID::AND; } +"\or" { return TokenID::OR; } +"\impl" { return TokenID::IMPLICATION; } +"\equiv" { return TokenID::EQUIVALENT; } -"\plus" { return TokenID::PLUS; } -"\minus" { return TokenID::MINUS; } -"\multiply" { return TokenID::MULTIPLY; } -"\gr" { return TokenID::GREATER; } -"\ls" { return TokenID::LESSER; } -"\ge" { return TokenID::GREATER_OR_EQ; } -"\le" { return TokenID::LESSER_OR_EQ; } +"\plus" { return TokenID::PLUS; } +"\minus" { return TokenID::MINUS; } +"\multiply" { return TokenID::MULTIPLY; } +"\gr" { return TokenID::GREATER; } +"\ls" { return TokenID::LESSER; } +"\ge" { return TokenID::GREATER_OR_EQ; } +"\le" { return TokenID::LESSER_OR_EQ; } -"\eq" { return TokenID::EQUAL; } -"\noteq" { return TokenID::NOTEQUAL; } +"\eq" { return TokenID::EQUAL; } +"\noteq" { return TokenID::NOTEQUAL; } -"\in" { return TokenID::IN; } -"\notin" { return TokenID::NOTIN; } -"\subseteq" { return TokenID::SUBSET_OR_EQ; } -"\subset" { return TokenID::SUBSET; } -"\notsubset" { return TokenID::NOTSUBSET; } +"\in" { return TokenID::IN; } +"\notin" { return TokenID::NOTIN; } +"\subseteq" { return TokenID::SUBSET_OR_EQ; } +"\subset" { return TokenID::SUBSET; } +"\notsubset" { return TokenID::NOTSUBSET; } -"*" { return TokenID::DECART; } -"\union" { return TokenID::UNION; } -"\intersect" { return TokenID::INTERSECTION; } -"\setminus" { return TokenID::SET_MINUS; } -"\symmdiff" { return TokenID::SYMMINUS; } -"B" { return TokenID::BOOLEAN; } +"*" { return TokenID::DECART; } +"\union" { return TokenID::UNION; } +"\intersect" { return TokenID::INTERSECTION; } +"\setminus" { return TokenID::SET_MINUS; } +"\symmdiff" { return TokenID::SYMMINUS; } +"B" { return TokenID::BOOLEAN; } -pr{index} { return TokenID::SMALLPR; } -Pr{index} { return TokenID::BIGPR; } -Fi{index} { return TokenID::FILTER; } -card { return TokenID::CARD; } -bool { return TokenID::BOOL; } -red { return TokenID::REDUCE; } -debool { return TokenID::DEBOOL; } +pr{index} { return TokenID::SMALLPR; } +Pr{index} { return TokenID::BIGPR; } +Fi{index} { return TokenID::FILTER; } +card { return TokenID::CARD; } +bool { return TokenID::BOOL; } +red { return TokenID::REDUCE; } +debool { return TokenID::DEBOOL; } -D { return TokenID::DECLARATIVE; } -R { return TokenID::RECURSIVE; } -I { return TokenID::IMPERATIVE; } +D { return TokenID::DECLARATIVE; } +R { return TokenID::RECURSIVE; } +I { return TokenID::IMPERATIVE; } -Z { return TokenID::LIT_INTSET; } -"{}" { return TokenID::LIT_EMPTYSET; } -{number} { return TokenID::LIT_INTEGER; } +Z { return TokenID::LIT_INTSET; } +"{}" { return TokenID::LIT_EMPTYSET; } +{number} { return TokenID::LIT_INTEGER; } -F{number} { return TokenID::ID_FUNCTION; } -P{number} { return TokenID::ID_PREDICATE; } -R{number} { return TokenID::ID_RADICAL; } +F{number} { return TokenID::ID_FUNCTION; } +P{number} { return TokenID::ID_PREDICATE; } +R{number} { return TokenID::ID_RADICAL; } -{global_id} { return TokenID::ID_GLOBAL; } -{local_id} { return TokenID::ID_LOCAL; } +{global_id} { return TokenID::ID_GLOBAL; } +{local_id} { return TokenID::ID_LOCAL; } -"\assign" { return TokenID::PUNC_ASSIGN; } -"\from" { return TokenID::PUNC_ITERATE; } -"\defexpr" { return TokenID::PUNC_DEFINE; } -"\deftype" { return TokenID::PUNC_STRUCT; } -"(" { return TokenID::PUNC_PL; } -")" { return TokenID::PUNC_PR; } -"{" { return TokenID::PUNC_CL; } -"}" { return TokenID::PUNC_CR; } -"[" { return TokenID::PUNC_SL; } -"]" { return TokenID::PUNC_SR; } -"|" { return TokenID::PUNC_BAR; } -"," { return TokenID::PUNC_COMMA; } -";" { return TokenID::PUNC_SEMICOLON; } +"\assign" { return TokenID::PUNC_ASSIGN; } +"\from" { return TokenID::PUNC_ITERATE; } +"\defexpr" { return TokenID::PUNC_DEFINE; } +"\deftype" { return TokenID::PUNC_STRUCT; } +"(" { return TokenID::PUNC_PL; } +")" { return TokenID::PUNC_PR; } +"{" { return TokenID::PUNC_CL; } +"}" { return TokenID::PUNC_CR; } +"[" { return TokenID::PUNC_SL; } +"]" { return TokenID::PUNC_SR; } +"|" { return TokenID::PUNC_BAR; } +"," { return TokenID::PUNC_COMMA; } +";" { return TokenID::PUNC_SEMICOLON; } -{ws} ; -<> { return TokenID::END; } -. { return TokenID::INTERRUPT; } +{ws} ; +<> { return TokenID::END; } +. { return TokenID::INTERRUPT; } %% \ No newline at end of file diff --git a/ccl/rslang/src/ErrorLogger.cpp b/ccl/rslang/src/ErrorLogger.cpp index 832b167..1e111b0 100644 --- a/ccl/rslang/src/ErrorLogger.cpp +++ b/ccl/rslang/src/ErrorLogger.cpp @@ -21,9 +21,15 @@ void ErrorLogger::LogError(const Error& error) { } int32_t ErrorLogger::Count(const ErrorStatus status) const { - return static_cast(std::count_if(begin(errors), end(errors), - [&](const Error& error) noexcept - { return ResolveErrorType(error.eid) == status; })); + return static_cast( + std::count_if( + begin(errors), + end(errors), + [&](const Error& error) noexcept { + return ResolveErrorType(error.eid) == status; + } + ) + ); } ErrorReporter ErrorLogger::SendReporter() { @@ -33,17 +39,24 @@ ErrorReporter ErrorLogger::SendReporter() { StrPos ErrorLogger::FirstErrorPos() const { if (std::empty(errors)) { return 0; - } else { - return std::accumulate(next(begin(errors)), end(errors), begin(errors)->position, - [](StrPos minimum, const Error& error) - { return std::min(error.position, minimum); }); } + return std::accumulate( + next(begin(errors)), + end(errors), + begin(errors)->position, + [](StrPos minimum, const Error& error) { + return std::min(error.position, minimum); + }); } bool ErrorLogger::HasCriticalErrors() const { - return std::any_of(begin(errors), end(errors), - [](const Error& error) noexcept - { return error.IsCritical(); }); + return std::any_of( + begin(errors), + end(errors), + [](const Error& error) noexcept { + return error.IsCritical(); + } + ); } } // namespace ccl::rslang \ No newline at end of file diff --git a/ccl/rslang/src/Literals.cpp b/ccl/rslang/src/Literals.cpp index c2962ba..93b0018 100644 --- a/ccl/rslang/src/Literals.cpp +++ b/ccl/rslang/src/Literals.cpp @@ -47,19 +47,24 @@ Typification operator""_t(const char* input, const size_t /*size*/) { if (!parser.Parse(lexer(input).Stream())) { assert(false); return Typification::Integer(); - } else if (!analyse.CheckType(parser.AST())) { + } + if (!analyse.CheckType(parser.AST())) { assert(false); return Typification::Integer(); - } else if (const auto& result = analyse.GetType(); - !std::holds_alternative(result)) { + } + + const auto& result = analyse.GetType(); + if (!std::holds_alternative(result)) { assert(false); return Typification::Integer(); - } else if (const auto& type = std::get(result); !type.IsCollection()) { + } + + const auto& type = std::get(result); + if (!type.IsCollection()) { assert(false); return Typification::Integer(); - } else { - return type.B().Base(); } + return type.B().Base(); } std::string operator"" _rs(const char* input, const size_t size) { diff --git a/ccl/rslang/src/MathLexerImpl.l b/ccl/rslang/src/MathLexerImpl.l index a1e61f7..9d23383 100644 --- a/ccl/rslang/src/MathLexerImpl.l +++ b/ccl/rslang/src/MathLexerImpl.l @@ -26,98 +26,100 @@ public: StrPos lineBase{ 0 }; [[nodiscard]] StrRange Range() const { - return StrRange{ static_cast(lineBase + columno()), - static_cast(lineBase + columno() + columns()) }; + return StrRange{ + static_cast(lineBase + columno()), + static_cast(lineBase + columno() + columns()) + }; } %} -digit [0-9] -upper [A-Z] -lower [a-z\x{03B1}-\x{03C9}] -alpha ({upper}|{lower}) -alnum (_|{digit}|{alpha}) +digit [0-9] +upper [A-Z] +lower [a-z\x{03B1}-\x{03C9}] +alpha ({upper}|{lower}) +alnum (_|{digit}|{alpha}) number {digit}+ -index {number}(,{number})* +index {number}(,{number})* -global_id [||{upper}--[B]]{alnum}* +global_id [||{upper}--[B]]{alnum}* local_id (_|{lower}){alnum}* %% -"+" { return TokenID::PLUS; } -"-" { return TokenID::MINUS; } -"*" { return TokenID::MULTIPLY; } -">" { return TokenID::GREATER; } -"<" { return TokenID::LESSER; } -\x{2265} { return TokenID::GREATER_OR_EQ; } -\x{2264} { return TokenID::LESSER_OR_EQ; } +"+" { return TokenID::PLUS; } +"-" { return TokenID::MINUS; } +"*" { return TokenID::MULTIPLY; } +">" { return TokenID::GREATER; } +"<" { return TokenID::LESSER; } +\x{2265} { return TokenID::GREATER_OR_EQ; } +\x{2264} { return TokenID::LESSER_OR_EQ; } -"=" { return TokenID::EQUAL; } -\x{2260} { return TokenID::NOTEQUAL; } +"=" { return TokenID::EQUAL; } +\x{2260} { return TokenID::NOTEQUAL; } -\x{2200} { return TokenID::FORALL; } -\x{2203} { return TokenID::EXISTS; } +\x{2200} { return TokenID::FORALL; } +\x{2203} { return TokenID::EXISTS; } -\x{00AC} { return TokenID::NOT; } -"&" { return TokenID::AND; } -\x{2228} { return TokenID::OR; } -\x{21D2} { return TokenID::IMPLICATION; } -\x{21D4} { return TokenID::EQUIVALENT; } +\x{00AC} { return TokenID::NOT; } +"&" { return TokenID::AND; } +\x{2228} { return TokenID::OR; } +\x{21D2} { return TokenID::IMPLICATION; } +\x{21D4} { return TokenID::EQUIVALENT; } -:\x{2208} { return TokenID::PUNC_ITERATE; } -\x{2208} { return TokenID::IN; } -\x{2209} { return TokenID::NOTIN; } -\x{2286} { return TokenID::SUBSET_OR_EQ; } -\x{2282} { return TokenID::SUBSET; } -\x{2284} { return TokenID::NOTSUBSET; } +:\x{2208} { return TokenID::PUNC_ITERATE; } +\x{2208} { return TokenID::IN; } +\x{2209} { return TokenID::NOTIN; } +\x{2286} { return TokenID::SUBSET_OR_EQ; } +\x{2282} { return TokenID::SUBSET; } +\x{2284} { return TokenID::NOTSUBSET; } -\x{00D7} { return TokenID::DECART; } -\x{222A} { return TokenID::UNION; } -\x{2229} { return TokenID::INTERSECTION; } -\x{005C} { return TokenID::SET_MINUS; } -\x{2206} { return TokenID::SYMMINUS; } -\x{212C} { return TokenID::BOOLEAN; } +\x{00D7} { return TokenID::DECART; } +\x{222A} { return TokenID::UNION; } +\x{2229} { return TokenID::INTERSECTION; } +\x{005C} { return TokenID::SET_MINUS; } +\x{2206} { return TokenID::SYMMINUS; } +\x{212C} { return TokenID::BOOLEAN; } -pr{index} { return TokenID::SMALLPR; } -Pr{index} { return TokenID::BIGPR; } -Fi{index} { return TokenID::FILTER; } -card { return TokenID::CARD; } -bool { return TokenID::BOOL; } -red { return TokenID::REDUCE; } -debool { return TokenID::DEBOOL; } +pr{index} { return TokenID::SMALLPR; } +Pr{index} { return TokenID::BIGPR; } +Fi{index} { return TokenID::FILTER; } +card { return TokenID::CARD; } +bool { return TokenID::BOOL; } +red { return TokenID::REDUCE; } +debool { return TokenID::DEBOOL; } -D { return TokenID::DECLARATIVE; } -R { return TokenID::RECURSIVE; } -I { return TokenID::IMPERATIVE; } +D { return TokenID::DECLARATIVE; } +R { return TokenID::RECURSIVE; } +I { return TokenID::IMPERATIVE; } -Z { return TokenID::LIT_INTSET; } -\x{2205} { return TokenID::LIT_EMPTYSET; } -{number} { return TokenID::LIT_INTEGER; } +Z { return TokenID::LIT_INTSET; } +\x{2205} { return TokenID::LIT_EMPTYSET; } +{number} { return TokenID::LIT_INTEGER; } -F{number} { return TokenID::ID_FUNCTION; } -P{number} { return TokenID::ID_PREDICATE; } -R{number} { return TokenID::ID_RADICAL; } +F{number} { return TokenID::ID_FUNCTION; } +P{number} { return TokenID::ID_PREDICATE; } +R{number} { return TokenID::ID_RADICAL; } -{global_id} { return TokenID::ID_GLOBAL; } -{local_id} { return TokenID::ID_LOCAL; } +{global_id} { return TokenID::ID_GLOBAL; } +{local_id} { return TokenID::ID_LOCAL; } -":=" { return TokenID::PUNC_ASSIGN; } -":==" { return TokenID::PUNC_DEFINE; } -"::=" { return TokenID::PUNC_STRUCT; } -"(" { return TokenID::PUNC_PL; } -")" { return TokenID::PUNC_PR; } -"{" { return TokenID::PUNC_CL; } -"}" { return TokenID::PUNC_CR; } -"[" { return TokenID::PUNC_SL; } -"]" { return TokenID::PUNC_SR; } -"|" { return TokenID::PUNC_BAR; } -"," { return TokenID::PUNC_COMMA; } -";" { return TokenID::PUNC_SEMICOLON; } +":=" { return TokenID::PUNC_ASSIGN; } +":==" { return TokenID::PUNC_DEFINE; } +"::=" { return TokenID::PUNC_STRUCT; } +"(" { return TokenID::PUNC_PL; } +")" { return TokenID::PUNC_PR; } +"{" { return TokenID::PUNC_CL; } +"}" { return TokenID::PUNC_CR; } +"[" { return TokenID::PUNC_SL; } +"]" { return TokenID::PUNC_SR; } +"|" { return TokenID::PUNC_BAR; } +"," { return TokenID::PUNC_COMMA; } +";" { return TokenID::PUNC_SEMICOLON; } -\n { lineBase += static_cast(columno() + 1); } -[ \t]+ ; -<> { return TokenID::END; } -. { return TokenID::INTERRUPT; } +\n { lineBase += static_cast(columno() + 1); } +[ \t]+ ; +<> { return TokenID::END; } +. { return TokenID::INTERRUPT; } %% diff --git a/ccl/rslang/src/NameCollector.cpp b/ccl/rslang/src/NameCollector.cpp index 9389e0c..8ea5069 100644 --- a/ccl/rslang/src/NameCollector.cpp +++ b/ccl/rslang/src/NameCollector.cpp @@ -49,14 +49,15 @@ bool ASTInterpreter::NameCollector::ViGlobal(Cursor iter) { const auto nextID = static_cast(size(parent.idsData)); parent.idsBase.insert({ idName, nextID }); - if (const auto data = parent.context(iter->data.ToText()); data.has_value()) { - parent.idsData.emplace_back(data.value()); - parent.nodeVars[iter.get()] = { nextID }; - return true; - } else { + const auto data = parent.context(iter->data.ToText()); + if (!data.has_value()) { parent.OnError(ValueEID::globalMissingValue, iter->pos.start, iter->data.ToText()); return false; - } + + } + parent.idsData.emplace_back(data.value()); + parent.nodeVars[iter.get()] = { nextID }; + return true; } bool ASTInterpreter::NameCollector::ViLocal(Cursor iter) { diff --git a/ccl/rslang/src/RSGenerator.cpp b/ccl/rslang/src/RSGenerator.cpp index d8c2da1..4305229 100644 --- a/ccl/rslang/src/RSGenerator.cpp +++ b/ccl/rslang/src/RSGenerator.cpp @@ -6,10 +6,14 @@ #include "ccl/rslang/RSExpr.h" #include "ccl/rslang/Parser.h" +#include + namespace ccl::rslang { namespace { +using Description = Generator::StructureDescription; + [[nodiscard]] size_t FindArgumentSectionEnd(const std::string& input) { auto counter = 0; for (auto iter = UTF8Iterator(input); iter != UTF8End(input); ++iter) { @@ -26,46 +30,55 @@ namespace { return std::string::npos; } -[[nodiscard]] std::string SubstituteInPrefix(const StrSubstitutes& substitutes, - const std::vector& args, const TypeContext& env) { +[[nodiscard]] std::string SubstituteInPrefix( + const StrSubstitutes& substitutes, + const std::vector& args, + const TypeContext& env +) { FunctionArguments argsTypes{}; for (const auto& argName : args) { - if (const auto* type = env.TypeFor(argName); type == nullptr) { + const auto* type = env.TypeFor(argName); + if (type == nullptr) { return {}; - } else { - const auto& newName = substitutes.at(argName); - argsTypes.emplace_back(TypedID{ newName, std::get(*type) }); } + const auto& newName = substitutes.at(argName); + argsTypes.emplace_back(TypedID{ newName, std::get(*type) }); } return Generator::CreatePrefix(argsTypes); } -class StructureContextGenerator final { +class StructureGenerator final { private: - Generator::StructureDescription structure{}; + Description structure{}; public: - [[nodiscard]] static Generator::StructureDescription GenerateFor(const std::string& cstName, - const Typification& type); + [[nodiscard]] static Description GenerateFor( + const std::string& cstName, + const Typification& type + ); private: void GenerateRecursive(const std::string& currentStr, const Typification& type); void GenerateReduce(const std::string& currentStr, const Typification& type); void GenerateProjection(const std::string& currentStr, const Typification& type); - void CallRecursionForToken(const std::string& tokenText, - const std::string& currentStr, - const Typification& type); + void CallRecursionForToken( + const std::string& tokenText, + const std::string& currentStr, + const Typification& type + ); }; -Generator::StructureDescription StructureContextGenerator::GenerateFor(const std::string& cstName, - const Typification& type) { - static StructureContextGenerator generator{}; +Description StructureGenerator::GenerateFor( + const std::string& cstName, + const Typification& type +) { + static StructureGenerator generator{}; generator.structure.clear(); generator.GenerateRecursive(cstName, type); return generator.structure; } -void StructureContextGenerator::GenerateRecursive(const std::string& currentStr, const Typification& type) { +void StructureGenerator::GenerateRecursive(const std::string& currentStr, const Typification& type) { if (!empty(currentStr) && type.IsCollection()) { const auto& elementType = type.B().Base(); switch (elementType.Structure()) { @@ -76,11 +89,11 @@ void StructureContextGenerator::GenerateRecursive(const std::string& currentStr, } } -void StructureContextGenerator::GenerateReduce(const std::string& currentStr, const Typification& type) { +void StructureGenerator::GenerateReduce(const std::string& currentStr, const Typification& type) { CallRecursionForToken(rslang::Token::Str(rslang::TokenID::REDUCE), currentStr, type); } -void StructureContextGenerator::GenerateProjection(const std::string& currentStr, const Typification& type) { +void StructureGenerator::GenerateProjection(const std::string& currentStr, const Typification& type) { for (Index i = 0; i < type.T().Arity(); ++i) { Typification component = type.T().Component(Typification::PR_START + i); // NOLINT const auto tokenText = rslang::Token::Str(rslang::TokenID::BIGPR) + std::to_string(Typification::PR_START + i); @@ -88,9 +101,11 @@ void StructureContextGenerator::GenerateProjection(const std::string& currentStr } } -void StructureContextGenerator::CallRecursionForToken(const std::string& tokenText, - const std::string& currentStr, - const Typification& type) { +void StructureGenerator::CallRecursionForToken( + const std::string& tokenText, + const std::string& currentStr, + const Typification& type +) { std::string newStr = tokenText; newStr += '('; newStr += currentStr; @@ -99,8 +114,10 @@ void StructureContextGenerator::CallRecursionForToken(const std::string& tokenTe GenerateRecursive(newStr, type); } -[[nodiscard]] StrSubstitutes UniqueSubstitutes(const std::vector& args, - const std::unordered_set& takenNames) { +[[nodiscard]] StrSubstitutes UniqueSubstitutes( + const std::vector& args, + const std::unordered_set& takenNames +) { static constexpr auto LOCAL_ID_BASE = 1; static const std::string_view LOCAL_NAME_BASE = "arg"; StrSubstitutes substitutes{}; @@ -152,8 +169,10 @@ std::string Generator::ExtractPrefix(const std::string& declaration) { } } -std::string Generator::FunctionFromExpr(const std::vector& args, - const std::string& expression) const { +std::string Generator::FunctionFromExpr( + const std::vector& args, + const std::string& expression +) const { if (empty(args) || empty(expression)) { return expression; } @@ -183,9 +202,11 @@ std::string Generator::CreateCall(const std::string& funcName, const std::vector return funcName + '[' + argString + ']'; } -std::string Generator::TermFromFunction(const std::string& funcName, - const std::string& expression, - const std::vector& args) const { +std::string Generator::TermFromFunction( + const std::string& funcName, + const std::string& expression, + const std::vector& args +) const { const auto* argsTypes = environment.FunctionArgsFor(funcName); if (argsTypes == nullptr || ssize(*argsTypes) != ssize(args)) { return {}; @@ -208,9 +229,11 @@ std::string Generator::TermFromFunction(const std::string& funcName, return result; } -Generator::StructureDescription Generator::StructureFor(const std::string& globalName, - const Typification& type) { - return StructureContextGenerator::GenerateFor(globalName, type); +Generator::StructureDescription Generator::StructureFor( + const std::string& globalName, + const Typification& type +) { + return StructureGenerator::GenerateFor(globalName, type); } std::string ConvertTo(const std::string& input, const Syntax targetSyntax) { diff --git a/ccl/rslang/src/RSParserImpl.cpp b/ccl/rslang/src/RSParserImpl.cpp index ab15340..cdf85c3 100644 --- a/ccl/rslang/src/RSParserImpl.cpp +++ b/ccl/rslang/src/RSParserImpl.cpp @@ -1569,20 +1569,20 @@ namespace ccl { namespace rslang { namespace detail { "PLUS", "MINUS", "MULTIPLY", "GREATER", "LESSER", "GREATER_OR_EQ", "LESSER_OR_EQ", "EQUAL", "NOTEQUAL", "FORALL", "EXISTS", "NOT", "EQUIVALENT", "IMPLICATION", "OR", "AND", "IN", "NOTIN", "SUBSET", - "SUBOR_EQ", "NOTSUBSET", "DECART", "UNION", "INTERSECTION", "SET_MINUS", - "SYMMINUS", "BOOLEAN", "BIGPR", "SMALLPR", "FILTER", "CARD", "BOOL", - "DEBOOL", "RED", "DECLARATIVE", "RECURSIVE", "IMPERATIVE", "DEFINE", - "STRUCT", "ASSIGN", "ITERATE", "LP", "RP", "LC", "RC", "LS", "RS", "BAR", - "COMMA", "SEMICOLON", "$accept", "expression", "global_declaration", - "function_name", "logic_or_setexpr", "function_decl", "arguments", - "declaration", "variable", "var_enum", "var_all", "logic", "logic_all", - "logic_par", "logic_predicates", "binary_predicate", "logic_unary", - "logic_no_binary", "quantifier", "quant_var", "quant_var_enum", - "logic_binary", "setexpr", "operation_name", "setexpr_enum", - "setexpr_enum_min2", "literal", "identifier", "setexpr_binary", - "setexpr_generators", "enumeration", "tuple", "boolean", - "filter_expression", "declarative", "recursion", "imperative", - "imp_blocks", "imp_block", "RPE", "RCE", YY_NULLPTR + "SUBSET_OR_EQ", "NOTSUBSET", "DECART", "UNION", "INTERSECTION", + "SET_MINUS", "SYMMINUS", "BOOLEAN", "BIGPR", "SMALLPR", "FILTER", "CARD", + "BOOL", "DEBOOL", "RED", "DECLARATIVE", "RECURSIVE", "IMPERATIVE", + "DEFINE", "STRUCT", "ASSIGN", "ITERATE", "LP", "RP", "LC", "RC", "LS", + "RS", "BAR", "COMMA", "SEMICOLON", "$accept", "expression", + "global_declaration", "function_name", "logic_or_setexpr", + "function_decl", "arguments", "declaration", "variable", "var_enum", + "var_all", "logic", "logic_all", "logic_par", "logic_predicates", + "binary_predicate", "logic_unary", "logic_no_binary", "quantifier", + "quant_var", "quant_var_enum", "logic_binary", "setexpr", + "operation_name", "setexpr_enum", "setexpr_enum_min2", "literal", + "identifier", "setexpr_binary", "setexpr_generators", "enumeration", + "tuple", "boolean", "filter_expression", "declarative", "recursion", + "imperative", "imp_blocks", "imp_block", "RPE", "RCE", YY_NULLPTR }; #endif diff --git a/ccl/rslang/src/RSParserImpl.y b/ccl/rslang/src/RSParserImpl.y index 3e61659..0880bc0 100644 --- a/ccl/rslang/src/RSParserImpl.y +++ b/ccl/rslang/src/RSParserImpl.y @@ -199,7 +199,7 @@ RawNode Imperative( IN // IsElement NOTIN // NotElement SUBSET // IsSubset and NotEqual - SUBOR_EQ // IsSubset + SUBSET_OR_EQ // IsSubset NOTSUBSET // NotSubset @@ -331,7 +331,7 @@ binary_predicate : IN | NOTIN | SUBSET - | SUBOR_EQ + | SUBSET_OR_EQ | NOTSUBSET | NOTEQUAL | EQUAL diff --git a/ccl/rslang/src/TypeAuditor.cpp b/ccl/rslang/src/TypeAuditor.cpp index f7b0a61..978472a 100644 --- a/ccl/rslang/src/TypeAuditor.cpp +++ b/ccl/rslang/src/TypeAuditor.cpp @@ -12,10 +12,12 @@ namespace { void MangleRadicals(const std::string& funcName, Typification& type); std::string ToString(const ExpressionType& type) noexcept(false) { - return std::visit(meta::Overloads{ - [](const Typification& t) { return t.ToString(); }, - [](const LogicT& /*t*/) { return std::string{"LOGIC"}; }, - }, type); + return std::visit( + meta::Overloads{ + [](const Typification& t) { return t.ToString(); }, + [](const LogicT& /*t*/) { return std::string{"LOGIC"}; }, + } + , type); } constexpr bool IsSubset(const TokenID token) noexcept { @@ -142,42 +144,42 @@ bool TypeEnv::AreCompatible(const Typification& type1, const Typification& type2 std::optional TypeEnv::Merge(const Typification& type1, const Typification& type2) const { if (type1 == type2) { return type1; - } else if (type1.Structure() != type2.Structure()) { + } + if (type1.Structure() != type2.Structure()) { return std::nullopt; } switch (type1.Structure()) { default: - case rslang::StructureType::basic: { - if (const auto* type = CommonType(type1, type2); type == nullptr) { - return std::nullopt; - } else { + case rslang::StructureType::basic: { + const auto* type = CommonType(type1, type2); + if (type == nullptr) { + return std::nullopt; + } return *type; } - } - case rslang::StructureType::collection: { - if (auto base = Merge(type1.B().Base(), type2.B().Base()); !base.has_value()) { - return std::nullopt; - } else { + case rslang::StructureType::collection: { + auto base = Merge(type1.B().Base(), type2.B().Base()); + if (!base.has_value()) { + return std::nullopt; + } return base.value().ApplyBool(); } - } - case rslang::StructureType::tuple: { - if (type1.T().Arity() != type2.T().Arity()) { - return std::nullopt; - } else { + case rslang::StructureType::tuple: { + if (type1.T().Arity() != type2.T().Arity()) { + return std::nullopt; + } std::vector components{}; - for (auto index = Typification::PR_START; index < type1.T().Arity() + Typification::PR_START; ++index) { - if (auto component = Merge(type1.T().Component(index), type2.T().Component(index)); - !component.has_value()) { + const auto maxIndex = Typification::PR_START + type1.T().Arity(); + for (auto index = Typification::PR_START; index < maxIndex; ++index) { + auto component = Merge(type1.T().Component(index), type2.T().Component(index)); + if (!component.has_value()) { return std::nullopt; - } else { - components.emplace_back(std::move(component.value())); } + components.emplace_back(std::move(component.value())); } return Typification::Tuple(components); } } - } } bool TypeEnv::CompareTemplated( @@ -189,28 +191,33 @@ bool TypeEnv::CompareTemplated( return true; } if (arg.IsElement() && IsRadical(arg.E().baseID)) { - if (const auto& base = arg.E().baseID; !substitutes.contains(base)) { + const auto& base = arg.E().baseID; + if (!substitutes.contains(base)) { substitutes.insert({ base, value }); return true; - } else if (auto mergeType = Merge(substitutes.at(base), value); - !mergeType.has_value()) { - return false; - } else { - substitutes.at(base) = std::move(mergeType.value()); - return true; } + + auto mergeType = Merge(substitutes.at(base), value); + if (!mergeType.has_value()) { + return false; + } + substitutes.at(base) = std::move(mergeType.value()); + return true; } else if (arg.Structure() != value.Structure()) { return false; } else { switch (arg.Structure()) { - default: - case rslang::StructureType::basic: return CommonType(arg, value) != nullptr; - case rslang::StructureType::collection: return CompareTemplated(substitutes, arg.B().Base(), value.B().Base()); - case rslang::StructureType::tuple: { - if (arg.T().Arity() != value.T().Arity()) { - return false; - } else { - for (auto index = Typification::PR_START; index < arg.T().Arity() + Typification::PR_START; ++index) { + default: + case rslang::StructureType::basic: + return CommonType(arg, value) != nullptr; + case rslang::StructureType::collection: + return CompareTemplated(substitutes, arg.B().Base(), value.B().Base()); + case rslang::StructureType::tuple: { + if (arg.T().Arity() != value.T().Arity()) { + return false; + } + const auto maxIndex = Typification::PR_START + arg.T().Arity(); + for (auto index = Typification::PR_START; index < maxIndex; ++index) { if (!CompareTemplated(substitutes, arg.T().Component(index), value.T().Component(index))) { return false; } @@ -218,7 +225,6 @@ bool TypeEnv::CompareTemplated( return true; } } - } } } @@ -270,44 +276,59 @@ bool TypeAuditor::ViGlobalDefinition(Cursor iter) { if (childrenCount != 2 || !IsEchelon(iter, 1)) { OnError(SemanticEID::globalStructure, iter(0).pos.finish); return false; - } else if (const auto maybeType = ChildType(iter, 1); !maybeType.has_value()) { - return false; - } else if (const auto& type = std::get(maybeType.value()); !type.IsCollection()) { - return false; - } else { - return VisitAndReturn(type.B().Base()); } + const auto maybeType = ChildType(iter, 1); + if (!maybeType.has_value()) { + return false; + } + + const auto& type = std::get(maybeType.value()); + if (!type.IsCollection()) { + return false; + } + return VisitAndReturn(type.B().Base()); } else { assert(iter->id == TokenID::PUNC_DEFINE); if (childrenCount == 1) { return VisitAndReturn(Typification{ iter(0).data.ToText() }.ApplyBool()); - } else if (const auto type = ChildType(iter, 1); !type.has_value()) { + } + + const auto type = ChildType(iter, 1); + if (!type.has_value()) { return false; - } else { - return VisitAndReturn(type.value()); } + return VisitAndReturn(type.value()); } } bool TypeAuditor::ViFunctionDefinition(Cursor iter) { - if (const auto guard = isFuncDeclaration.CreateGuard(); !VisitChild(iter, 0)) { - return false; + { + const auto guard = isFuncDeclaration.CreateGuard(); + if (!VisitChild(iter, 0)) { + return false; + } } + for (auto n : functionArgsID) { functionArgs.emplace_back(localVars.at(n).arg); } - if (const auto type = ChildType(iter, 1); !type.has_value()) { + + const auto type = ChildType(iter, 1); + if (!type.has_value()) { return false; - } else { - return VisitAndReturn(type.value()); } + return VisitAndReturn(type.value()); } bool TypeAuditor::ViFunctionCall(Cursor iter) { const auto& funcName = iter(0).data.ToText(); const auto* funcType = env.context.TypeFor(funcName); if (funcType == nullptr) { - OnError(SemanticEID::globalNotTyped, iter->pos.start, funcName); + OnError( + SemanticEID::globalNotTyped, + iter->pos.start, + funcName + ); return false; } const auto substitutes = CheckFuncArguments(iter, funcName); @@ -329,13 +350,18 @@ bool TypeAuditor::ViFunctionCall(Cursor iter) { std::optional TypeAuditor::CheckFuncArguments(Cursor iter, const std::string& funcName) { const auto* args = env.context.FunctionArgsFor(funcName); if (args == nullptr) { - OnError(SemanticEID::globalFuncMissing, iter(0).pos.start, iter(0).data.ToText()); + OnError( + SemanticEID::globalFuncMissing, + iter(0).pos.start, + iter(0).data.ToText() + ); return std::nullopt; } const auto expectedArguments = iter.ChildrenCount() - 1; - if (const auto argCount = static_cast(ssize(*args)); argCount != expectedArguments) { + const auto argCount = static_cast(ssize(*args)); + if (argCount != expectedArguments) { OnError( - SemanticEID::invalidArgsArtity, + SemanticEID::invalidArgsArity, iter(1).pos.start, { std::to_string(expectedArguments), std::to_string(argCount) } ); @@ -351,7 +377,11 @@ std::optional TypeAuditor::CheckFuncArguments(Cursor Typification argType = args->at(static_cast(child) - 1).type; MangleRadicals(funcName, argType); if (!env.CompareTemplated(substitutes, argType, std::get(childType.value()))) { - OnError(SemanticEID::invalidArgumentType, iter(child).pos.start, argType, childType.value()); + OnError( + SemanticEID::invalidArgumentType, + iter(child).pos.start, argType, + childType.value() + ); return std::nullopt; } } @@ -361,19 +391,33 @@ std::optional TypeAuditor::CheckFuncArguments(Cursor bool TypeAuditor::ViGlobal(Cursor iter) { const auto& globalName = iter->data.ToText(); if (iter->id == TokenID::ID_RADICAL) { - if (isFuncDeclaration) { - return VisitAndReturn(Typification(globalName).ApplyBool()); - } else { - OnError(SemanticEID::radicalUsage, iter->pos.start, globalName); + if (!isFuncDeclaration) { + OnError( + SemanticEID::radicalUsage, + iter->pos.start, + globalName + ); return false; } - } else if (env.context.FunctionArgsFor(globalName) != nullptr) { - OnError(SemanticEID::globalFuncWithoutArgs, iter->pos.start, globalName); - return false; - } else if (const auto* type = env.context.TypeFor(globalName); type == nullptr) { - OnError(SemanticEID::globalNotTyped, iter->pos.start, globalName); - return false; + return VisitAndReturn(Typification(globalName).ApplyBool()); } else { + if (env.context.FunctionArgsFor(globalName) != nullptr) { + OnError( + SemanticEID::globalFuncWithoutArgs, + iter->pos.start, + globalName + ); + return false; + } + const auto* type = env.context.TypeFor(globalName); + if (type == nullptr) { + OnError( + SemanticEID::globalNotTyped, + iter->pos.start, + globalName + ); + return false; + } return VisitAndReturn(*type); } } @@ -384,11 +428,10 @@ bool TypeAuditor::ViLocal(Cursor iter) { return AddLocalVar(localName, std::get(currentType), iter->pos.start); } else { const auto* local = GetLocalTypification(localName, iter->pos.start); - if (local != nullptr) { - return VisitAndReturn(*local); - } else { + if (local == nullptr) { return false; } + return VisitAndReturn(*local); } } @@ -401,7 +444,7 @@ bool TypeAuditor::ViLocalBind(Cursor iter) { assert(isLocalDeclaration || isFuncDeclaration); const Typification type = std::get(currentType); if (!type.IsTuple() || type.T().Arity() != iter.ChildrenCount()) { - OnError(SemanticEID::ivalidBinding, iter(0).pos.start); + OnError(SemanticEID::invalidBinding, iter(0).pos.start); return false; } for (Index child = 0; child < iter.ChildrenCount(); ++child) { @@ -417,11 +460,10 @@ bool TypeAuditor::ViArgument(Cursor iter) { const auto domain = ChildTypeDebool(iter, 1, SemanticEID::invalidTypeOperation); if (!domain.has_value()) { return false; - } else { - const auto guard{ isArgDeclaration.CreateGuard() }; - currentType = domain.value(); - return VisitChild(iter, 0) && VisitAndReturn(LogicT{}); } + const auto guard{ isArgDeclaration.CreateGuard() }; + currentType = domain.value(); + return VisitChild(iter, 0) && VisitAndReturn(LogicT{}); } bool TypeAuditor::ViCard(Cursor iter) { @@ -430,85 +472,136 @@ bool TypeAuditor::ViCard(Cursor iter) { } bool TypeAuditor::ViArithmetic(Cursor iter) { - if (const auto test1 = ChildType(iter, 0); !test1.has_value()) { + const auto test1 = ChildType(iter, 0); + if (!test1.has_value()) { return false; - } else if (const auto& type1 = std::get(test1.value()); - !env.IsArithmetic(type1)) { - OnError(SemanticEID::arithmeticNotSupported, iter(0).pos.start, type1.ToString()); + } + + const auto& type1 = std::get(test1.value()); + if (!env.IsArithmetic(type1)) { + OnError( + SemanticEID::arithmeticNotSupported, + iter(0).pos.start, + type1.ToString() + ); return false; - } else if (const auto test2 = ChildType(iter, 1); !test2.has_value()) { + } + + const auto test2 = ChildType(iter, 1); + if (!test2.has_value()) { return false; - } else if (const auto& type2 = std::get(test2.value()); - !env.IsArithmetic(type2)) { - OnError(SemanticEID::arithmeticNotSupported, iter(1).pos.start, type2.ToString()); + } + + const auto& type2 = std::get(test2.value()); + if (!env.IsArithmetic(type2)) { + OnError( + SemanticEID::arithmeticNotSupported, + iter(1).pos.start, + type2.ToString() + ); return false; - } else if (const auto result = env.Merge(type1, type2); !result.has_value()) { - OnError(SemanticEID::typesNotCompatible, iter(1).pos.start, type1, type2); + } + + const auto result = env.Merge(type1, type2); + if (!result.has_value()) { + OnError( + SemanticEID::typesNotCompatible, + iter(1).pos.start, + type1, + type2 + ); return false; - } else { - return VisitAndReturn(result.value()); } + return VisitAndReturn(result.value()); } bool TypeAuditor::ViOrdering(Cursor iter) { - if(const auto test1 = ChildType(iter, 0); !test1.has_value()) { + const auto test1 = ChildType(iter, 0); + if(!test1.has_value()) { return false; - } else if (const auto& type1 = std::get(test1.value()); - !env.IsOrdered(type1)) { - OnError(SemanticEID::orderingNotSupported, iter(0).pos.start, type1.ToString()); + } + + const auto& type1 = std::get(test1.value()); + if (!env.IsOrdered(type1)) { + OnError( + SemanticEID::orderingNotSupported, + iter(0).pos.start, + type1.ToString() + ); return false; - } else if (const auto test2 = ChildType(iter, 1); !test2.has_value()) { + } + + const auto test2 = ChildType(iter, 1); + if (!test2.has_value()) { return false; - } else if (const auto& type2 = std::get(test2.value()); - !env.IsOrdered(type2)) { - OnError(SemanticEID::orderingNotSupported, iter(1).pos.start, type2.ToString()); + } + + const auto& type2 = std::get(test2.value()); + if (!env.IsOrdered(type2)) { + OnError( + SemanticEID::orderingNotSupported, + iter(1).pos.start, + type2.ToString() + ); return false; - } else if (!env.AreCompatible(type1, type2)) { - OnError(SemanticEID::typesNotCompatible, iter(1).pos.start, type1, type2); + } + + if (!env.AreCompatible(type1, type2)) { + OnError( + SemanticEID::typesNotCompatible, + iter(1).pos.start, + type1, + type2 + ); return false; - } else { - return VisitAndReturn(LogicT{}); } + return VisitAndReturn(LogicT{}); } bool TypeAuditor::ViQuantifier(Cursor iter) { StartScope(); - if (const auto domain = ChildTypeDebool(iter, 1, SemanticEID::invalidTypeOperation); !domain.has_value()) { + + const auto domain = ChildTypeDebool(iter, 1, SemanticEID::invalidTypeOperation); + if (!domain.has_value()) { return false; } else if (!VisitChildDeclaration(iter, 0, domain.value())) { return false; } else if (!VisitChild(iter, 2)) { return false; - } else { - EndScope(iter->pos.start); - return VisitAndReturn(LogicT{}); } + + EndScope(iter->pos.start); + return VisitAndReturn(LogicT{}); } bool TypeAuditor::ViEquals(Cursor iter) { if (iter(1).id == TokenID::LIT_EMPTYSET) { const auto type = ChildTypeDebool(iter, 0, SemanticEID::invalidEqualsEmpty); return type.has_value() && VisitAndReturn(LogicT{}); - } else { - const auto test1 = ChildType(iter, 0); - if (!test1.has_value()) { - return false; - } - const auto& type1 = std::get(test1.value()); - - const auto test2 = ChildType(iter, 1); - if (!test2.has_value()) { - return false; - } - const auto& type2 = std::get(test2.value()); - - if (!env.AreCompatible(type1, type2)) { - OnError(SemanticEID::typesNotCompatible, iter(1).pos.start, type1, type2); - return false; - } else { - return VisitAndReturn(LogicT{}); - } } + + const auto test1 = ChildType(iter, 0); + if (!test1.has_value()) { + return false; + } + const auto& type1 = std::get(test1.value()); + + const auto test2 = ChildType(iter, 1); + if (!test2.has_value()) { + return false; + } + const auto& type2 = std::get(test2.value()); + + if (!env.AreCompatible(type1, type2)) { + OnError( + SemanticEID::typesNotCompatible, + iter(1).pos.start, + type1, + type2 + ); + return false; + } + return VisitAndReturn(LogicT{}); } bool TypeAuditor::ViTypedPredicate(Cursor iter) { @@ -527,44 +620,56 @@ bool TypeAuditor::ViTypedPredicate(Cursor iter) { if (!env.AreCompatible(type1.value(), type2.value())) { if (isSubset) { - OnError(SemanticEID::typesNotEqual, iter(1).pos.start, type1.value(), type2.value()); + OnError( + SemanticEID::typesNotEqual, + iter(1).pos.start, + type1.value(), + type2.value() + ); } else { - OnError(SemanticEID::invalidElementPredicat, iter(1).pos.start, - { ToString(type1.value()), iter->ToString(), type2->Bool().ToString() }); + OnError( + SemanticEID::invalidElementPredicate, + iter(1).pos.start, + { ToString(type1.value()), iter->ToString(), type2->Bool().ToString() } + ); } return false; - } else { - return VisitAndReturn(LogicT{}); } + return VisitAndReturn(LogicT{}); } bool TypeAuditor::ViDeclarative(Cursor iter) { StartScope(); - if (auto domain = ChildTypeDebool(iter, 1, SemanticEID::invalidTypeOperation); !domain.has_value()) { + + auto domain = ChildTypeDebool(iter, 1, SemanticEID::invalidTypeOperation); + if (!domain.has_value()) { return false; } else if (!VisitChildDeclaration(iter, 0, domain.value())) { return false; } else if (!VisitChild(iter, 2)) { return false; - } else { - EndScope(iter->pos.start); - return VisitAndReturn(domain->ApplyBool()); } + + EndScope(iter->pos.start); + return VisitAndReturn(domain->ApplyBool()); } bool TypeAuditor::ViImperative(Cursor iter) { StartScope(); + for (Index child = 1; child < iter.ChildrenCount(); ++child) { if (!VisitChild(iter, child)) { return false; } } - if (auto type = ChildType(iter, 0); !type.has_value()) { + + auto type = ChildType(iter, 0); + if (!type.has_value()) { return false; - } else { - EndScope(iter->pos.start); - return VisitAndReturn(std::get(type.value()).Bool()); } + + EndScope(iter->pos.start); + return VisitAndReturn(std::get(type.value()).Bool()); } bool TypeAuditor::ViImpDeclare(Cursor iter) { @@ -581,6 +686,7 @@ bool TypeAuditor::ViImpAssign(Cursor iter) { bool TypeAuditor::ViRecursion(Cursor iter) { StartScope(); + auto initType = ChildType(iter, 1); if (!initType.has_value()) { return false; @@ -600,10 +706,15 @@ bool TypeAuditor::ViRecursion(Cursor iter) { if (!iterationType.has_value()) { return false; } else if (!env.AreCompatible(iterationType.value(), initType.value())) { - OnError(SemanticEID::typesNotEqual, iter(iterationIndex).pos.start, - iterationType.value(), initType.value()); + OnError( + SemanticEID::typesNotEqual, + iter(iterationIndex).pos.start, + iterationType.value(), + initType.value() + ); return false; } + EndScope(iter->pos.start); return VisitAndReturn(iterationType.value()); } @@ -622,21 +733,21 @@ bool TypeAuditor::ViDecart(Cursor iter) { } bool TypeAuditor::ViBoolean(Cursor iter) { - if (auto type = ChildTypeDebool(iter, 0, SemanticEID::invalidBoolean); !type.has_value()) { + auto type = ChildTypeDebool(iter, 0, SemanticEID::invalidBoolean); + if (!type.has_value()) { return false; - } else { - return VisitAndReturn(type->ApplyBool().ApplyBool()); } + return VisitAndReturn(type->ApplyBool().ApplyBool()); } bool TypeAuditor::ViTuple(Cursor iter) { std::vector components{}; for (Index child = 0; child < iter.ChildrenCount(); ++child) { - if (const auto type = ChildType(iter, child); !type.has_value()) { + const auto type = ChildType(iter, child); + if (!type.has_value()) { return false; - } else { - components.emplace_back(std::get(type.value())); } + components.emplace_back(std::get(type.value())); } return VisitAndReturn(Typification::Tuple(components)); } @@ -648,25 +759,32 @@ bool TypeAuditor::ViSetEnum(Cursor iter) { } auto& type = std::get(test.value()); for (Index child = 1; child < iter.ChildrenCount(); ++child) { - if (auto childType = ChildType(iter, child); !childType.has_value()) { + auto childType = ChildType(iter, child); + if (!childType.has_value()) { return false; - } else if (auto merge = env.Merge(type, std::get(childType.value())); - !merge.has_value()) { - OnError(SemanticEID::invalidEnumeration, iter(child).pos.start, type, childType.value()); + } + + auto merge = env.Merge(type, std::get(childType.value())); + if (!merge.has_value()) { + OnError( + SemanticEID::invalidEnumeration, + iter(child).pos.start, + type, + childType.value() + ); return false; - } else { - type = std::move(merge.value()); } + type = std::move(merge.value()); } return VisitAndReturn(type.Bool()); } bool TypeAuditor::ViDebool(Cursor iter) { - if (auto type = ChildTypeDebool(iter, 0, SemanticEID::invalidDebool); type.has_value()) { - return VisitAndReturn(type.value()); - } else { + auto type = ChildTypeDebool(iter, 0, SemanticEID::invalidDebool); + if (!type.has_value()) { return false; } + return VisitAndReturn(type.value()); } bool TypeAuditor::ViTypedBinary(Cursor iter) { @@ -674,16 +792,23 @@ bool TypeAuditor::ViTypedBinary(Cursor iter) { if (!type1.has_value()) { return false; } + auto type2 = ChildTypeDebool(iter, 1, SemanticEID::invalidTypeOperation); if (!type2.has_value()) { return false; } - if (const auto result = env.Merge(type1.value(), type2.value()); !result.has_value()) { - OnError(SemanticEID::typesNotEqual, iter(1).pos.start, type1->Bool(), type2->Bool()); + + const auto result = env.Merge(type1.value(), type2.value()); + if (!result.has_value()) { + OnError( + SemanticEID::typesNotEqual, + iter(1).pos.start, + type1->Bool(), + type2->Bool() + ); return false; - } else { - return VisitAndReturn(result.value().Bool()); } + return VisitAndReturn(result.value().Bool()); } bool TypeAuditor::ViProjectSet(Cursor iter) { @@ -693,7 +818,11 @@ bool TypeAuditor::ViProjectSet(Cursor iter) { return false; } if (!baseType->IsTuple()) { - OnError(SemanticEID::invalidProjectionSet, iter(0).pos.start, { iter->ToString(), baseType->ToString() }); + OnError( + SemanticEID::invalidProjectionSet, + iter(0).pos.start, + { iter->ToString(), baseType->ToString() } + ); return false; } @@ -702,7 +831,11 @@ bool TypeAuditor::ViProjectSet(Cursor iter) { components.reserve(size(indicies)); for (const auto index : indicies) { if (!baseType->T().TestIndex(index)) { - OnError(SemanticEID::invalidProjectionSet, iter(0).pos.start, { iter->ToString(), baseType->ToString() }); + OnError( + SemanticEID::invalidProjectionSet, + iter(0).pos.start, + { iter->ToString(), baseType->ToString() } + ); return false; } else { components.emplace_back(baseType->T().Component(index)); @@ -787,11 +920,14 @@ bool TypeAuditor::ViReduce(Cursor iter) { } const auto& base = std::get(baseType.value()); if (!base.IsCollection() || !base.B().Base().IsCollection()) { - OnError(SemanticEID::invalidReduce, iter(0).pos.start + 1, base.ToString()); + OnError( + SemanticEID::invalidReduce, + iter(0).pos.start + 1, + base.ToString() + ); return false; - } else { - return VisitAndReturn(base.B().Base()); } + return VisitAndReturn(base.B().Base()); } bool TypeAuditor::VisitAndReturn(ExpressionType type) noexcept { @@ -832,16 +968,22 @@ std::optional TypeAuditor::ChildTypeDebool(Cursor iter, const Inde return std::nullopt; } if (!std::get(result.value()).IsCollection()) { - OnError(eid, iter(index).pos.start, ToString(result.value())); + OnError( + eid, + iter(index).pos.start, + ToString(result.value()) + ); return std::nullopt; - } else { - return std::get(result.value()).B().Base(); } + return std::get(result.value()).B().Base(); } const Typification* TypeAuditor::GetLocalTypification(const std::string& name, const StrPos pos) { - const auto varIter = std::find_if(begin(localVars), end(localVars), - [&](const auto& data) noexcept { return data.arg.name == name; }); + const auto varIter = std::find_if( + begin(localVars), + end(localVars), + [&](const auto& data) noexcept { return data.arg.name == name; } + ); if (varIter == end(localVars)) { if (!isArgDeclaration) { OnError(SemanticEID::localUndeclared, pos, name); @@ -868,7 +1010,11 @@ void TypeAuditor::EndScope(const StrPos pos) { if (var.level < 0 && var.enabled) { var.enabled = false; if (var.useCount == 0) { - OnError(SemanticEID::localNotUsed, pos, var.arg.name); + OnError( + SemanticEID::localNotUsed, + pos, + var.arg.name + ); } } } @@ -879,10 +1025,18 @@ bool TypeAuditor::AddLocalVar(const std::string& name, const Typification& type, [&](const auto& data) noexcept { return data.arg.name == name; }); if (varIter != end(localVars)) { if (varIter->enabled) { - OnError(SemanticEID::localShadowing, pos, name); + OnError( + SemanticEID::localShadowing, + pos, + name + ); return false; } else { - OnError(SemanticEID::localDoubleDeclare, pos, name); + OnError( + SemanticEID::localDoubleDeclare, + pos, + name + ); varIter->arg.type = type; varIter->enabled = true; varIter->level = 0; diff --git a/ccl/rslang/src/ValueAuditor.cpp b/ccl/rslang/src/ValueAuditor.cpp index c125849..5c196b2 100644 --- a/ccl/rslang/src/ValueAuditor.cpp +++ b/ccl/rslang/src/ValueAuditor.cpp @@ -102,9 +102,11 @@ bool ValueAuditor::ViFunctionCall(Cursor iter) { } } -bool ValueAuditor::RunCheckOnFunc(Cursor iter, - const std::string& funcName, - const std::vector& argumentVals) { +bool ValueAuditor::RunCheckOnFunc( + Cursor iter, + const std::string& funcName, + const std::vector& argumentVals +) { const auto* ast = globalAST(funcName); if (ast == nullptr) { OnError(SemanticEID::globalMissingAST, iter->pos.start, funcName); @@ -123,10 +125,9 @@ bool ValueAuditor::RunCheckOnFunc(Cursor iter, if (!ast->Root().Child(1).Child(1).DispatchVisit(funcAuditor)) { OnError(SemanticEID::globalFuncNoInterpretation, iter->pos.start); return false; - } else { - current = funcAuditor.VType(); - return true; } + current = funcAuditor.VType(); + return true; } bool ValueAuditor::ViGlobal(Cursor iter) { @@ -138,10 +139,9 @@ bool ValueAuditor::ViGlobal(Cursor iter) { if (type == ValueClass::invalid) { OnError(SemanticEID::globalNoValue, iter->pos.start, globalName); return false; - } else { - current = type; - return true; } + current = type; + return true; } } diff --git a/ccl/rslang/test/src/testTypeAuditor.cpp b/ccl/rslang/test/src/testTypeAuditor.cpp index df69266..14cb578 100644 --- a/ccl/rslang/test/src/testTypeAuditor.cpp +++ b/ccl/rslang/test/src/testTypeAuditor.cpp @@ -215,8 +215,8 @@ TEST_F(UTTypeAuditor, LogicErrors) { ExpectError(R"(\A a \in X1*X1 a \eq {})", SemanticEID::invalidEqualsEmpty, 15); ExpectError(R"(\A (a,a) \in S1 pr2(a) \in X1)", SemanticEID::localShadowing, 6); - ExpectError(R"(\A (a,b) \in X1 1 \eq 1)", SemanticEID::ivalidBinding, 4); - ExpectError(R"(\A (a,b,c) \in S1 1 \eq 1)", SemanticEID::ivalidBinding, 4); + ExpectError(R"(\A (a,b) \in X1 1 \eq 1)", SemanticEID::invalidBinding, 4); + ExpectError(R"(\A (a,b,c) \in S1 1 \eq 1)", SemanticEID::invalidBinding, 4); ExpectError(R"(\A t \in X1 {t \in X1 | t \eq t} \eq X1)", SemanticEID::localShadowing, 13); ExpectError(R"(\A t \in X1 t \eq t \and t \eq X1)", SemanticEID::localOutOfScope, 25); @@ -289,17 +289,17 @@ TEST_F(UTTypeAuditor, TypedPredicatesCorrect) { TEST_F(UTTypeAuditor, TypedPredicatesError) { SetupConstants(); - ExpectError(R"(X1 \in X1)", SemanticEID::invalidElementPredicat, 7); - ExpectError(R"(S4 \in C2)", SemanticEID::invalidElementPredicat, 7); - ExpectError(R"(S5 \in Z)", SemanticEID::invalidElementPredicat, 7); - ExpectError(R"(S6 \in Z)", SemanticEID::invalidElementPredicat, 7); - ExpectError(R"((1,2) \in Z)", SemanticEID::invalidElementPredicat, 10); - ExpectError(R"({1} \in Z)", SemanticEID::invalidElementPredicat, 8); - ExpectError(R"((1,2) \in Z)", SemanticEID::invalidElementPredicat, 10); + ExpectError(R"(X1 \in X1)", SemanticEID::invalidElementPredicate, 7); + ExpectError(R"(S4 \in C2)", SemanticEID::invalidElementPredicate, 7); + ExpectError(R"(S5 \in Z)", SemanticEID::invalidElementPredicate, 7); + ExpectError(R"(S6 \in Z)", SemanticEID::invalidElementPredicate, 7); + ExpectError(R"((1,2) \in Z)", SemanticEID::invalidElementPredicate, 10); + ExpectError(R"({1} \in Z)", SemanticEID::invalidElementPredicate, 8); + ExpectError(R"((1,2) \in Z)", SemanticEID::invalidElementPredicate, 10); ExpectError(R"(X1 \subset S2)", SemanticEID::typesNotEqual, 11); - ExpectError(R"(X1 \notin X1)", SemanticEID::invalidElementPredicat, 10); + ExpectError(R"(X1 \notin X1)", SemanticEID::invalidElementPredicate, 10); ExpectError(R"(X1 \subseteq S2)", SemanticEID::typesNotEqual, 13); ExpectError(R"(X1 \notsubset S2)", SemanticEID::typesNotEqual, 14); } @@ -364,10 +364,10 @@ TEST_F(UTTypeAuditor, TypedFunctions) { ExpectTypification(R"(F1[Pr1(S1), Pr2(S1)])", "B(X1)"_t); ExpectError(R"(F1)", SemanticEID::globalFuncWithoutArgs, 0); - ExpectError(R"(F1[X1])", SemanticEID::invalidArgsArtity, 3); + ExpectError(R"(F1[X1])", SemanticEID::invalidArgsArity, 3); EXPECT_EQ(parser.log.All()[0].params[0], "1"); EXPECT_EQ(parser.log.All()[0].params[1], "2"); - ExpectError(R"(F1[X1, X1, X1])", SemanticEID::invalidArgsArtity, 3); + ExpectError(R"(F1[X1, X1, X1])", SemanticEID::invalidArgsArity, 3); EXPECT_EQ(parser.log.All()[0].params[0], "3"); EXPECT_EQ(parser.log.All()[0].params[1], "2"); @@ -388,8 +388,8 @@ TEST_F(UTTypeAuditor, LogicFunctions) { ExpectLogic(R"(P1[Pr1(S1), Pr2(S1)])"); ExpectError(R"(P1)", SemanticEID::globalFuncWithoutArgs, 0); - ExpectError(R"(P1[X1])", SemanticEID::invalidArgsArtity, 3); - ExpectError(R"(P1[X1, X1, X1])", SemanticEID::invalidArgsArtity, 3); + ExpectError(R"(P1[X1])", SemanticEID::invalidArgsArity, 3); + ExpectError(R"(P1[X1, X1, X1])", SemanticEID::invalidArgsArity, 3); ExpectError(R"(P1[S1, X1])", SemanticEID::invalidArgumentType, 3); ExpectError(R"(P1[X1, S1])", SemanticEID::invalidArgumentType, 7);