mirror of
https://github.com/IRBorisov/ConceptCore.git
synced 2025-06-26 09:10:37 +03:00
Fix EmptySet type check errors
This commit is contained in:
parent
de8e6df46b
commit
4786ba851b
|
@ -106,8 +106,8 @@ private:
|
||||||
void OnError(ValueEID eid, StrPos position);
|
void OnError(ValueEID eid, StrPos position);
|
||||||
void OnError(ValueEID eid, StrPos position, std::string param);
|
void OnError(ValueEID eid, StrPos position, std::string param);
|
||||||
|
|
||||||
[[nodiscard]] bool VisitAndReturn(ExpressionValue&& value) noexcept;
|
[[nodiscard]] bool SetCurrent(ExpressionValue&& value) noexcept;
|
||||||
[[nodiscard]] bool VisitAndReturn(const ExpressionValue& value) noexcept;
|
[[nodiscard]] bool SetCurrent(const ExpressionValue& value) noexcept;
|
||||||
[[nodiscard]] std::optional<ExpressionValue> EvaluateChild(Cursor iter, Index index);
|
[[nodiscard]] std::optional<ExpressionValue> EvaluateChild(Cursor iter, Index index);
|
||||||
|
|
||||||
[[nodiscard]] std::optional<object::StructuredData> ExtractDomain(Cursor iter);
|
[[nodiscard]] std::optional<object::StructuredData> ExtractDomain(Cursor iter);
|
||||||
|
|
|
@ -58,6 +58,7 @@ class TypeAuditor final : public ASTVisitor<TypeAuditor> {
|
||||||
types::GuardableBool isArgDeclaration{ false };
|
types::GuardableBool isArgDeclaration{ false };
|
||||||
types::GuardableBool isLocalDeclaration{ false };
|
types::GuardableBool isLocalDeclaration{ false };
|
||||||
types::GuardableBool isFuncDeclaration{ false };
|
types::GuardableBool isFuncDeclaration{ false };
|
||||||
|
types::GuardableBool noWarnings{ false };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TypeAuditor(const TypeContext& context) noexcept
|
explicit TypeAuditor(const TypeContext& context) noexcept
|
||||||
|
@ -79,21 +80,21 @@ protected:
|
||||||
|
|
||||||
bool ViGlobal(Cursor iter);
|
bool ViGlobal(Cursor iter);
|
||||||
bool ViLocal(Cursor iter);
|
bool ViLocal(Cursor iter);
|
||||||
bool ViInteger(Cursor /*iter*/) { return VisitAndReturn(Typification::Integer()); }
|
bool ViInteger(Cursor /*iter*/) { return SetCurrent(Typification::Integer()); }
|
||||||
bool ViIntegerSet(Cursor /*iter*/) { return VisitAndReturn(Typification::Integer().Bool()); }
|
bool ViIntegerSet(Cursor /*iter*/) { return SetCurrent(Typification::Integer().Bool()); }
|
||||||
bool ViEmptySet(Cursor /*iter*/);
|
bool ViEmptySet(Cursor /*iter*/);
|
||||||
|
|
||||||
bool ViLocalBind(Cursor iter);
|
bool ViLocalBind(Cursor iter);
|
||||||
bool ViLocalEnum(Cursor iter) { return VisitAllAndReturn(iter, LogicT{}); }
|
bool ViLocalEnum(Cursor iter) { return VisitAllAndSetCurrent(iter, LogicT{}); }
|
||||||
bool ViArgumentsEnum(Cursor iter) { return VisitAllAndReturn(iter, LogicT{}); }
|
bool ViArgumentsEnum(Cursor iter) { return VisitAllAndSetCurrent(iter, LogicT{}); }
|
||||||
bool ViArgument(Cursor iter);
|
bool ViArgument(Cursor iter);
|
||||||
|
|
||||||
bool ViArithmetic(Cursor iter);
|
bool ViArithmetic(Cursor iter);
|
||||||
bool ViCard(Cursor iter);
|
bool ViCard(Cursor iter);
|
||||||
|
|
||||||
bool ViQuantifier(Cursor iter);
|
bool ViQuantifier(Cursor iter);
|
||||||
bool ViNegation(Cursor iter) { return VisitAllAndReturn(iter, LogicT{}); }
|
bool ViNegation(Cursor iter) { return VisitAllAndSetCurrent(iter, LogicT{}); }
|
||||||
bool ViLogicBinary(Cursor iter) { return VisitAllAndReturn(iter, LogicT{}); }
|
bool ViLogicBinary(Cursor iter) { return VisitAllAndSetCurrent(iter, LogicT{}); }
|
||||||
bool ViEquals(Cursor iter);
|
bool ViEquals(Cursor iter);
|
||||||
bool ViOrdering(Cursor iter);
|
bool ViOrdering(Cursor iter);
|
||||||
bool ViTypedPredicate(Cursor iter);
|
bool ViTypedPredicate(Cursor iter);
|
||||||
|
@ -105,7 +106,7 @@ protected:
|
||||||
bool ViImperative(Cursor iter);
|
bool ViImperative(Cursor iter);
|
||||||
bool ViImpDeclare(Cursor iter);
|
bool ViImpDeclare(Cursor iter);
|
||||||
bool ViImpAssign(Cursor iter);
|
bool ViImpAssign(Cursor iter);
|
||||||
bool ViImpCheck(Cursor iter) { return VisitAllAndReturn(iter, LogicT{}); }
|
bool ViImpCheck(Cursor iter) { return VisitAllAndSetCurrent(iter, LogicT{}); }
|
||||||
bool ViRecursion(Cursor iter);
|
bool ViRecursion(Cursor iter);
|
||||||
|
|
||||||
bool ViTuple(Cursor iter);
|
bool ViTuple(Cursor iter);
|
||||||
|
@ -124,8 +125,8 @@ private:
|
||||||
|
|
||||||
[[nodiscard]] bool VisitChildDeclaration(const Cursor& iter, Index index, const Typification& domain);
|
[[nodiscard]] bool VisitChildDeclaration(const Cursor& iter, Index index, const Typification& domain);
|
||||||
|
|
||||||
[[nodiscard]] bool VisitAndReturn(ExpressionType type) noexcept;
|
[[nodiscard]] bool SetCurrent(ExpressionType type) noexcept;
|
||||||
[[nodiscard]] bool VisitAllAndReturn(Cursor iter, const ExpressionType& type);
|
[[nodiscard]] bool VisitAllAndSetCurrent(Cursor iter, const ExpressionType& type);
|
||||||
|
|
||||||
[[nodiscard]] std::optional<ExpressionType> ChildType(Cursor iter, Index index);
|
[[nodiscard]] std::optional<ExpressionType> ChildType(Cursor iter, Index index);
|
||||||
[[nodiscard]] std::optional<Typification> ChildTypeDebool(Cursor iter, Index index, SemanticEID eid);
|
[[nodiscard]] std::optional<Typification> ChildTypeDebool(Cursor iter, Index index, SemanticEID eid);
|
||||||
|
@ -139,7 +140,9 @@ private:
|
||||||
CheckFuncArguments(Cursor iter, const std::string& funcName);
|
CheckFuncArguments(Cursor iter, const std::string& funcName);
|
||||||
|
|
||||||
[[nodiscard]] const Typification* GetLocalTypification(const std::string& name, StrPos pos);
|
[[nodiscard]] const Typification* GetLocalTypification(const std::string& name, StrPos pos);
|
||||||
[[nodiscard]] bool AddLocalVar(const std::string& name, const Typification& type, StrPos pos);
|
[[nodiscard]] bool AddLocalVariable(const std::string& name, const Typification& type, StrPos pos);
|
||||||
|
void ClearLocalVariables();
|
||||||
|
|
||||||
void StartScope() noexcept;
|
void StartScope() noexcept;
|
||||||
void EndScope(StrPos pos);
|
void EndScope(StrPos pos);
|
||||||
};
|
};
|
||||||
|
|
|
@ -93,6 +93,8 @@ public:
|
||||||
public:
|
public:
|
||||||
using Substitutes = std::unordered_map<std::string, Typification>;
|
using Substitutes = std::unordered_map<std::string, Typification>;
|
||||||
|
|
||||||
|
[[nodiscard]] bool IsAnyType() const noexcept;
|
||||||
|
|
||||||
Typification& ApplyBool();
|
Typification& ApplyBool();
|
||||||
[[nodiscard]] Typification Bool() const;
|
[[nodiscard]] Typification Bool() const;
|
||||||
|
|
||||||
|
|
|
@ -40,23 +40,23 @@ protected:
|
||||||
|
|
||||||
bool ViGlobal(Cursor iter);
|
bool ViGlobal(Cursor iter);
|
||||||
bool ViLocal(Cursor iter);
|
bool ViLocal(Cursor iter);
|
||||||
bool ViInteger(Cursor /*iter*/) noexcept { return VisitAndReturn(ValueClass::value); }
|
bool ViInteger(Cursor /*iter*/) noexcept { return SetCurrent(ValueClass::value); }
|
||||||
bool ViIntegerSet(Cursor /*iter*/) noexcept { return VisitAndReturn(ValueClass::props); }
|
bool ViIntegerSet(Cursor /*iter*/) noexcept { return SetCurrent(ValueClass::props); }
|
||||||
bool ViEmptySet(Cursor /*iter*/) noexcept { return VisitAndReturn(ValueClass::value); }
|
bool ViEmptySet(Cursor /*iter*/) noexcept { return SetCurrent(ValueClass::value); }
|
||||||
|
|
||||||
bool ViLocalBind(Cursor iter) { return VisitAllAndReturn(iter, ValueClass::value); }
|
bool ViLocalBind(Cursor iter) { return VisitAllAndSetCurrent(iter, ValueClass::value); }
|
||||||
bool ViLocalEnum(Cursor iter) { return VisitAllAndReturn(iter, ValueClass::value); }
|
bool ViLocalEnum(Cursor iter) { return VisitAllAndSetCurrent(iter, ValueClass::value); }
|
||||||
bool ViArgumentsEnum(Cursor iter) { return VisitAllChildren(iter); }
|
bool ViArgumentsEnum(Cursor iter) { return VisitAllChildren(iter); }
|
||||||
bool ViArgument(Cursor iter) { return VisitAllChildren(iter); }
|
bool ViArgument(Cursor iter) { return VisitAllChildren(iter); }
|
||||||
|
|
||||||
bool ViArithmetic(Cursor iter) { return VisitAllAndReturn(iter, ValueClass::value); }
|
bool ViArithmetic(Cursor iter) { return VisitAllAndSetCurrent(iter, ValueClass::value); }
|
||||||
bool ViCard(Cursor iter) { return AssertChildIsValue(iter, 0); }
|
bool ViCard(Cursor iter) { return AssertChildIsValue(iter, 0); }
|
||||||
|
|
||||||
bool ViQuantifier(Cursor iter);
|
bool ViQuantifier(Cursor iter);
|
||||||
bool ViNegation(Cursor iter) { return VisitAllAndReturn(iter, ValueClass::value); }
|
bool ViNegation(Cursor iter) { return VisitAllAndSetCurrent(iter, ValueClass::value); }
|
||||||
bool ViLogicBinary(Cursor iter) { return VisitAllAndReturn(iter, ValueClass::value); }
|
bool ViLogicBinary(Cursor iter) { return VisitAllAndSetCurrent(iter, ValueClass::value); }
|
||||||
bool ViEquals(Cursor iter) { return AssertAllValues(iter); }
|
bool ViEquals(Cursor iter) { return AssertAllValues(iter); }
|
||||||
bool ViOrdering(Cursor iter) { return VisitAllAndReturn(iter, ValueClass::value); }
|
bool ViOrdering(Cursor iter) { return VisitAllAndSetCurrent(iter, ValueClass::value); }
|
||||||
bool ViTypedPredicate(Cursor iter);
|
bool ViTypedPredicate(Cursor iter);
|
||||||
|
|
||||||
bool ViDecart(Cursor iter);
|
bool ViDecart(Cursor iter);
|
||||||
|
@ -66,7 +66,7 @@ protected:
|
||||||
bool ViImperative(Cursor iter);
|
bool ViImperative(Cursor iter);
|
||||||
bool ViImpDeclare(Cursor iter) { return AssertChildIsValue(iter, 1); }
|
bool ViImpDeclare(Cursor iter) { return AssertChildIsValue(iter, 1); }
|
||||||
bool ViImpAssign(Cursor iter) { return AssertChildIsValue(iter, 1); }
|
bool ViImpAssign(Cursor iter) { return AssertChildIsValue(iter, 1); }
|
||||||
bool ViImpCheck(Cursor iter) { return VisitAllAndReturn(iter, ValueClass::value); }
|
bool ViImpCheck(Cursor iter) { return VisitAllAndSetCurrent(iter, ValueClass::value); }
|
||||||
bool ViRecursion(Cursor iter) { return AssertAllValues(iter); }
|
bool ViRecursion(Cursor iter) { return AssertAllValues(iter); }
|
||||||
|
|
||||||
bool ViTuple(Cursor iter) { return AssertAllValues(iter); }
|
bool ViTuple(Cursor iter) { return AssertAllValues(iter); }
|
||||||
|
@ -82,8 +82,8 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Clear() noexcept;
|
void Clear() noexcept;
|
||||||
[[nodiscard]] bool VisitAndReturn(ValueClass type) noexcept;
|
[[nodiscard]] bool SetCurrent(ValueClass type) noexcept;
|
||||||
[[nodiscard]] bool VisitAllAndReturn(Cursor iter, ValueClass type);
|
[[nodiscard]] bool VisitAllAndSetCurrent(Cursor iter, ValueClass type);
|
||||||
|
|
||||||
[[nodiscard]] bool AssertAllValues(Cursor iter);
|
[[nodiscard]] bool AssertAllValues(Cursor iter);
|
||||||
[[nodiscard]] bool AssertChildIsValue(Cursor iter, Index index);
|
[[nodiscard]] bool AssertChildIsValue(Cursor iter, Index index);
|
||||||
|
|
|
@ -215,12 +215,12 @@ void ASTInterpreter::Clear() noexcept {
|
||||||
countCriticalErrors = 0;
|
countCriticalErrors = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::VisitAndReturn(ExpressionValue&& value) noexcept {
|
bool ASTInterpreter::SetCurrent(ExpressionValue&& value) noexcept {
|
||||||
curValue = std::move(value);
|
curValue = std::move(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::VisitAndReturn(const ExpressionValue& value) noexcept {
|
bool ASTInterpreter::SetCurrent(const ExpressionValue& value) noexcept {
|
||||||
curValue = value;
|
curValue = value;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -230,11 +230,11 @@ bool ASTInterpreter::ViGlobalDefinition(Cursor iter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::ViLocal(Cursor iter) {
|
bool ASTInterpreter::ViLocal(Cursor iter) {
|
||||||
return VisitAndReturn(idsData[*begin(nodeVars[iter.get()])]);
|
return SetCurrent(idsData[*begin(nodeVars[iter.get()])]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::ViInteger(Cursor iter) {
|
bool ASTInterpreter::ViInteger(Cursor iter) {
|
||||||
return VisitAndReturn(Factory::Val(iter->data.ToInt()));
|
return SetCurrent(Factory::Val(iter->data.ToInt()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::ViIntegerSet(Cursor iter) {
|
bool ASTInterpreter::ViIntegerSet(Cursor iter) {
|
||||||
|
@ -243,7 +243,7 @@ bool ASTInterpreter::ViIntegerSet(Cursor iter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::ViEmptySet(Cursor /*iter*/) {
|
bool ASTInterpreter::ViEmptySet(Cursor /*iter*/) {
|
||||||
return VisitAndReturn(Factory::EmptySet());
|
return SetCurrent(Factory::EmptySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::ViArithmetic(Cursor iter) {
|
bool ASTInterpreter::ViArithmetic(Cursor iter) {
|
||||||
|
@ -260,11 +260,11 @@ bool ASTInterpreter::ViArithmetic(Cursor iter) {
|
||||||
switch (iter->id) {
|
switch (iter->id) {
|
||||||
default:
|
default:
|
||||||
case TokenID::PLUS:
|
case TokenID::PLUS:
|
||||||
return VisitAndReturn(Factory::Val(op1 + op2));
|
return SetCurrent(Factory::Val(op1 + op2));
|
||||||
case TokenID::MINUS:
|
case TokenID::MINUS:
|
||||||
return VisitAndReturn(Factory::Val(op1 - op2));
|
return SetCurrent(Factory::Val(op1 - op2));
|
||||||
case TokenID::MULTIPLY:
|
case TokenID::MULTIPLY:
|
||||||
return VisitAndReturn(Factory::Val(op1 * op2));
|
return SetCurrent(Factory::Val(op1 * op2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ bool ASTInterpreter::ViCard(Cursor iter) {
|
||||||
OnError(ValueEID::typedOverflow, iter->pos.start, std::to_string(StructuredData::SET_INFINITY));
|
OnError(ValueEID::typedOverflow, iter->pos.start, std::to_string(StructuredData::SET_INFINITY));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(Factory::Val(size));
|
return SetCurrent(Factory::Val(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::ViQuantifier(Cursor iter) {
|
bool ASTInterpreter::ViQuantifier(Cursor iter) {
|
||||||
|
@ -298,10 +298,10 @@ bool ASTInterpreter::ViQuantifier(Cursor iter) {
|
||||||
if (const auto iterationValue = EvaluateChild(iter, 2); !iterationValue.has_value()) {
|
if (const auto iterationValue = EvaluateChild(iter, 2); !iterationValue.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
} else if (std::get<bool>(iterationValue.value()) != isUniversal) {
|
} else if (std::get<bool>(iterationValue.value()) != isUniversal) {
|
||||||
return VisitAndReturn(!isUniversal);
|
return SetCurrent(!isUniversal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return VisitAndReturn(isUniversal);
|
return SetCurrent(isUniversal);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<StructuredData> ASTInterpreter::ExtractDomain(Cursor iter) {
|
std::optional<StructuredData> ASTInterpreter::ExtractDomain(Cursor iter) {
|
||||||
|
@ -316,7 +316,7 @@ bool ASTInterpreter::ViNegation(Cursor iter) {
|
||||||
if (!childValue.has_value()) {
|
if (!childValue.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(!std::get<bool>(childValue.value()));
|
return SetCurrent(!std::get<bool>(childValue.value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::ViLogicBinary(Cursor iter) {
|
bool ASTInterpreter::ViLogicBinary(Cursor iter) {
|
||||||
|
@ -347,9 +347,9 @@ bool ASTInterpreter::ViLogicBinary(Cursor iter) {
|
||||||
bool ASTInterpreter::TryEvaluateFromFirstArg(TokenID operation, bool firstArgValue) noexcept {
|
bool ASTInterpreter::TryEvaluateFromFirstArg(TokenID operation, bool firstArgValue) noexcept {
|
||||||
if ((operation == TokenID::AND && !firstArgValue) ||
|
if ((operation == TokenID::AND && !firstArgValue) ||
|
||||||
(operation == TokenID::OR && firstArgValue)) {
|
(operation == TokenID::OR && firstArgValue)) {
|
||||||
return VisitAndReturn(firstArgValue);
|
return SetCurrent(firstArgValue);
|
||||||
} else if (operation == TokenID::IMPLICATION && !firstArgValue) {
|
} else if (operation == TokenID::IMPLICATION && !firstArgValue) {
|
||||||
return VisitAndReturn(!firstArgValue);
|
return SetCurrent(!firstArgValue);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -364,7 +364,7 @@ bool ASTInterpreter::ViEquals(Cursor iter) {
|
||||||
if (!val2.has_value()) {
|
if (!val2.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn((val1 == val2) != (iter->id == TokenID::NOTEQUAL));
|
return SetCurrent((val1 == val2) != (iter->id == TokenID::NOTEQUAL));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::ViOrdering(Cursor iter) {
|
bool ASTInterpreter::ViOrdering(Cursor iter) {
|
||||||
|
@ -380,10 +380,10 @@ bool ASTInterpreter::ViOrdering(Cursor iter) {
|
||||||
const auto op2 = std::get<StructuredData>(val2.value()).E().Value();
|
const auto op2 = std::get<StructuredData>(val2.value()).E().Value();
|
||||||
switch (iter->id) {
|
switch (iter->id) {
|
||||||
default:
|
default:
|
||||||
case TokenID::GREATER: return VisitAndReturn(op1 > op2);
|
case TokenID::GREATER: return SetCurrent(op1 > op2);
|
||||||
case TokenID::LESSER: return VisitAndReturn(op1 < op2);
|
case TokenID::LESSER: return SetCurrent(op1 < op2);
|
||||||
case TokenID::GREATER_OR_EQ: return VisitAndReturn(op1 >= op2);
|
case TokenID::GREATER_OR_EQ: return SetCurrent(op1 >= op2);
|
||||||
case TokenID::LESSER_OR_EQ: return VisitAndReturn(op1 <= op2);
|
case TokenID::LESSER_OR_EQ: return SetCurrent(op1 <= op2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,7 +408,7 @@ bool ASTInterpreter::ViDeclarative(Cursor iter) {
|
||||||
result.ModifyB().AddElement(child);
|
result.ModifyB().AddElement(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return VisitAndReturn(std::move(result));
|
return SetCurrent(std::move(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::ViImperative(const Cursor iter) {
|
bool ASTInterpreter::ViImperative(const Cursor iter) {
|
||||||
|
@ -416,7 +416,7 @@ bool ASTInterpreter::ViImperative(const Cursor iter) {
|
||||||
if (!eval.Evaluate()) {
|
if (!eval.Evaluate()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(eval.value);
|
return SetCurrent(eval.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::ViRecursion(Cursor iter) {
|
bool ASTInterpreter::ViRecursion(Cursor iter) {
|
||||||
|
@ -448,7 +448,7 @@ bool ASTInterpreter::ViRecursion(Cursor iter) {
|
||||||
}
|
}
|
||||||
current = std::get<StructuredData>(curValue);
|
current = std::get<StructuredData>(curValue);
|
||||||
} while (idsData[varID] != current);
|
} while (idsData[varID] != current);
|
||||||
return VisitAndReturn(std::move(current));
|
return SetCurrent(std::move(current));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::ViDecart(Cursor iter) {
|
bool ASTInterpreter::ViDecart(Cursor iter) {
|
||||||
|
@ -486,7 +486,7 @@ bool ASTInterpreter::ViBoolean(Cursor iter) {
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(Factory::Boolean(value));
|
return SetCurrent(Factory::Boolean(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::ViTuple(Cursor iter) {
|
bool ASTInterpreter::ViTuple(Cursor iter) {
|
||||||
|
@ -498,7 +498,7 @@ bool ASTInterpreter::ViTuple(Cursor iter) {
|
||||||
}
|
}
|
||||||
args.emplace_back(std::get<StructuredData>(childValue.value()));
|
args.emplace_back(std::get<StructuredData>(childValue.value()));
|
||||||
}
|
}
|
||||||
return VisitAndReturn(Factory::Tuple(args));
|
return SetCurrent(Factory::Tuple(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::ViSetEnum(Cursor iter) {
|
bool ASTInterpreter::ViSetEnum(Cursor iter) {
|
||||||
|
@ -510,7 +510,7 @@ bool ASTInterpreter::ViSetEnum(Cursor iter) {
|
||||||
}
|
}
|
||||||
args.emplace_back(std::get<StructuredData>(childValue.value()));
|
args.emplace_back(std::get<StructuredData>(childValue.value()));
|
||||||
}
|
}
|
||||||
return VisitAndReturn(Factory::Set(args));
|
return SetCurrent(Factory::Set(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::ViBool(Cursor iter) {
|
bool ASTInterpreter::ViBool(Cursor iter) {
|
||||||
|
@ -518,7 +518,7 @@ bool ASTInterpreter::ViBool(Cursor iter) {
|
||||||
if (!childValue.has_value()) {
|
if (!childValue.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(Factory::Singleton(std::get<StructuredData>(childValue.value())));
|
return SetCurrent(Factory::Singleton(std::get<StructuredData>(childValue.value())));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::ViTypedBinary(Cursor iter) {
|
bool ASTInterpreter::ViTypedBinary(Cursor iter) {
|
||||||
|
@ -535,16 +535,16 @@ bool ASTInterpreter::ViTypedBinary(Cursor iter) {
|
||||||
const auto& op2 = std::get<StructuredData>(val2.value());
|
const auto& op2 = std::get<StructuredData>(val2.value());
|
||||||
switch (iter->id) {
|
switch (iter->id) {
|
||||||
default:
|
default:
|
||||||
case TokenID::UNION: return VisitAndReturn(op1.B().Union(op2.B()));
|
case TokenID::UNION: return SetCurrent(op1.B().Union(op2.B()));
|
||||||
case TokenID::INTERSECTION: return VisitAndReturn(op1.B().Intersect(op2.B()));
|
case TokenID::INTERSECTION: return SetCurrent(op1.B().Intersect(op2.B()));
|
||||||
case TokenID::SET_MINUS: return VisitAndReturn(op1.B().Diff(op2.B()));
|
case TokenID::SET_MINUS: return SetCurrent(op1.B().Diff(op2.B()));
|
||||||
case TokenID::SYMMINUS: return VisitAndReturn(op1.B().SymDiff(op2.B()));
|
case TokenID::SYMMINUS: return SetCurrent(op1.B().SymDiff(op2.B()));
|
||||||
|
|
||||||
case TokenID::IN: return VisitAndReturn(op2.B().Contains(op1));
|
case TokenID::IN: return SetCurrent(op2.B().Contains(op1));
|
||||||
case TokenID::NOTIN: return VisitAndReturn(!op2.B().Contains(op1));
|
case TokenID::NOTIN: return SetCurrent(!op2.B().Contains(op1));
|
||||||
case TokenID::SUBSET: return VisitAndReturn(!(op1 == op2) && op1.B().IsSubsetOrEq(op2.B()));
|
case TokenID::SUBSET: return SetCurrent(!(op1 == op2) && op1.B().IsSubsetOrEq(op2.B()));
|
||||||
case TokenID::NOTSUBSET: return VisitAndReturn(op1 == op2 || !op1.B().IsSubsetOrEq(op2.B()));
|
case TokenID::NOTSUBSET: return SetCurrent(op1 == op2 || !op1.B().IsSubsetOrEq(op2.B()));
|
||||||
case TokenID::SUBSET_OR_EQ: return VisitAndReturn(op1.B().IsSubsetOrEq(op2.B()));
|
case TokenID::SUBSET_OR_EQ: return SetCurrent(op1.B().IsSubsetOrEq(op2.B()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,7 +553,7 @@ bool ASTInterpreter::ViProjectSet(Cursor iter) {
|
||||||
if (!childValue.has_value()) {
|
if (!childValue.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(std::get<StructuredData>(childValue.value()).B().Projection(iter->data.ToTuple()));
|
return SetCurrent(std::get<StructuredData>(childValue.value()).B().Projection(iter->data.ToTuple()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::ViProjectTuple(Cursor iter) {
|
bool ASTInterpreter::ViProjectTuple(Cursor iter) {
|
||||||
|
@ -568,7 +568,7 @@ bool ASTInterpreter::ViProjectTuple(Cursor iter) {
|
||||||
for (const auto index : indicies) {
|
for (const auto index : indicies) {
|
||||||
components.emplace_back(std::get<StructuredData>(childValue.value()).T().Component(index));
|
components.emplace_back(std::get<StructuredData>(childValue.value()).T().Component(index));
|
||||||
}
|
}
|
||||||
return VisitAndReturn(Factory::Tuple(components));
|
return SetCurrent(Factory::Tuple(components));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::ViFilter(Cursor iter) {
|
bool ASTInterpreter::ViFilter(Cursor iter) {
|
||||||
|
@ -578,7 +578,7 @@ bool ASTInterpreter::ViFilter(Cursor iter) {
|
||||||
}
|
}
|
||||||
const auto& argument = std::get<StructuredData>(argumentValue.value());
|
const auto& argument = std::get<StructuredData>(argumentValue.value());
|
||||||
if (argument.B().IsEmpty()) {
|
if (argument.B().IsEmpty()) {
|
||||||
return VisitAndReturn(Factory::EmptySet());
|
return SetCurrent(Factory::EmptySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& indicies = iter->data.ToTuple();
|
const auto& indicies = iter->data.ToTuple();
|
||||||
|
@ -590,7 +590,7 @@ bool ASTInterpreter::ViFilter(Cursor iter) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (const auto val = std::get<StructuredData>(param.value()); val.B().IsEmpty()) {
|
if (const auto val = std::get<StructuredData>(param.value()); val.B().IsEmpty()) {
|
||||||
return VisitAndReturn(Factory::EmptySet());
|
return SetCurrent(Factory::EmptySet());
|
||||||
} else {
|
} else {
|
||||||
params.emplace_back(val);
|
params.emplace_back(val);
|
||||||
}
|
}
|
||||||
|
@ -609,7 +609,7 @@ bool ASTInterpreter::ViFilter(Cursor iter) {
|
||||||
result.ModifyB().AddElement(element);
|
result.ModifyB().AddElement(element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return VisitAndReturn(std::move(result));
|
return SetCurrent(std::move(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::ViReduce(Cursor iter) {
|
bool ASTInterpreter::ViReduce(Cursor iter) {
|
||||||
|
@ -617,7 +617,7 @@ bool ASTInterpreter::ViReduce(Cursor iter) {
|
||||||
if (!childValue.has_value()) {
|
if (!childValue.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(std::get<StructuredData>(childValue.value()).B().Reduce());
|
return SetCurrent(std::get<StructuredData>(childValue.value()).B().Reduce());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTInterpreter::ViDebool(Cursor iter) {
|
bool ASTInterpreter::ViDebool(Cursor iter) {
|
||||||
|
@ -630,7 +630,7 @@ bool ASTInterpreter::ViDebool(Cursor iter) {
|
||||||
OnError(ValueEID::invalidDebool, iter->pos.start);
|
OnError(ValueEID::invalidDebool, iter->pos.start);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(std::get<StructuredData>(childValue.value()).B().Debool());
|
return SetCurrent(std::get<StructuredData>(childValue.value()).B().Debool());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ExpressionValue> ASTInterpreter::EvaluateChild(Cursor iter, const Index index) {
|
std::optional<ExpressionValue> ASTInterpreter::EvaluateChild(Cursor iter, const Index index) {
|
||||||
|
|
|
@ -50,7 +50,7 @@ bool IsEchelon(SyntaxTree::Cursor iter, const Index index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsRadical(const std::string& globalName) {
|
bool IsRadical(const std::string& globalName) {
|
||||||
return !empty(globalName) && globalName.at(0) == 'R';
|
return !empty(globalName) && globalName.at(0) == 'R' && globalName.at(1) != '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
void MangleRadicals(const std::string& funcName, Typification& type) {
|
void MangleRadicals(const std::string& funcName, Typification& type) {
|
||||||
|
@ -122,12 +122,11 @@ bool TypeEnv::AreCompatible(const Typification& type1, const Typification& type2
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto struct1 = type1.Structure();
|
const auto struct1 = type1.Structure();
|
||||||
const auto struct2 = type2.Structure();
|
if (struct1 == rslang::StructureType::basic && type1.IsAnyType()) {
|
||||||
|
|
||||||
if (struct1 == rslang::StructureType::basic && type1.E().baseID == Typification::anyTypificationName) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (struct2 == rslang::StructureType::basic && type2.E().baseID == Typification::anyTypificationName) {
|
const auto struct2 = type2.Structure();
|
||||||
|
if (struct2 == rslang::StructureType::basic && type2.IsAnyType()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (struct1 != struct2) {
|
if (struct1 != struct2) {
|
||||||
|
@ -157,19 +156,18 @@ std::optional<Typification> TypeEnv::Merge(const Typification& type1, const Typi
|
||||||
if (type1 == type2) {
|
if (type1 == type2) {
|
||||||
return type1;
|
return type1;
|
||||||
}
|
}
|
||||||
if (type1.Structure() != type2.Structure()) {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto struct1 = type1.Structure();
|
const auto struct1 = type1.Structure();
|
||||||
const auto struct2 = type2.Structure();
|
if (struct1 == rslang::StructureType::basic && type1.IsAnyType()) {
|
||||||
|
|
||||||
if (struct1 == rslang::StructureType::basic && type1.E().baseID == Typification::anyTypificationName) {
|
|
||||||
return type2;
|
return type2;
|
||||||
}
|
}
|
||||||
if (struct2 == rslang::StructureType::basic && type2.E().baseID == Typification::anyTypificationName) {
|
const auto struct2 = type2.Structure();
|
||||||
|
if (struct2 == rslang::StructureType::basic && type2.IsAnyType()) {
|
||||||
return type1;
|
return type1;
|
||||||
}
|
}
|
||||||
|
if (struct1 != struct2) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
switch (struct1) {
|
switch (struct1) {
|
||||||
default:
|
default:
|
||||||
|
@ -218,18 +216,25 @@ bool TypeEnv::CompareTemplated(
|
||||||
if (!substitutes.contains(base)) {
|
if (!substitutes.contains(base)) {
|
||||||
substitutes.insert({ base, value });
|
substitutes.insert({ base, value });
|
||||||
return true;
|
return true;
|
||||||
}
|
} else {
|
||||||
|
|
||||||
auto mergeType = Merge(substitutes.at(base), value);
|
auto mergeType = Merge(substitutes.at(base), value);
|
||||||
if (!mergeType.has_value()) {
|
if (!mergeType.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
substitutes.at(base) = std::move(mergeType.value());
|
substitutes.at(base) = std::move(mergeType.value());
|
||||||
return true;
|
return true;
|
||||||
} else if (arg.Structure() != value.Structure()) {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto valueStructure = value.Structure();
|
||||||
|
if (valueStructure == rslang::StructureType::basic && value.IsAnyType()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const auto argStructure = arg.Structure();
|
||||||
|
if (argStructure != valueStructure) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
}
|
||||||
switch (arg.Structure()) {
|
switch (argStructure) {
|
||||||
default:
|
default:
|
||||||
case rslang::StructureType::basic:
|
case rslang::StructureType::basic:
|
||||||
return CommonType(arg, value) != nullptr;
|
return CommonType(arg, value) != nullptr;
|
||||||
|
@ -249,7 +254,6 @@ bool TypeEnv::CompareTemplated(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace details
|
} // namespace details
|
||||||
|
|
||||||
|
@ -313,18 +317,18 @@ bool TypeAuditor::ViGlobalDefinition(Cursor iter) {
|
||||||
if (!type.IsCollection()) {
|
if (!type.IsCollection()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(type.B().Base());
|
return SetCurrent(type.B().Base());
|
||||||
} else {
|
} else {
|
||||||
assert(iter->id == TokenID::PUNC_DEFINE);
|
assert(iter->id == TokenID::PUNC_DEFINE);
|
||||||
if (childrenCount == 1) {
|
if (childrenCount == 1) {
|
||||||
return VisitAndReturn(Typification{ iter(0).data.ToText() }.ApplyBool());
|
return SetCurrent(Typification{ iter(0).data.ToText() }.ApplyBool());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto type = ChildType(iter, 1);
|
const auto type = ChildType(iter, 1);
|
||||||
if (!type.has_value()) {
|
if (!type.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(type.value());
|
return SetCurrent(type.value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,7 +348,7 @@ bool TypeAuditor::ViFunctionDefinition(Cursor iter) {
|
||||||
if (!type.has_value()) {
|
if (!type.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(type.value());
|
return SetCurrent(type.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViFunctionCall(Cursor iter) {
|
bool TypeAuditor::ViFunctionCall(Cursor iter) {
|
||||||
|
@ -363,14 +367,14 @@ bool TypeAuditor::ViFunctionCall(Cursor iter) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!std::holds_alternative<Typification>(*funcType)) {
|
if (!std::holds_alternative<Typification>(*funcType)) {
|
||||||
return VisitAndReturn(*funcType);
|
return SetCurrent(*funcType);
|
||||||
} else {
|
} else {
|
||||||
Typification fixedType = std::get<Typification>(*funcType);
|
Typification fixedType = std::get<Typification>(*funcType);
|
||||||
MangleRadicals(funcName, fixedType);
|
MangleRadicals(funcName, fixedType);
|
||||||
if (!empty(substitutes.value())) {
|
if (!empty(substitutes.value())) {
|
||||||
fixedType.SubstituteBase(substitutes.value());
|
fixedType.SubstituteBase(substitutes.value());
|
||||||
}
|
}
|
||||||
return VisitAndReturn(fixedType);
|
return SetCurrent(fixedType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,7 +430,7 @@ bool TypeAuditor::ViGlobal(Cursor iter) {
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(Typification(globalName).ApplyBool());
|
return SetCurrent(Typification(globalName).ApplyBool());
|
||||||
} else {
|
} else {
|
||||||
if (env.context.FunctionArgsFor(globalName) != nullptr) {
|
if (env.context.FunctionArgsFor(globalName) != nullptr) {
|
||||||
OnError(
|
OnError(
|
||||||
|
@ -445,25 +449,25 @@ bool TypeAuditor::ViGlobal(Cursor iter) {
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(*type);
|
return SetCurrent(*type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViLocal(Cursor iter) {
|
bool TypeAuditor::ViLocal(Cursor iter) {
|
||||||
const auto& localName = iter->data.ToText();
|
const auto& localName = iter->data.ToText();
|
||||||
if (isLocalDeclaration || isArgDeclaration) {
|
if (isLocalDeclaration || isArgDeclaration) {
|
||||||
return AddLocalVar(localName, std::get<Typification>(currentType), iter->pos.start);
|
return AddLocalVariable(localName, std::get<Typification>(currentType), iter->pos.start);
|
||||||
} else {
|
} else {
|
||||||
const auto* local = GetLocalTypification(localName, iter->pos.start);
|
const auto* local = GetLocalTypification(localName, iter->pos.start);
|
||||||
if (local == nullptr) {
|
if (local == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(*local);
|
return SetCurrent(*local);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViEmptySet(Cursor /*iter*/) {
|
bool TypeAuditor::ViEmptySet(Cursor /*iter*/) {
|
||||||
return VisitAndReturn(Typification::EmptySet());
|
return SetCurrent(Typification::EmptySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViLocalBind(Cursor iter) {
|
bool TypeAuditor::ViLocalBind(Cursor iter) {
|
||||||
|
@ -479,7 +483,7 @@ bool TypeAuditor::ViLocalBind(Cursor iter) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return VisitAndReturn(type);
|
return SetCurrent(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViArgument(Cursor iter) {
|
bool TypeAuditor::ViArgument(Cursor iter) {
|
||||||
|
@ -489,12 +493,12 @@ bool TypeAuditor::ViArgument(Cursor iter) {
|
||||||
}
|
}
|
||||||
const auto guard{ isArgDeclaration.CreateGuard() };
|
const auto guard{ isArgDeclaration.CreateGuard() };
|
||||||
currentType = domain.value();
|
currentType = domain.value();
|
||||||
return VisitChild(iter, 0) && VisitAndReturn(LogicT{});
|
return VisitChild(iter, 0) && SetCurrent(LogicT{});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViCard(Cursor iter) {
|
bool TypeAuditor::ViCard(Cursor iter) {
|
||||||
return ChildTypeDebool(iter, 0, SemanticEID::invalidCard).has_value()
|
return ChildTypeDebool(iter, 0, SemanticEID::invalidCard).has_value()
|
||||||
&& VisitAndReturn(Typification::Integer());
|
&& SetCurrent(Typification::Integer());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViArithmetic(Cursor iter) {
|
bool TypeAuditor::ViArithmetic(Cursor iter) {
|
||||||
|
@ -538,7 +542,7 @@ bool TypeAuditor::ViArithmetic(Cursor iter) {
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(result.value());
|
return SetCurrent(result.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViOrdering(Cursor iter) {
|
bool TypeAuditor::ViOrdering(Cursor iter) {
|
||||||
|
@ -581,7 +585,7 @@ bool TypeAuditor::ViOrdering(Cursor iter) {
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(LogicT{});
|
return SetCurrent(LogicT{});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViQuantifier(Cursor iter) {
|
bool TypeAuditor::ViQuantifier(Cursor iter) {
|
||||||
|
@ -597,7 +601,7 @@ bool TypeAuditor::ViQuantifier(Cursor iter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
EndScope(iter->pos.start);
|
EndScope(iter->pos.start);
|
||||||
return VisitAndReturn(LogicT{});
|
return SetCurrent(LogicT{});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViEquals(Cursor iter) {
|
bool TypeAuditor::ViEquals(Cursor iter) {
|
||||||
|
@ -622,7 +626,7 @@ bool TypeAuditor::ViEquals(Cursor iter) {
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(LogicT{});
|
return SetCurrent(LogicT{});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViTypedPredicate(Cursor iter) {
|
bool TypeAuditor::ViTypedPredicate(Cursor iter) {
|
||||||
|
@ -656,7 +660,7 @@ bool TypeAuditor::ViTypedPredicate(Cursor iter) {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(LogicT{});
|
return SetCurrent(LogicT{});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViDeclarative(Cursor iter) {
|
bool TypeAuditor::ViDeclarative(Cursor iter) {
|
||||||
|
@ -672,7 +676,7 @@ bool TypeAuditor::ViDeclarative(Cursor iter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
EndScope(iter->pos.start);
|
EndScope(iter->pos.start);
|
||||||
return VisitAndReturn(domain->ApplyBool());
|
return SetCurrent(domain->ApplyBool());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViImperative(Cursor iter) {
|
bool TypeAuditor::ViImperative(Cursor iter) {
|
||||||
|
@ -690,7 +694,7 @@ bool TypeAuditor::ViImperative(Cursor iter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
EndScope(iter->pos.start);
|
EndScope(iter->pos.start);
|
||||||
return VisitAndReturn(std::get<Typification>(type.value()).Bool());
|
return SetCurrent(std::get<Typification>(type.value()).Bool());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViImpDeclare(Cursor iter) {
|
bool TypeAuditor::ViImpDeclare(Cursor iter) {
|
||||||
|
@ -711,22 +715,19 @@ bool TypeAuditor::ViRecursion(Cursor iter) {
|
||||||
auto initType = ChildType(iter, 1);
|
auto initType = ChildType(iter, 1);
|
||||||
if (!initType.has_value()) {
|
if (!initType.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
} else if (!VisitChildDeclaration(iter, 0, std::get<Typification>(initType.value()))) {
|
}
|
||||||
|
if (!VisitChildDeclaration(iter, 0, std::get<Typification>(initType.value()))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Index iterationIndex{ 2 };
|
const bool isFull = iter->id == TokenID::NT_RECURSIVE_FULL;
|
||||||
if (iter->id == TokenID::NT_RECURSIVE_FULL) {
|
Index iterationIndex{ isFull ? 3 : 2 };
|
||||||
iterationIndex = 3;
|
|
||||||
if (!VisitChild(iter, 2)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto iterationType = ChildType(iter, iterationIndex);
|
const auto iterationType = ChildType(iter, iterationIndex);
|
||||||
if (!iterationType.has_value()) {
|
if (!iterationType.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
} else if (!env.AreCompatible(iterationType.value(), initType.value())) {
|
}
|
||||||
|
if (!env.AreCompatible(iterationType.value(), initType.value())) {
|
||||||
OnError(
|
OnError(
|
||||||
SemanticEID::typesNotEqual,
|
SemanticEID::typesNotEqual,
|
||||||
iter(iterationIndex).pos.start,
|
iter(iterationIndex).pos.start,
|
||||||
|
@ -736,8 +737,25 @@ bool TypeAuditor::ViRecursion(Cursor iter) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const auto guard = noWarnings.CreateGuard();
|
||||||
|
ClearLocalVariables();
|
||||||
|
if (!VisitChildDeclaration(iter, 0, std::get<Typification>(iterationType.value()))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!VisitChild(iter, iterationIndex)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isFull) {
|
||||||
|
if (!VisitChild(iter, 2)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EndScope(iter->pos.start);
|
EndScope(iter->pos.start);
|
||||||
return VisitAndReturn(iterationType.value());
|
return SetCurrent(iterationType.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViDecart(Cursor iter) {
|
bool TypeAuditor::ViDecart(Cursor iter) {
|
||||||
|
@ -750,7 +768,7 @@ bool TypeAuditor::ViDecart(Cursor iter) {
|
||||||
factors.emplace_back(type.value());
|
factors.emplace_back(type.value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return VisitAndReturn(Typification::Tuple(factors).ApplyBool());
|
return SetCurrent(Typification::Tuple(factors).ApplyBool());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViBoolean(Cursor iter) {
|
bool TypeAuditor::ViBoolean(Cursor iter) {
|
||||||
|
@ -758,7 +776,7 @@ bool TypeAuditor::ViBoolean(Cursor iter) {
|
||||||
if (!type.has_value()) {
|
if (!type.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(type->ApplyBool().ApplyBool());
|
return SetCurrent(type->ApplyBool().ApplyBool());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViTuple(Cursor iter) {
|
bool TypeAuditor::ViTuple(Cursor iter) {
|
||||||
|
@ -770,7 +788,7 @@ bool TypeAuditor::ViTuple(Cursor iter) {
|
||||||
}
|
}
|
||||||
components.emplace_back(std::get<Typification>(type.value()));
|
components.emplace_back(std::get<Typification>(type.value()));
|
||||||
}
|
}
|
||||||
return VisitAndReturn(Typification::Tuple(components));
|
return SetCurrent(Typification::Tuple(components));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViSetEnum(Cursor iter) {
|
bool TypeAuditor::ViSetEnum(Cursor iter) {
|
||||||
|
@ -797,7 +815,7 @@ bool TypeAuditor::ViSetEnum(Cursor iter) {
|
||||||
}
|
}
|
||||||
type = std::move(merge.value());
|
type = std::move(merge.value());
|
||||||
}
|
}
|
||||||
return VisitAndReturn(type.Bool());
|
return SetCurrent(type.Bool());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViDebool(Cursor iter) {
|
bool TypeAuditor::ViDebool(Cursor iter) {
|
||||||
|
@ -805,7 +823,7 @@ bool TypeAuditor::ViDebool(Cursor iter) {
|
||||||
if (!type.has_value()) {
|
if (!type.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(type.value());
|
return SetCurrent(type.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViTypedBinary(Cursor iter) {
|
bool TypeAuditor::ViTypedBinary(Cursor iter) {
|
||||||
|
@ -829,20 +847,24 @@ bool TypeAuditor::ViTypedBinary(Cursor iter) {
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(result.value().Bool());
|
return SetCurrent(result.value().Bool());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViProjectSet(Cursor iter) {
|
bool TypeAuditor::ViProjectSet(Cursor iter) {
|
||||||
// T(Pri(a)) = B(Pi(D(T(a))))
|
// T(Pri(a)) = B(Pi(D(T(a))))
|
||||||
const auto baseType = ChildTypeDebool(iter, 0, SemanticEID::invalidProjectionSet);
|
const auto maybeArgument = ChildTypeDebool(iter, 0, SemanticEID::invalidProjectionSet);
|
||||||
if (!baseType.has_value()) {
|
if (!maybeArgument.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!baseType->IsTuple()) {
|
const auto& argument = maybeArgument.value();
|
||||||
|
if (argument.IsAnyType()) {
|
||||||
|
return SetCurrent(Typification::EmptySet());
|
||||||
|
}
|
||||||
|
if (!argument.IsTuple()) {
|
||||||
OnError(
|
OnError(
|
||||||
SemanticEID::invalidProjectionSet,
|
SemanticEID::invalidProjectionSet,
|
||||||
iter(0).pos.start,
|
iter(0).pos.start,
|
||||||
{ iter->ToString(), baseType->ToString() }
|
{ iter->ToString(), argument.ToString() }
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -851,30 +873,36 @@ bool TypeAuditor::ViProjectSet(Cursor iter) {
|
||||||
std::vector<Typification> components{};
|
std::vector<Typification> components{};
|
||||||
components.reserve(size(indicies));
|
components.reserve(size(indicies));
|
||||||
for (const auto index : indicies) {
|
for (const auto index : indicies) {
|
||||||
if (!baseType->T().TestIndex(index)) {
|
if (!argument.T().TestIndex(index)) {
|
||||||
OnError(
|
OnError(
|
||||||
SemanticEID::invalidProjectionSet,
|
SemanticEID::invalidProjectionSet,
|
||||||
iter(0).pos.start,
|
iter(0).pos.start,
|
||||||
{ iter->ToString(), baseType->ToString() }
|
{ iter->ToString(), argument.ToString() }
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
components.emplace_back(baseType->T().Component(index));
|
components.emplace_back(argument.T().Component(index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentType = Typification::Tuple(components).ApplyBool();
|
return SetCurrent(Typification::Tuple(components).ApplyBool());
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViProjectTuple(Cursor iter) {
|
bool TypeAuditor::ViProjectTuple(Cursor iter) {
|
||||||
// T(pri(a)) = Pi(T(a))
|
// T(pri(a)) = Pi(T(a))
|
||||||
const auto baseType = ChildType(iter, 0);
|
const auto maybeArgument = ChildType(iter, 0);
|
||||||
if (!baseType.has_value()) {
|
if (!maybeArgument.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto& base = std::get<Typification>(baseType.value());
|
const auto& argument = std::get<Typification>(maybeArgument.value());
|
||||||
if (!base.IsTuple()) {
|
if (argument.IsAnyType()) {
|
||||||
OnError(SemanticEID::invalidProjectionTuple, iter(0).pos.start, { iter->ToString(), base.ToString() });
|
return SetCurrent(argument);
|
||||||
|
}
|
||||||
|
if (!argument.IsTuple()) {
|
||||||
|
OnError(
|
||||||
|
SemanticEID::invalidProjectionTuple,
|
||||||
|
iter(0).pos.start,
|
||||||
|
{ iter->ToString(), argument.ToString() }
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -882,39 +910,52 @@ bool TypeAuditor::ViProjectTuple(Cursor iter) {
|
||||||
std::vector<Typification> components{};
|
std::vector<Typification> components{};
|
||||||
components.reserve(size(indicies));
|
components.reserve(size(indicies));
|
||||||
for (const auto index : indicies) {
|
for (const auto index : indicies) {
|
||||||
if (!base.T().TestIndex(index)) {
|
if (!argument.T().TestIndex(index)) {
|
||||||
OnError(SemanticEID::invalidProjectionTuple, iter(0).pos.start, { iter->ToString(), base.ToString() });
|
OnError(
|
||||||
|
SemanticEID::invalidProjectionTuple,
|
||||||
|
iter(0).pos.start,
|
||||||
|
{ iter->ToString(), argument.ToString() }
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
components.emplace_back(base.T().Component(index));
|
components.emplace_back(argument.T().Component(index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return VisitAndReturn(Typification::Tuple(components));
|
return SetCurrent(Typification::Tuple(components));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViFilter(Cursor iter) {
|
bool TypeAuditor::ViFilter(Cursor iter) {
|
||||||
const auto baseType = ChildType(iter, static_cast<Index>(iter.ChildrenCount() - 1));
|
|
||||||
if (!baseType.has_value()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const auto& base = std::get<Typification>(baseType.value());
|
|
||||||
if (!base.IsCollection() || !base.B().Base().IsTuple()) {
|
|
||||||
OnError(SemanticEID::invalidFilterArgumentType,
|
|
||||||
iter(static_cast<Index>(iter.ChildrenCount() - 1)).pos.start,
|
|
||||||
{ iter->ToString(), base.ToString() });
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& indicies = iter->data.ToTuple();
|
const auto& indicies = iter->data.ToTuple();
|
||||||
if (ssize(indicies) + 1 != iter.ChildrenCount()) {
|
if (ssize(indicies) + 1 != iter.ChildrenCount()) {
|
||||||
OnError(SemanticEID::invalidFilterArity, iter->pos.start);
|
OnError(SemanticEID::invalidFilterArity, iter->pos.start);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto maybeArgument = ChildType(iter, static_cast<Index>(iter.ChildrenCount() - 1));
|
||||||
|
if (!maybeArgument.has_value()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto& argument = std::get<Typification>(maybeArgument.value());
|
||||||
|
if (argument.IsAnyType() || (argument.IsCollection() && argument.B().Base().IsAnyType())) {
|
||||||
|
return SetCurrent(Typification::EmptySet());
|
||||||
|
}
|
||||||
|
if (!argument.IsCollection() || !argument.B().Base().IsTuple()) {
|
||||||
|
OnError(
|
||||||
|
SemanticEID::invalidFilterArgumentType,
|
||||||
|
iter(static_cast<Index>(iter.ChildrenCount() - 1)).pos.start,
|
||||||
|
{ iter->ToString(), argument.ToString() }
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Index child{ 0 };
|
Index child{ 0 };
|
||||||
for (const auto index : indicies) {
|
for (const auto index : indicies) {
|
||||||
if (!base.B().Base().T().TestIndex(index)) {
|
if (!argument.B().Base().T().TestIndex(index)) {
|
||||||
OnError(SemanticEID::invalidFilterArgumentType, iter(static_cast<Index>(iter.ChildrenCount() - 1)).pos.start,
|
OnError(
|
||||||
{ iter->ToString(), base.ToString() });
|
SemanticEID::invalidFilterArgumentType,
|
||||||
|
iter(static_cast<Index>(iter.ChildrenCount() - 1)).pos.start,
|
||||||
|
{ iter->ToString(), argument.ToString() }
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto param = ChildType(iter, child);
|
const auto param = ChildType(iter, child);
|
||||||
|
@ -923,50 +964,56 @@ bool TypeAuditor::ViFilter(Cursor iter) {
|
||||||
}
|
}
|
||||||
const auto& paramType = std::get<Typification>(param.value());
|
const auto& paramType = std::get<Typification>(param.value());
|
||||||
if (!paramType.IsCollection() ||
|
if (!paramType.IsCollection() ||
|
||||||
!env.AreCompatible(base.B().Base().T().Component(index), paramType.B().Base())) {
|
!env.AreCompatible(argument.B().Base().T().Component(index), paramType.B().Base())) {
|
||||||
OnError(SemanticEID::typesNotEqual, iter(child).pos.start,
|
OnError(
|
||||||
base.B().Base().T().Component(index).Bool(), paramType);
|
SemanticEID::typesNotEqual,
|
||||||
|
iter(child).pos.start,
|
||||||
|
argument.B().Base().T().Component(index).Bool(), paramType
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
++child;
|
++child;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(baseType.value());
|
return SetCurrent(maybeArgument.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViReduce(Cursor iter) {
|
bool TypeAuditor::ViReduce(Cursor iter) {
|
||||||
// T(red(a)) = B(DD(T(a)))
|
// T(red(a)) = B(DD(T(a)))
|
||||||
const auto baseType = ChildType(iter, 0);
|
const auto maybeArgument = ChildType(iter, 0);
|
||||||
if (!baseType.has_value()) {
|
if (!maybeArgument.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto& base = std::get<Typification>(baseType.value());
|
const auto& argument = std::get<Typification>(maybeArgument.value());
|
||||||
if (!base.IsCollection() || !base.B().Base().IsCollection()) {
|
if (argument.IsAnyType() || (argument.IsCollection() && argument.B().Base().IsAnyType())) {
|
||||||
|
return SetCurrent(Typification::EmptySet());
|
||||||
|
}
|
||||||
|
if (!argument.IsCollection() || !argument.B().Base().IsCollection()) {
|
||||||
OnError(
|
OnError(
|
||||||
SemanticEID::invalidReduce,
|
SemanticEID::invalidReduce,
|
||||||
iter(0).pos.start + 1,
|
iter(0).pos.start + 1,
|
||||||
base.ToString()
|
argument.ToString()
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(base.B().Base());
|
return SetCurrent(argument.B().Base());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::VisitAndReturn(ExpressionType type) noexcept {
|
bool TypeAuditor::SetCurrent(ExpressionType type) noexcept {
|
||||||
currentType = std::move(type);
|
currentType = std::move(type);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::VisitAllAndReturn(Cursor iter, const ExpressionType& type) {
|
bool TypeAuditor::VisitAllAndSetCurrent(Cursor iter, const ExpressionType& type) {
|
||||||
return VisitAllChildren(iter) && VisitAndReturn(type);
|
return VisitAllChildren(iter) && SetCurrent(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::VisitChildDeclaration(const Cursor& iter, const Index index, const Typification& domain) {
|
bool TypeAuditor::VisitChildDeclaration(const Cursor& iter, const Index index, const Typification& domain) {
|
||||||
currentType = domain;
|
currentType = domain;
|
||||||
if (const auto guard = isLocalDeclaration.CreateGuard();
|
const auto guard = isLocalDeclaration.CreateGuard();
|
||||||
!VisitChild(iter, index)) {
|
if (!VisitChild(iter, index)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return VisitAndReturn(LogicT{});
|
return SetCurrent(LogicT{});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ExpressionType> TypeAuditor::ChildType(Cursor iter, const Index index) {
|
std::optional<ExpressionType> TypeAuditor::ChildType(Cursor iter, const Index index) {
|
||||||
|
@ -984,19 +1031,23 @@ std::optional<ExpressionType> TypeAuditor::ChildType(Cursor iter, const Index in
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Typification> TypeAuditor::ChildTypeDebool(Cursor iter, const Index index, const SemanticEID eid) {
|
std::optional<Typification> TypeAuditor::ChildTypeDebool(Cursor iter, const Index index, const SemanticEID eid) {
|
||||||
const auto result = ChildType(iter, index);
|
const auto maybeResult = ChildType(iter, index);
|
||||||
if (!result.has_value() || !std::holds_alternative<Typification>(result.value())) {
|
if (!maybeResult.has_value() || !std::holds_alternative<Typification>(maybeResult.value())) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
if (!std::get<Typification>(result.value()).IsCollection()) {
|
const auto& result = std::get<Typification>(maybeResult.value());
|
||||||
|
if (result.IsAnyType()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (!result.IsCollection()) {
|
||||||
OnError(
|
OnError(
|
||||||
eid,
|
eid,
|
||||||
iter(index).pos.start,
|
iter(index).pos.start,
|
||||||
ToString(result.value())
|
ToString(maybeResult.value())
|
||||||
);
|
);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
return std::get<Typification>(result.value()).B().Base();
|
return result.B().Base();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Typification* TypeAuditor::GetLocalTypification(const std::string& name, const StrPos pos) {
|
const Typification* TypeAuditor::GetLocalTypification(const std::string& name, const StrPos pos) {
|
||||||
|
@ -1030,7 +1081,7 @@ void TypeAuditor::EndScope(const StrPos pos) {
|
||||||
--var.level;
|
--var.level;
|
||||||
if (var.level < 0 && var.enabled) {
|
if (var.level < 0 && var.enabled) {
|
||||||
var.enabled = false;
|
var.enabled = false;
|
||||||
if (var.useCount == 0) {
|
if (var.useCount == 0 && !noWarnings) {
|
||||||
OnError(
|
OnError(
|
||||||
SemanticEID::localNotUsed,
|
SemanticEID::localNotUsed,
|
||||||
pos,
|
pos,
|
||||||
|
@ -1041,9 +1092,12 @@ void TypeAuditor::EndScope(const StrPos pos) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::AddLocalVar(const std::string& name, const Typification& type, const StrPos pos) {
|
bool TypeAuditor::AddLocalVariable(const std::string& name, const Typification& type, const StrPos pos) {
|
||||||
auto varIter = std::find_if(begin(localVars), end(localVars),
|
auto varIter = std::find_if(
|
||||||
[&](const auto& data) noexcept { return data.arg.name == name; });
|
begin(localVars),
|
||||||
|
end(localVars),
|
||||||
|
[&](const auto& data) noexcept { return data.arg.name == name; }
|
||||||
|
);
|
||||||
if (varIter != end(localVars)) {
|
if (varIter != end(localVars)) {
|
||||||
if (varIter->enabled) {
|
if (varIter->enabled) {
|
||||||
OnError(
|
OnError(
|
||||||
|
@ -1053,15 +1107,16 @@ bool TypeAuditor::AddLocalVar(const std::string& name, const Typification& type,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
if (!noWarnings) {
|
||||||
OnError(
|
OnError(
|
||||||
SemanticEID::localDoubleDeclare,
|
SemanticEID::localDoubleDeclare,
|
||||||
pos,
|
pos,
|
||||||
name
|
name
|
||||||
);
|
);
|
||||||
|
}
|
||||||
varIter->arg.type = type;
|
varIter->arg.type = type;
|
||||||
varIter->enabled = true;
|
varIter->enabled = true;
|
||||||
varIter->level = 0;
|
varIter->level = 0;
|
||||||
varIter->useCount = 0;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1073,4 +1128,9 @@ bool TypeAuditor::AddLocalVar(const std::string& name, const Typification& type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TypeAuditor::ClearLocalVariables() {
|
||||||
|
std::erase_if(localVars, [&](const auto& data) noexcept { return data.level <= 0; });
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ccl::rslang
|
} // namespace ccl::rslang
|
|
@ -7,6 +7,10 @@
|
||||||
|
|
||||||
namespace ccl::rslang {
|
namespace ccl::rslang {
|
||||||
|
|
||||||
|
bool Typification::IsAnyType() const noexcept {
|
||||||
|
return IsElement() && E().baseID == anyTypificationName;
|
||||||
|
}
|
||||||
|
|
||||||
Typification& Typification::ApplyBool() {
|
Typification& Typification::ApplyBool() {
|
||||||
state = EchelonBool(*this);
|
state = EchelonBool(*this);
|
||||||
return *this;
|
return *this;
|
||||||
|
|
|
@ -37,13 +37,13 @@ void ValueAuditor::Clear() noexcept {
|
||||||
current = ValueClass::invalid;
|
current = ValueClass::invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ValueAuditor::VisitAndReturn(const ValueClass type) noexcept {
|
bool ValueAuditor::SetCurrent(const ValueClass type) noexcept {
|
||||||
current = type;
|
current = type;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ValueAuditor::VisitAllAndReturn(Cursor iter, const ValueClass type) {
|
bool ValueAuditor::VisitAllAndSetCurrent(Cursor iter, const ValueClass type) {
|
||||||
return VisitAllChildren(iter) && VisitAndReturn(type);
|
return VisitAllChildren(iter) && SetCurrent(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ValueAuditor::AssertChildIsValue(Cursor iter, const Index index) {
|
bool ValueAuditor::AssertChildIsValue(Cursor iter, const Index index) {
|
||||||
|
@ -68,9 +68,9 @@ bool ValueAuditor::AssertAllValues(Cursor iter) {
|
||||||
|
|
||||||
bool ValueAuditor::ViGlobalDefinition(Cursor iter) {
|
bool ValueAuditor::ViGlobalDefinition(Cursor iter) {
|
||||||
if (iter->id == TokenID::PUNC_STRUCT) {
|
if (iter->id == TokenID::PUNC_STRUCT) {
|
||||||
return VisitChild(iter, 1) && VisitAndReturn(ValueClass::value);
|
return VisitChild(iter, 1) && SetCurrent(ValueClass::value);
|
||||||
} else if (iter.ChildrenCount() == 1) {
|
} else if (iter.ChildrenCount() == 1) {
|
||||||
return VisitAndReturn(ValueClass::value);
|
return SetCurrent(ValueClass::value);
|
||||||
} else {
|
} else {
|
||||||
return VisitChild(iter, 1);
|
return VisitChild(iter, 1);
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ bool ValueAuditor::RunCheckOnFunc(
|
||||||
bool ValueAuditor::ViGlobal(Cursor iter) {
|
bool ValueAuditor::ViGlobal(Cursor iter) {
|
||||||
const auto& globalName = iter->data.ToText();
|
const auto& globalName = iter->data.ToText();
|
||||||
if (iter->id == TokenID::ID_RADICAL) {
|
if (iter->id == TokenID::ID_RADICAL) {
|
||||||
return VisitAndReturn(ValueClass::value);
|
return SetCurrent(ValueClass::value);
|
||||||
} else {
|
} else {
|
||||||
const auto type = globalClass(globalName);
|
const auto type = globalClass(globalName);
|
||||||
if (type == ValueClass::invalid) {
|
if (type == ValueClass::invalid) {
|
||||||
|
@ -148,9 +148,9 @@ bool ValueAuditor::ViGlobal(Cursor iter) {
|
||||||
bool ValueAuditor::ViLocal(Cursor iter) {
|
bool ValueAuditor::ViLocal(Cursor iter) {
|
||||||
const auto& localName = iter->data.ToText();
|
const auto& localName = iter->data.ToText();
|
||||||
if (std::find(begin(localProps), end(localProps), localName) == end(localProps)) {
|
if (std::find(begin(localProps), end(localProps), localName) == end(localProps)) {
|
||||||
return VisitAndReturn(ValueClass::value);
|
return SetCurrent(ValueClass::value);
|
||||||
} else {
|
} else {
|
||||||
return VisitAndReturn(ValueClass::props);
|
return SetCurrent(ValueClass::props);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,11 +195,11 @@ bool ValueAuditor::ViDecart(Cursor iter) {
|
||||||
type = current;
|
type = current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return VisitAndReturn(type);
|
return SetCurrent(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ValueAuditor::ViBoolean(Cursor iter) {
|
bool ValueAuditor::ViBoolean(Cursor iter) {
|
||||||
return VisitChild(iter, 0) && VisitAndReturn(ValueClass::props);
|
return VisitChild(iter, 0) && SetCurrent(ValueClass::props);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ValueAuditor::ViTypedBinary(Cursor iter) {
|
bool ValueAuditor::ViTypedBinary(Cursor iter) {
|
||||||
|
@ -214,9 +214,9 @@ bool ValueAuditor::ViTypedBinary(Cursor iter) {
|
||||||
const auto secondValue = current == ValueClass::value;
|
const auto secondValue = current == ValueClass::value;
|
||||||
|
|
||||||
if (CombineOperationValues(iter->id, firstValue, secondValue)) {
|
if (CombineOperationValues(iter->id, firstValue, secondValue)) {
|
||||||
return VisitAndReturn(ValueClass::value);
|
return SetCurrent(ValueClass::value);
|
||||||
} else {
|
} else {
|
||||||
return VisitAndReturn(ValueClass::props);
|
return SetCurrent(ValueClass::props);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -227,6 +227,9 @@ TEST_F(UTTypeAuditor, ConstructorsCorrect) {
|
||||||
SetupConstants();
|
SetupConstants();
|
||||||
|
|
||||||
ExpectTypification(R"({X1, X1})", "BB(X1)"_t);
|
ExpectTypification(R"({X1, X1})", "BB(X1)"_t);
|
||||||
|
ExpectTypification(R"({{}, X1})", "BB(X1)"_t);
|
||||||
|
ExpectTypification(R"({X1, {}})", "BB(X1)"_t);
|
||||||
|
ExpectTypification(R"({{}})", "BB(R0)"_t);
|
||||||
ExpectTypification(R"({1})", "B(Z)"_t);
|
ExpectTypification(R"({1})", "B(Z)"_t);
|
||||||
ExpectTypification(R"({1, card(X1)})", "B(Z)"_t);
|
ExpectTypification(R"({1, card(X1)})", "B(Z)"_t);
|
||||||
ExpectTypification(R"({S4, 1})", "B(C1)"_t);
|
ExpectTypification(R"({S4, 1})", "B(C1)"_t);
|
||||||
|
@ -245,6 +248,9 @@ TEST_F(UTTypeAuditor, ConstructorsCorrect) {
|
||||||
ExpectTypification(R"(R{a \assign 1 | a \ls 10 | a \plus 1})", "Z"_t);
|
ExpectTypification(R"(R{a \assign 1 | a \ls 10 | a \plus 1})", "Z"_t);
|
||||||
ExpectTypification(R"(R{a \assign 1 | a \ls S4 | a \plus S4})", "C1"_t);
|
ExpectTypification(R"(R{a \assign 1 | a \ls S4 | a \plus S4})", "C1"_t);
|
||||||
ExpectTypification(R"(R{a \assign {} | a \union {S4}})", "B(C1)"_t);
|
ExpectTypification(R"(R{a \assign {} | a \union {S4}})", "B(C1)"_t);
|
||||||
|
ExpectTypification(R"(R{a \assign {} | Pr1(a) \eq Pr2(a) | a \union (X1*X1)})", "B(X1*X1)"_t);
|
||||||
|
ExpectTypification(R"(R{a \assign {} | a \union D{x \in X1 | x \eq x}})", "B(X1)"_t);
|
||||||
|
ExpectTypification(R"(R{a \assign {} | red(a) \eq {} | a \union {X1}})", "BB(X1)"_t);
|
||||||
|
|
||||||
ExpectTypification(R"(I{(a, b) | a \from X1; b \assign a})", "B(X1*X1)"_t);
|
ExpectTypification(R"(I{(a, b) | a \from X1; b \assign a})", "B(X1*X1)"_t);
|
||||||
ExpectTypification(R"(I{(a, b) | a \from X1; b \assign a; 1 \eq 1})", "B(X1*X1)"_t);
|
ExpectTypification(R"(I{(a, b) | a \from X1; b \assign a; 1 \eq 1})", "B(X1*X1)"_t);
|
||||||
|
@ -264,6 +270,8 @@ TEST_F(UTTypeAuditor, ConstructorsErrors) {
|
||||||
|
|
||||||
ExpectError(R"(R{a \assign S1 | {a}})", SemanticEID::typesNotEqual, 17);
|
ExpectError(R"(R{a \assign S1 | {a}})", SemanticEID::typesNotEqual, 17);
|
||||||
ExpectError(R"(R{a \assign {} | a \union S4})", SemanticEID::invalidTypeOperation, 26);
|
ExpectError(R"(R{a \assign {} | a \union S4})", SemanticEID::invalidTypeOperation, 26);
|
||||||
|
ExpectError(R"(R{a \assign {} | Pr1(a) \eq Pr2(a) | a \union X1})", SemanticEID::invalidProjectionSet, 21);
|
||||||
|
ExpectError(R"(R{a \assign {} | red(a) \eq {} | a \union (X1*X1)})", SemanticEID::invalidReduce, 22);
|
||||||
ExpectError(R"(\A a \in S1 R{(a1, a2) \assign a | a1} \eq a)", SemanticEID::typesNotEqual, 35);
|
ExpectError(R"(\A a \in S1 R{(a1, a2) \assign a | a1} \eq a)", SemanticEID::typesNotEqual, 35);
|
||||||
|
|
||||||
ExpectError(R"(I{(a, b) | a \from X1; b \assign {a}; a \noteq b})", SemanticEID::typesNotCompatible, 47);
|
ExpectError(R"(I{(a, b) | a \from X1; b \assign {a}; a \noteq b})", SemanticEID::typesNotCompatible, 47);
|
||||||
|
@ -327,10 +335,12 @@ TEST_F(UTTypeAuditor, TypedOperationsCorrect) {
|
||||||
ExpectTypification(R"(B(X1))", "BB(X1)"_t);
|
ExpectTypification(R"(B(X1))", "BB(X1)"_t);
|
||||||
ExpectTypification(R"(X1*X1)", "B(X1*X1)"_t);
|
ExpectTypification(R"(X1*X1)", "B(X1*X1)"_t);
|
||||||
ExpectTypification(R"(Pr1(S1))", "B(X1)"_t);
|
ExpectTypification(R"(Pr1(S1))", "B(X1)"_t);
|
||||||
|
ExpectTypification(R"(Pr1({}))", "B(R0)"_t);
|
||||||
ExpectTypification(R"(Fi1[X1](S1))", "B(X1*X1)"_t);
|
ExpectTypification(R"(Fi1[X1](S1))", "B(X1*X1)"_t);
|
||||||
ExpectTypification(R"(Fi1[{1,2,3}](Z*X1))", "B(Z*X1)"_t);
|
ExpectTypification(R"(Fi1[{1,2,3}](Z*X1))", "B(Z*X1)"_t);
|
||||||
ExpectTypification(R"(Fi1[{1,2,3}](C1*X1))", "B(C1*X1)"_t);
|
ExpectTypification(R"(Fi1[{1,2,3}](C1*X1))", "B(C1*X1)"_t);
|
||||||
ExpectTypification(R"(Pr1,2(S1))", "B(X1*X1)"_t);
|
ExpectTypification(R"(Pr1,2(S1))", "B(X1*X1)"_t);
|
||||||
|
ExpectTypification(R"(Pr1,2({}))", "B(R0)"_t);
|
||||||
ExpectTypification(R"(bool(X1))", "BB(X1)"_t);
|
ExpectTypification(R"(bool(X1))", "BB(X1)"_t);
|
||||||
ExpectTypification(R"(debool({X1}))", "B(X1)"_t);
|
ExpectTypification(R"(debool({X1}))", "B(X1)"_t);
|
||||||
ExpectTypification(R"(red(S2))", "B(X1)"_t);
|
ExpectTypification(R"(red(S2))", "B(X1)"_t);
|
||||||
|
@ -365,6 +375,8 @@ TEST_F(UTTypeAuditor, TypedOperationsErrors) {
|
||||||
|
|
||||||
TEST_F(UTTypeAuditor, TypedFunctions) {
|
TEST_F(UTTypeAuditor, TypedFunctions) {
|
||||||
ExpectTypification(R"(F1[X1, X1])", "B(X1)"_t);
|
ExpectTypification(R"(F1[X1, X1])", "B(X1)"_t);
|
||||||
|
ExpectTypification(R"(F1[{}, X1])", "B(X1)"_t);
|
||||||
|
ExpectTypification(R"(F1[X1, {}])", "B(X1)"_t);
|
||||||
ExpectTypification(R"(F1[X1 \union X1, X1])", "B(X1)"_t);
|
ExpectTypification(R"(F1[X1 \union X1, X1])", "B(X1)"_t);
|
||||||
ExpectTypification(R"(F1[Pr1(S1), Pr2(S1)])", "B(X1)"_t);
|
ExpectTypification(R"(F1[Pr1(S1), Pr2(S1)])", "B(X1)"_t);
|
||||||
|
|
||||||
|
@ -410,6 +422,9 @@ TEST_F(UTTypeAuditor, TemplatedFunctions) {
|
||||||
env.data["F2"].arguments = f2Args;
|
env.data["F2"].arguments = f2Args;
|
||||||
|
|
||||||
ExpectTypification(R"(F2[B(X1), X1])", "BB(X1)"_t);
|
ExpectTypification(R"(F2[B(X1), X1])", "BB(X1)"_t);
|
||||||
|
ExpectTypification(R"(F2[{}, X1])", "BB(X1)"_t);
|
||||||
|
ExpectTypification(R"(F2[B(X1), {}])", "BB(X1)"_t);
|
||||||
|
ExpectTypification(R"(F2[{}, {}])", "BB(R0)"_t);
|
||||||
ExpectTypification(R"(F2[Z, 1])", "B(Z)"_t);
|
ExpectTypification(R"(F2[Z, 1])", "B(Z)"_t);
|
||||||
ExpectTypification(R"(F2[Z, S4])", "B(C1)"_t);
|
ExpectTypification(R"(F2[Z, S4])", "B(C1)"_t);
|
||||||
ExpectTypification(R"(F2[{S4}, 1])", "B(C1)"_t);
|
ExpectTypification(R"(F2[{S4}, 1])", "B(C1)"_t);
|
||||||
|
|
|
@ -30,6 +30,24 @@ TEST_F(UTTypification, Basic) {
|
||||||
EXPECT_TRUE(newBasic.IsElement());
|
EXPECT_TRUE(newBasic.IsElement());
|
||||||
EXPECT_FALSE(newBasic.IsCollection());
|
EXPECT_FALSE(newBasic.IsCollection());
|
||||||
EXPECT_FALSE(newBasic.IsTuple());
|
EXPECT_FALSE(newBasic.IsTuple());
|
||||||
|
EXPECT_FALSE(newBasic.IsAnyType());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(UTTypification, EmptySet) {
|
||||||
|
auto empty = Typification::EmptySet();
|
||||||
|
EXPECT_EQ(empty, Typification::EmptySet());
|
||||||
|
EXPECT_FALSE(empty.IsElement());
|
||||||
|
EXPECT_FALSE(empty.IsTuple());
|
||||||
|
EXPECT_TRUE(empty.IsCollection());
|
||||||
|
EXPECT_FALSE(empty.IsAnyType());
|
||||||
|
EXPECT_EQ(empty.Structure(), StructureType::collection);
|
||||||
|
|
||||||
|
const auto& base = empty.B().Base();
|
||||||
|
EXPECT_TRUE(base.IsElement());
|
||||||
|
EXPECT_FALSE(base.IsCollection());
|
||||||
|
EXPECT_FALSE(base.IsCollection());
|
||||||
|
EXPECT_TRUE(base.IsAnyType());
|
||||||
|
EXPECT_EQ(base.Structure(), StructureType::basic);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(UTTypification, Tuple) {
|
TEST_F(UTTypification, Tuple) {
|
||||||
|
@ -37,6 +55,7 @@ TEST_F(UTTypification, Tuple) {
|
||||||
EXPECT_FALSE(tuple.IsElement());
|
EXPECT_FALSE(tuple.IsElement());
|
||||||
EXPECT_FALSE(tuple.IsCollection());
|
EXPECT_FALSE(tuple.IsCollection());
|
||||||
EXPECT_TRUE(tuple.IsTuple());
|
EXPECT_TRUE(tuple.IsTuple());
|
||||||
|
EXPECT_FALSE(tuple.IsAnyType());
|
||||||
EXPECT_EQ(tuple.T().Arity(), 2);
|
EXPECT_EQ(tuple.T().Arity(), 2);
|
||||||
|
|
||||||
tuple = Typification::Tuple({ basic });
|
tuple = Typification::Tuple({ basic });
|
||||||
|
@ -74,6 +93,7 @@ TEST_F(UTTypification, Bool) {
|
||||||
EXPECT_FALSE(sBool.IsElement());
|
EXPECT_FALSE(sBool.IsElement());
|
||||||
EXPECT_TRUE(sBool.IsCollection());
|
EXPECT_TRUE(sBool.IsCollection());
|
||||||
EXPECT_FALSE(sBool.IsTuple());
|
EXPECT_FALSE(sBool.IsTuple());
|
||||||
|
EXPECT_FALSE(sBool.IsAnyType());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(UTTypification, ElementTypification) {
|
TEST_F(UTTypification, ElementTypification) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user