mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
tmp
This commit is contained in:
parent
f9d6e805ba
commit
955ada39e5
@ -78,6 +78,8 @@ set(sources
|
|||||||
ast/Types.h
|
ast/Types.h
|
||||||
ast/TypeProvider.cpp
|
ast/TypeProvider.cpp
|
||||||
ast/TypeProvider.h
|
ast/TypeProvider.h
|
||||||
|
ast/experimental/Type.cpp
|
||||||
|
ast/experimental/Type.h
|
||||||
ast/experimental/TypeSystem.cpp
|
ast/experimental/TypeSystem.cpp
|
||||||
ast/experimental/TypeSystem.h
|
ast/experimental/TypeSystem.h
|
||||||
codegen/ABIFunctions.cpp
|
codegen/ABIFunctions.cpp
|
||||||
|
@ -696,12 +696,12 @@ bool TypeInference::visit(TypeDefinition const& _typeDefinition)
|
|||||||
|
|
||||||
TypeSystemHelpers helper{m_typeSystem};
|
TypeSystemHelpers helper{m_typeSystem};
|
||||||
if (arguments.empty())
|
if (arguments.empty())
|
||||||
typeDefinitionAnnotation.type = helper.kindType(m_typeSystem.type(TypeConstant::Constructor{&_typeDefinition}, arguments));
|
typeDefinitionAnnotation.type = helper.kindType(m_typeSystem.type(TypeConstructor{&_typeDefinition}, arguments));
|
||||||
else
|
else
|
||||||
typeDefinitionAnnotation.type =
|
typeDefinitionAnnotation.type =
|
||||||
helper.functionType(
|
helper.functionType(
|
||||||
helper.kindType(helper.tupleType(arguments)),
|
helper.kindType(helper.tupleType(arguments)),
|
||||||
helper.kindType(m_typeSystem.type(TypeConstant::Constructor{&_typeDefinition}, arguments))
|
helper.kindType(m_typeSystem.type(TypeConstructor{&_typeDefinition}, arguments))
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ bool TypeRegistration::visit(TypeClassInstantiation const& _typeClassInstantiati
|
|||||||
|
|
||||||
TypeName const& typeName = _typeClassInstantiation.typeConstructor();
|
TypeName const& typeName = _typeClassInstantiation.typeConstructor();
|
||||||
|
|
||||||
TypeConstant::Constructor typeConstructor = [&]() -> TypeConstant::Constructor {
|
TypeConstructor typeConstructor = [&]() -> TypeConstructor {
|
||||||
if (auto const* elementaryTypeName = dynamic_cast<ElementaryTypeName const*>(&typeName))
|
if (auto const* elementaryTypeName = dynamic_cast<ElementaryTypeName const*>(&typeName))
|
||||||
{
|
{
|
||||||
switch(elementaryTypeName->typeName().token())
|
switch(elementaryTypeName->typeName().token())
|
||||||
@ -149,7 +149,7 @@ bool TypeRegistration::visit(TypeClassInstantiation const& _typeClassInstantiati
|
|||||||
bool TypeRegistration::visit(TypeDefinition const& _typeDefinition)
|
bool TypeRegistration::visit(TypeDefinition const& _typeDefinition)
|
||||||
{
|
{
|
||||||
m_typeSystem.declareTypeConstructor(
|
m_typeSystem.declareTypeConstructor(
|
||||||
TypeConstant::Constructor{&_typeDefinition},
|
TypeConstructor{&_typeDefinition},
|
||||||
_typeDefinition.name(),
|
_typeDefinition.name(),
|
||||||
_typeDefinition.arguments() ? _typeDefinition.arguments()->parameters().size() : 0
|
_typeDefinition.arguments() ? _typeDefinition.arguments()->parameters().size() : 0
|
||||||
);
|
);
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
struct Annotation
|
struct Annotation
|
||||||
{
|
{
|
||||||
Type type;
|
Type type;
|
||||||
std::map<TypeConstant::Constructor, TypeClassInstantiation const*> instantiations;
|
std::map<TypeConstructor, TypeClassInstantiation const*> instantiations;
|
||||||
};
|
};
|
||||||
TypeRegistration(Analysis& _analysis);
|
TypeRegistration(Analysis& _analysis);
|
||||||
|
|
||||||
|
182
libsolidity/ast/experimental/Type.cpp
Normal file
182
libsolidity/ast/experimental/Type.cpp
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
This file is part of solidity.
|
||||||
|
|
||||||
|
solidity is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
solidity is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
|
||||||
|
#include <libsolidity/ast/experimental/Type.h>
|
||||||
|
#include <libsolidity/ast/AST.h>
|
||||||
|
#include <libsolutil/Visitor.h>
|
||||||
|
|
||||||
|
#include <range/v3/view/drop_last.hpp>
|
||||||
|
#include <range/v3/view/zip.hpp>
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace solidity;
|
||||||
|
using namespace solidity::frontend::experimental;
|
||||||
|
|
||||||
|
std::string frontend::experimental::canonicalTypeName(Type _type)
|
||||||
|
{
|
||||||
|
return std::visit(util::GenericVisitor{
|
||||||
|
[&](TypeConstant const& _type) {
|
||||||
|
std::stringstream stream;
|
||||||
|
auto printTypeArguments = [&]() {
|
||||||
|
if (!_type.arguments.empty())
|
||||||
|
{
|
||||||
|
stream << "$";
|
||||||
|
for (auto type: _type.arguments | ranges::views::drop_last(1))
|
||||||
|
stream << canonicalTypeName(type) << "$";
|
||||||
|
stream << canonicalTypeName(_type.arguments.back());
|
||||||
|
stream << "$";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
std::visit(util::GenericVisitor{
|
||||||
|
[&](Declaration const* _declaration) {
|
||||||
|
printTypeArguments();
|
||||||
|
if (auto const* typeDeclarationAnnotation = dynamic_cast<TypeDeclarationAnnotation const*>(&_declaration->annotation()))
|
||||||
|
stream << *typeDeclarationAnnotation->canonicalName;
|
||||||
|
else
|
||||||
|
// TODO: canonical name
|
||||||
|
stream << _declaration->name();
|
||||||
|
},
|
||||||
|
[&](BuiltinType _builtinType) {
|
||||||
|
printTypeArguments();
|
||||||
|
switch(_builtinType)
|
||||||
|
{
|
||||||
|
case BuiltinType::Type:
|
||||||
|
stream << "type";
|
||||||
|
break;
|
||||||
|
case BuiltinType::Sort:
|
||||||
|
stream << "sort";
|
||||||
|
break;
|
||||||
|
case BuiltinType::Void:
|
||||||
|
stream << "void";
|
||||||
|
break;
|
||||||
|
case BuiltinType::Function:
|
||||||
|
stream << "fun";
|
||||||
|
break;
|
||||||
|
case BuiltinType::Unit:
|
||||||
|
stream << "unit";
|
||||||
|
break;
|
||||||
|
case BuiltinType::Pair:
|
||||||
|
stream << "pair";
|
||||||
|
break;
|
||||||
|
case BuiltinType::Word:
|
||||||
|
stream << "word";
|
||||||
|
break;
|
||||||
|
case BuiltinType::Integer:
|
||||||
|
stream << "integer";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, _type.constructor);
|
||||||
|
return stream.str();
|
||||||
|
},
|
||||||
|
[](TypeVariable const&)-> string {
|
||||||
|
solAssert(false);
|
||||||
|
},
|
||||||
|
}, _type);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TypeClass::operator<(TypeClass const& _rhs) const
|
||||||
|
{
|
||||||
|
return std::visit(util::GenericVisitor{
|
||||||
|
[](BuiltinClass _left, BuiltinClass _right) { return _left < _right; },
|
||||||
|
[](TypeClassDefinition const* _left, TypeClassDefinition const* _right) { return _left->id() < _right->id(); },
|
||||||
|
[](BuiltinClass, TypeClassDefinition const*) { return true; },
|
||||||
|
[](TypeClassDefinition const*, BuiltinClass) { return false; },
|
||||||
|
}, declaration, _rhs.declaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TypeClass::operator==(TypeClass const& _rhs) const
|
||||||
|
{
|
||||||
|
return std::visit(util::GenericVisitor{
|
||||||
|
[](BuiltinClass _left, BuiltinClass _right) { return _left == _right; },
|
||||||
|
[](TypeClassDefinition const* _left, TypeClassDefinition const* _right) { return _left->id() == _right->id(); },
|
||||||
|
[](BuiltinClass, TypeClassDefinition const*) { return false; },
|
||||||
|
[](TypeClassDefinition const*, BuiltinClass) { return false; },
|
||||||
|
}, declaration, _rhs.declaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
string TypeClass::toString() const
|
||||||
|
{
|
||||||
|
return std::visit(util::GenericVisitor{
|
||||||
|
[](BuiltinClass _class) -> string {
|
||||||
|
switch(_class)
|
||||||
|
{
|
||||||
|
case BuiltinClass::Type:
|
||||||
|
return "type";
|
||||||
|
case BuiltinClass::Kind:
|
||||||
|
return "kind";
|
||||||
|
case BuiltinClass::Constraint:
|
||||||
|
return "contraint";
|
||||||
|
}
|
||||||
|
solAssert(false);
|
||||||
|
},
|
||||||
|
[](TypeClassDefinition const* _declaration) { return _declaration->name(); },
|
||||||
|
}, declaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sort::operator==(Sort const& _rhs) const
|
||||||
|
{
|
||||||
|
if (classes.size() != _rhs.classes.size())
|
||||||
|
return false;
|
||||||
|
for (auto [lhs, rhs]: ranges::zip_view(classes, _rhs.classes))
|
||||||
|
if (lhs != rhs)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Sort::operator<=(Sort const& _rhs) const
|
||||||
|
{
|
||||||
|
for (auto c: classes)
|
||||||
|
if (!_rhs.classes.count(c))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sort Sort::operator+(Sort const& _rhs) const
|
||||||
|
{
|
||||||
|
Sort result { classes };
|
||||||
|
result.classes += _rhs.classes;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Sort Sort::operator-(Sort const& _rhs) const
|
||||||
|
{
|
||||||
|
Sort result { classes };
|
||||||
|
result.classes -= _rhs.classes;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TypeConstant::operator<(TypeConstant const& _rhs) const
|
||||||
|
{
|
||||||
|
if (constructor < _rhs.constructor)
|
||||||
|
return true;
|
||||||
|
if (_rhs.constructor < constructor)
|
||||||
|
return false;
|
||||||
|
solAssert(arguments.size() == _rhs.arguments.size());
|
||||||
|
for(auto [lhs, rhs]: ranges::zip_view(arguments, _rhs.arguments))
|
||||||
|
{
|
||||||
|
if (lhs < rhs)
|
||||||
|
return true;
|
||||||
|
if (rhs < lhs)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
133
libsolidity/ast/experimental/Type.h
Normal file
133
libsolidity/ast/experimental/Type.h
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
This file is part of solidity.
|
||||||
|
|
||||||
|
solidity is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
solidity is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace solidity::frontend
|
||||||
|
{
|
||||||
|
class Declaration;
|
||||||
|
class TypeClassDefinition;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace solidity::frontend::experimental
|
||||||
|
{
|
||||||
|
|
||||||
|
class TypeSystem;
|
||||||
|
|
||||||
|
struct TypeConstant;
|
||||||
|
struct TypeVariable;
|
||||||
|
|
||||||
|
using Type = std::variant<TypeConstant, TypeVariable>;
|
||||||
|
|
||||||
|
std::string canonicalTypeName(Type _type);
|
||||||
|
|
||||||
|
enum class BuiltinType
|
||||||
|
{
|
||||||
|
Type,
|
||||||
|
Sort,
|
||||||
|
Void,
|
||||||
|
Function,
|
||||||
|
Unit,
|
||||||
|
Pair,
|
||||||
|
Word,
|
||||||
|
Integer
|
||||||
|
};
|
||||||
|
|
||||||
|
using TypeConstructor = std::variant<BuiltinType, Declaration const*>;
|
||||||
|
|
||||||
|
struct TypeConstant
|
||||||
|
{
|
||||||
|
TypeConstructor constructor;
|
||||||
|
std::vector<Type> arguments;
|
||||||
|
bool operator<(TypeConstant const& _rhs) const;
|
||||||
|
bool operator==(TypeConstant const& _rhs) const
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
return !(*this < _rhs) && !(_rhs < *this);
|
||||||
|
}
|
||||||
|
bool operator!=(TypeConstant const& _rhs) const
|
||||||
|
{
|
||||||
|
return !operator==(_rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class BuiltinClass
|
||||||
|
{
|
||||||
|
Type,
|
||||||
|
Kind,
|
||||||
|
Constraint
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TypeClass
|
||||||
|
{
|
||||||
|
std::variant<BuiltinClass, TypeClassDefinition const*> declaration;
|
||||||
|
std::string toString() const;
|
||||||
|
bool operator<(TypeClass const& _rhs) const;
|
||||||
|
bool operator==(TypeClass const& _rhs) const;
|
||||||
|
bool operator!=(TypeClass const& _rhs) const { return !operator==(_rhs); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Sort
|
||||||
|
{
|
||||||
|
std::set<TypeClass> classes;
|
||||||
|
bool operator==(Sort const& _rhs) const;
|
||||||
|
bool operator!=(Sort const& _rhs) const { return !operator==(_rhs); }
|
||||||
|
bool operator<=(Sort const& _rhs) const;
|
||||||
|
Sort operator+(Sort const& _rhs) const;
|
||||||
|
Sort operator-(Sort const& _rhs) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Arity
|
||||||
|
{
|
||||||
|
std::vector<Sort> argumentSorts;
|
||||||
|
TypeClass typeClass;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TypeVariable
|
||||||
|
{
|
||||||
|
size_t index() const { return m_index; }
|
||||||
|
bool generic() const { return m_generic; }
|
||||||
|
Sort const& sort() const { return m_sort; }
|
||||||
|
bool operator<(TypeVariable const& _rhs) const
|
||||||
|
{
|
||||||
|
// TODO: more robust comparison?
|
||||||
|
return m_index < _rhs.m_index;
|
||||||
|
}
|
||||||
|
bool operator==(TypeVariable const& _rhs) const
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
return !(*this < _rhs) && !(_rhs < *this);
|
||||||
|
}
|
||||||
|
bool operator!=(TypeVariable const& _rhs) const
|
||||||
|
{
|
||||||
|
return !operator==(_rhs);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
friend class TypeSystem;
|
||||||
|
size_t m_index = 0;
|
||||||
|
Sort m_sort;
|
||||||
|
bool m_generic = false;
|
||||||
|
TypeVariable(size_t _index, Sort _sort, bool _generic):
|
||||||
|
m_index(_index), m_sort(std::move(_sort)), m_generic(_generic) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -35,158 +35,6 @@ using namespace std;
|
|||||||
using namespace solidity::frontend;
|
using namespace solidity::frontend;
|
||||||
using namespace solidity::frontend::experimental;
|
using namespace solidity::frontend::experimental;
|
||||||
|
|
||||||
bool TypeClass::operator<(TypeClass const& _rhs) const
|
|
||||||
{
|
|
||||||
return std::visit(util::GenericVisitor{
|
|
||||||
[](BuiltinClass _left, BuiltinClass _right) { return _left < _right; },
|
|
||||||
[](TypeClassDefinition const* _left, TypeClassDefinition const* _right) { return _left->id() < _right->id(); },
|
|
||||||
[](BuiltinClass, TypeClassDefinition const*) { return true; },
|
|
||||||
[](TypeClassDefinition const*, BuiltinClass) { return false; },
|
|
||||||
}, declaration, _rhs.declaration);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TypeClass::operator==(TypeClass const& _rhs) const
|
|
||||||
{
|
|
||||||
return std::visit(util::GenericVisitor{
|
|
||||||
[](BuiltinClass _left, BuiltinClass _right) { return _left == _right; },
|
|
||||||
[](TypeClassDefinition const* _left, TypeClassDefinition const* _right) { return _left->id() == _right->id(); },
|
|
||||||
[](BuiltinClass, TypeClassDefinition const*) { return false; },
|
|
||||||
[](TypeClassDefinition const*, BuiltinClass) { return false; },
|
|
||||||
}, declaration, _rhs.declaration);
|
|
||||||
}
|
|
||||||
|
|
||||||
string TypeClass::toString() const
|
|
||||||
{
|
|
||||||
return std::visit(util::GenericVisitor{
|
|
||||||
[](BuiltinClass _class) -> string {
|
|
||||||
switch(_class)
|
|
||||||
{
|
|
||||||
case BuiltinClass::Type:
|
|
||||||
return "type";
|
|
||||||
case BuiltinClass::Kind:
|
|
||||||
return "kind";
|
|
||||||
case BuiltinClass::Constraint:
|
|
||||||
return "contraint";
|
|
||||||
}
|
|
||||||
solAssert(false);
|
|
||||||
},
|
|
||||||
[](TypeClassDefinition const* _declaration) { return _declaration->name(); },
|
|
||||||
}, declaration);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Sort::operator==(Sort const& _rhs) const
|
|
||||||
{
|
|
||||||
if (classes.size() != _rhs.classes.size())
|
|
||||||
return false;
|
|
||||||
for (auto [lhs, rhs]: ranges::zip_view(classes, _rhs.classes))
|
|
||||||
if (lhs != rhs)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Sort::operator<=(Sort const& _rhs) const
|
|
||||||
{
|
|
||||||
for (auto c: classes)
|
|
||||||
if (!_rhs.classes.count(c))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sort Sort::operator+(Sort const& _rhs) const
|
|
||||||
{
|
|
||||||
Sort result { classes };
|
|
||||||
result.classes += _rhs.classes;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Sort Sort::operator-(Sort const& _rhs) const
|
|
||||||
{
|
|
||||||
Sort result { classes };
|
|
||||||
result.classes -= _rhs.classes;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TypeConstant::operator<(TypeConstant const& _rhs) const
|
|
||||||
{
|
|
||||||
if (constructor < _rhs.constructor)
|
|
||||||
return true;
|
|
||||||
if (_rhs.constructor < constructor)
|
|
||||||
return false;
|
|
||||||
solAssert(arguments.size() == _rhs.arguments.size());
|
|
||||||
for(auto [lhs, rhs]: ranges::zip_view(arguments, _rhs.arguments))
|
|
||||||
{
|
|
||||||
if (lhs < rhs)
|
|
||||||
return true;
|
|
||||||
if (rhs < lhs)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string experimental::canonicalTypeName(Type _type)
|
|
||||||
{
|
|
||||||
return std::visit(util::GenericVisitor{
|
|
||||||
[&](TypeConstant const& _type) {
|
|
||||||
std::stringstream stream;
|
|
||||||
auto printTypeArguments = [&]() {
|
|
||||||
if (!_type.arguments.empty())
|
|
||||||
{
|
|
||||||
stream << "$";
|
|
||||||
for (auto type: _type.arguments | ranges::views::drop_last(1))
|
|
||||||
stream << canonicalTypeName(type) << "$";
|
|
||||||
stream << canonicalTypeName(_type.arguments.back());
|
|
||||||
stream << "$";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
std::visit(util::GenericVisitor{
|
|
||||||
[&](Declaration const* _declaration) {
|
|
||||||
printTypeArguments();
|
|
||||||
if (auto const* typeDeclarationAnnotation = dynamic_cast<TypeDeclarationAnnotation const*>(&_declaration->annotation()))
|
|
||||||
stream << *typeDeclarationAnnotation->canonicalName;
|
|
||||||
else
|
|
||||||
// TODO: canonical name
|
|
||||||
stream << _declaration->name();
|
|
||||||
},
|
|
||||||
[&](BuiltinType _builtinType) {
|
|
||||||
printTypeArguments();
|
|
||||||
switch(_builtinType)
|
|
||||||
{
|
|
||||||
case BuiltinType::Type:
|
|
||||||
stream << "type";
|
|
||||||
break;
|
|
||||||
case BuiltinType::Sort:
|
|
||||||
stream << "sort";
|
|
||||||
break;
|
|
||||||
case BuiltinType::Void:
|
|
||||||
stream << "void";
|
|
||||||
break;
|
|
||||||
case BuiltinType::Function:
|
|
||||||
stream << "fun";
|
|
||||||
break;
|
|
||||||
case BuiltinType::Unit:
|
|
||||||
stream << "unit";
|
|
||||||
break;
|
|
||||||
case BuiltinType::Pair:
|
|
||||||
stream << "pair";
|
|
||||||
break;
|
|
||||||
case BuiltinType::Word:
|
|
||||||
stream << "word";
|
|
||||||
break;
|
|
||||||
case BuiltinType::Integer:
|
|
||||||
stream << "integer";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, _type.constructor);
|
|
||||||
return stream.str();
|
|
||||||
},
|
|
||||||
[](TypeVariable const&)-> string {
|
|
||||||
solAssert(false);
|
|
||||||
},
|
|
||||||
}, _type);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string TypeEnvironment::typeToString(Type const& _type) const
|
std::string TypeEnvironment::typeToString(Type const& _type) const
|
||||||
{
|
{
|
||||||
return std::visit(util::GenericVisitor{
|
return std::visit(util::GenericVisitor{
|
||||||
@ -431,7 +279,7 @@ Sort TypeEnvironment::sort(Type _type) const
|
|||||||
}, _type);
|
}, _type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeSystem::declareTypeConstructor(TypeConstant::Constructor _typeConstructor, std::string _name, size_t _arguments)
|
void TypeSystem::declareTypeConstructor(TypeConstructor _typeConstructor, std::string _name, size_t _arguments)
|
||||||
{
|
{
|
||||||
Sort baseSort{{TypeClass{BuiltinClass::Type}}};
|
Sort baseSort{{TypeClass{BuiltinClass::Type}}};
|
||||||
bool newlyInserted = m_typeConstructors.emplace(std::make_pair(_typeConstructor, TypeConstructorInfo{
|
bool newlyInserted = m_typeConstructors.emplace(std::make_pair(_typeConstructor, TypeConstructorInfo{
|
||||||
@ -442,7 +290,7 @@ void TypeSystem::declareTypeConstructor(TypeConstant::Constructor _typeConstruct
|
|||||||
solAssert(newlyInserted, "Type constructor already declared.");
|
solAssert(newlyInserted, "Type constructor already declared.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeSystem::declareTypeClass(TypeConstant::Constructor _classDeclaration, std::string _name)
|
void TypeSystem::declareTypeClass(TypeConstructor _classDeclaration, std::string _name)
|
||||||
{
|
{
|
||||||
bool newlyInserted = m_typeConstructors.emplace(std::make_pair(_classDeclaration, TypeConstructorInfo{
|
bool newlyInserted = m_typeConstructors.emplace(std::make_pair(_classDeclaration, TypeConstructorInfo{
|
||||||
_name,
|
_name,
|
||||||
@ -453,7 +301,7 @@ void TypeSystem::declareTypeClass(TypeConstant::Constructor _classDeclaration, s
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
experimental::Type TypeSystem::type(TypeConstant::Constructor _constructor, std::vector<Type> _arguments) const
|
experimental::Type TypeSystem::type(TypeConstructor _constructor, std::vector<Type> _arguments) const
|
||||||
{
|
{
|
||||||
// TODO: proper error handling
|
// TODO: proper error handling
|
||||||
auto const& info = m_typeConstructors.at(_constructor);
|
auto const& info = m_typeConstructors.at(_constructor);
|
||||||
@ -495,7 +343,7 @@ experimental::Type TypeEnvironment::fresh(Type _type, bool _generalize)
|
|||||||
return freshImpl(_type, _generalize, freshImpl);
|
return freshImpl(_type, _generalize, freshImpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeSystem::instantiateClass(TypeConstant::Constructor _typeConstructor, Arity _arity)
|
void TypeSystem::instantiateClass(TypeConstructor _typeConstructor, Arity _arity)
|
||||||
{
|
{
|
||||||
// TODO: proper error handling
|
// TODO: proper error handling
|
||||||
auto& typeConstructorInfo = m_typeConstructors.at(_typeConstructor);
|
auto& typeConstructorInfo = m_typeConstructors.at(_typeConstructor);
|
||||||
@ -517,7 +365,9 @@ experimental::Type TypeSystemHelpers::tupleType(vector<Type> _elements) const
|
|||||||
|
|
||||||
vector<experimental::Type> TypeSystemHelpers::destTupleType(Type _tupleType) const
|
vector<experimental::Type> TypeSystemHelpers::destTupleType(Type _tupleType) const
|
||||||
{
|
{
|
||||||
auto [constructor, arguments] = destTypeExpression(_tupleType);
|
if (!isTypeConstant(_tupleType))
|
||||||
|
return {_tupleType};
|
||||||
|
auto [constructor, arguments] = destTypeConstant(_tupleType);
|
||||||
if (auto const* builtinType = get_if<BuiltinType>(&constructor))
|
if (auto const* builtinType = get_if<BuiltinType>(&constructor))
|
||||||
{
|
{
|
||||||
if (*builtinType == BuiltinType::Unit)
|
if (*builtinType == BuiltinType::Unit)
|
||||||
@ -534,11 +384,9 @@ vector<experimental::Type> TypeSystemHelpers::destTupleType(Type _tupleType) con
|
|||||||
Type tail = arguments.back();
|
Type tail = arguments.back();
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
auto const* tailTypeConstant = get_if<TypeConstant>(&tail);
|
if (!isTypeConstant(tail))
|
||||||
if (!tailTypeConstant)
|
|
||||||
break;
|
break;
|
||||||
|
auto [tailConstructor, tailArguments] = destTypeConstant(tail);
|
||||||
auto [tailConstructor, tailArguments] = destTypeExpression(tail);
|
|
||||||
auto const* builtinType = get_if<BuiltinType>(&tailConstructor);
|
auto const* builtinType = get_if<BuiltinType>(&tailConstructor);
|
||||||
if(!builtinType || *builtinType != BuiltinType::Pair)
|
if(!builtinType || *builtinType != BuiltinType::Pair)
|
||||||
break;
|
break;
|
||||||
@ -555,9 +403,9 @@ experimental::Type TypeSystemHelpers::functionType(experimental::Type _argType,
|
|||||||
return typeSystem.type(BuiltinType::Function, {_argType, _resultType});
|
return typeSystem.type(BuiltinType::Function, {_argType, _resultType});
|
||||||
}
|
}
|
||||||
|
|
||||||
tuple<TypeConstant::Constructor, vector<experimental::Type>> TypeSystemHelpers::destTypeExpression(Type _type) const
|
tuple<TypeConstructor, vector<experimental::Type>> TypeSystemHelpers::destTypeConstant(Type _type) const
|
||||||
{
|
{
|
||||||
using ResultType = tuple<TypeConstant::Constructor, vector<Type>>;
|
using ResultType = tuple<TypeConstructor, vector<Type>>;
|
||||||
return std::visit(util::GenericVisitor{
|
return std::visit(util::GenericVisitor{
|
||||||
[&](TypeConstant const& _type) -> ResultType {
|
[&](TypeConstant const& _type) -> ResultType {
|
||||||
return std::make_tuple(_type.constructor, _type.arguments);
|
return std::make_tuple(_type.constructor, _type.arguments);
|
||||||
@ -568,7 +416,7 @@ tuple<TypeConstant::Constructor, vector<experimental::Type>> TypeSystemHelpers::
|
|||||||
}, _type);
|
}, _type);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeSystemHelpers::isTypeExpression(Type _type) const
|
bool TypeSystemHelpers::isTypeConstant(Type _type) const
|
||||||
{
|
{
|
||||||
return std::visit(util::GenericVisitor{
|
return std::visit(util::GenericVisitor{
|
||||||
[&](TypeConstant const&) -> bool {
|
[&](TypeConstant const&) -> bool {
|
||||||
@ -582,7 +430,7 @@ bool TypeSystemHelpers::isTypeExpression(Type _type) const
|
|||||||
|
|
||||||
tuple<experimental::Type, experimental::Type> TypeSystemHelpers::destFunctionType(Type _functionType) const
|
tuple<experimental::Type, experimental::Type> TypeSystemHelpers::destFunctionType(Type _functionType) const
|
||||||
{
|
{
|
||||||
auto [constructor, arguments] = destTypeExpression(_functionType);
|
auto [constructor, arguments] = destTypeConstant(_functionType);
|
||||||
auto const* builtinType = get_if<BuiltinType>(&constructor);
|
auto const* builtinType = get_if<BuiltinType>(&constructor);
|
||||||
solAssert(builtinType && *builtinType == BuiltinType::Function);
|
solAssert(builtinType && *builtinType == BuiltinType::Function);
|
||||||
solAssert(arguments.size() == 2);
|
solAssert(arguments.size() == 2);
|
||||||
@ -591,9 +439,9 @@ tuple<experimental::Type, experimental::Type> TypeSystemHelpers::destFunctionTyp
|
|||||||
|
|
||||||
bool TypeSystemHelpers::isFunctionType(Type _type) const
|
bool TypeSystemHelpers::isFunctionType(Type _type) const
|
||||||
{
|
{
|
||||||
if (!isTypeExpression(_type))
|
if (!isTypeConstant(_type))
|
||||||
return false;
|
return false;
|
||||||
auto constructor = get<0>(destTypeExpression(_type));
|
auto constructor = get<0>(destTypeConstant(_type));
|
||||||
auto const* builtinType = get_if<BuiltinType>(&constructor);
|
auto const* builtinType = get_if<BuiltinType>(&constructor);
|
||||||
return builtinType && *builtinType == BuiltinType::Function;
|
return builtinType && *builtinType == BuiltinType::Function;
|
||||||
}
|
}
|
||||||
@ -625,18 +473,18 @@ experimental::Type TypeSystemHelpers::kindType(Type _type) const
|
|||||||
|
|
||||||
experimental::Type TypeSystemHelpers::destKindType(Type _type) const
|
experimental::Type TypeSystemHelpers::destKindType(Type _type) const
|
||||||
{
|
{
|
||||||
auto [constructor, arguments] = destTypeExpression(_type);
|
auto [constructor, arguments] = destTypeConstant(_type);
|
||||||
solAssert(constructor == TypeConstant::Constructor{BuiltinType::Type});
|
solAssert(constructor == TypeConstructor{BuiltinType::Type});
|
||||||
solAssert(arguments.size() == 1);
|
solAssert(arguments.size() == 1);
|
||||||
return arguments.front();
|
return arguments.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeSystemHelpers::isKindType(Type _type) const
|
bool TypeSystemHelpers::isKindType(Type _type) const
|
||||||
{
|
{
|
||||||
if (!isTypeExpression(_type))
|
if (!isTypeConstant(_type))
|
||||||
return false;
|
return false;
|
||||||
auto constructor = get<0>(destTypeExpression(_type));
|
auto constructor = get<0>(destTypeConstant(_type));
|
||||||
return constructor == TypeConstant::Constructor{BuiltinType::Type};
|
return constructor == TypeConstructor{BuiltinType::Type};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string TypeSystemHelpers::sortToString(Sort _sort) const
|
std::string TypeSystemHelpers::sortToString(Sort _sort) const
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <libsolidity/ast/experimental/Type.h>
|
||||||
#include <liblangutil/Exceptions.h>
|
#include <liblangutil/Exceptions.h>
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
@ -33,105 +34,6 @@ class TypeClassDefinition;
|
|||||||
namespace solidity::frontend::experimental
|
namespace solidity::frontend::experimental
|
||||||
{
|
{
|
||||||
|
|
||||||
class TypeSystem;
|
|
||||||
class TypeEnvironment;
|
|
||||||
|
|
||||||
struct TypeConstant;
|
|
||||||
struct TypeVariable;
|
|
||||||
|
|
||||||
using Type = std::variant<TypeConstant, TypeVariable>;
|
|
||||||
|
|
||||||
std::string canonicalTypeName(Type _type);
|
|
||||||
|
|
||||||
enum class BuiltinType
|
|
||||||
{
|
|
||||||
Type,
|
|
||||||
Sort,
|
|
||||||
Void,
|
|
||||||
Function,
|
|
||||||
Unit,
|
|
||||||
Pair,
|
|
||||||
Word,
|
|
||||||
Integer
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TypeConstant
|
|
||||||
{
|
|
||||||
using Constructor = std::variant<BuiltinType, Declaration const*>;
|
|
||||||
Constructor constructor;
|
|
||||||
std::vector<Type> arguments;
|
|
||||||
bool operator<(TypeConstant const& _rhs) const;
|
|
||||||
bool operator==(TypeConstant const& _rhs) const
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return !(*this < _rhs) && !(_rhs < *this);
|
|
||||||
}
|
|
||||||
bool operator!=(TypeConstant const& _rhs) const
|
|
||||||
{
|
|
||||||
return !operator==(_rhs);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class BuiltinClass
|
|
||||||
{
|
|
||||||
Type,
|
|
||||||
Kind,
|
|
||||||
Constraint
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TypeClass
|
|
||||||
{
|
|
||||||
std::variant<BuiltinClass, TypeClassDefinition const*> declaration;
|
|
||||||
std::string toString() const;
|
|
||||||
bool operator<(TypeClass const& _rhs) const;
|
|
||||||
bool operator==(TypeClass const& _rhs) const;
|
|
||||||
bool operator!=(TypeClass const& _rhs) const { return !operator==(_rhs); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Sort
|
|
||||||
{
|
|
||||||
std::set<TypeClass> classes;
|
|
||||||
bool operator==(Sort const& _rhs) const;
|
|
||||||
bool operator!=(Sort const& _rhs) const { return !operator==(_rhs); }
|
|
||||||
bool operator<=(Sort const& _rhs) const;
|
|
||||||
Sort operator+(Sort const& _rhs) const;
|
|
||||||
Sort operator-(Sort const& _rhs) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Arity
|
|
||||||
{
|
|
||||||
std::vector<Sort> argumentSorts;
|
|
||||||
TypeClass typeClass;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TypeVariable
|
|
||||||
{
|
|
||||||
size_t index() const { return m_index; }
|
|
||||||
bool generic() const { return m_generic; }
|
|
||||||
Sort const& sort() const { return m_sort; }
|
|
||||||
bool operator<(TypeVariable const& _rhs) const
|
|
||||||
{
|
|
||||||
// TODO: more robust comparison?
|
|
||||||
return m_index < _rhs.m_index;
|
|
||||||
}
|
|
||||||
bool operator==(TypeVariable const& _rhs) const
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
return !(*this < _rhs) && !(_rhs < *this);
|
|
||||||
}
|
|
||||||
bool operator!=(TypeVariable const& _rhs) const
|
|
||||||
{
|
|
||||||
return !operator==(_rhs);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
friend class TypeSystem;
|
|
||||||
size_t m_index = 0;
|
|
||||||
Sort m_sort;
|
|
||||||
bool m_generic = false;
|
|
||||||
TypeVariable(size_t _index, Sort _sort, bool _generic):
|
|
||||||
m_index(_index), m_sort(std::move(_sort)), m_generic(_generic) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class TypeEnvironment
|
class TypeEnvironment
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -171,26 +73,26 @@ public:
|
|||||||
TypeSystem();
|
TypeSystem();
|
||||||
TypeSystem(TypeSystem const&) = delete;
|
TypeSystem(TypeSystem const&) = delete;
|
||||||
TypeSystem const& operator=(TypeSystem const&) = delete;
|
TypeSystem const& operator=(TypeSystem const&) = delete;
|
||||||
Type type(TypeConstant::Constructor _typeConstructor, std::vector<Type> _arguments) const;
|
Type type(TypeConstructor _typeConstructor, std::vector<Type> _arguments) const;
|
||||||
std::string typeName(TypeConstant::Constructor _typeConstructor) const
|
std::string typeName(TypeConstructor _typeConstructor) const
|
||||||
{
|
{
|
||||||
// TODO: proper error handling
|
// TODO: proper error handling
|
||||||
return m_typeConstructors.at(_typeConstructor).name;
|
return m_typeConstructors.at(_typeConstructor).name;
|
||||||
}
|
}
|
||||||
void declareTypeConstructor(TypeConstant::Constructor _typeConstructor, std::string _name, size_t _arguments);
|
void declareTypeConstructor(TypeConstructor _typeConstructor, std::string _name, size_t _arguments);
|
||||||
size_t constructorArguments(TypeConstant::Constructor _typeConstructor) const
|
size_t constructorArguments(TypeConstructor _typeConstructor) const
|
||||||
{
|
{
|
||||||
// TODO: error handling
|
// TODO: error handling
|
||||||
return m_typeConstructors.at(_typeConstructor).arguments();
|
return m_typeConstructors.at(_typeConstructor).arguments();
|
||||||
}
|
}
|
||||||
TypeConstructorInfo const& constructorInfo(TypeConstant::Constructor _typeConstructor) const
|
TypeConstructorInfo const& constructorInfo(TypeConstructor _typeConstructor) const
|
||||||
{
|
{
|
||||||
// TODO: error handling
|
// TODO: error handling
|
||||||
return m_typeConstructors.at(_typeConstructor);
|
return m_typeConstructors.at(_typeConstructor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void declareTypeClass(TypeConstant::Constructor _classDeclaration, std::string _name);
|
void declareTypeClass(TypeConstructor _classDeclaration, std::string _name);
|
||||||
void instantiateClass(TypeConstant::Constructor _typeConstructor, Arity _arity);
|
void instantiateClass(TypeConstructor _typeConstructor, Arity _arity);
|
||||||
|
|
||||||
Type freshTypeVariable(bool _generic, Sort _sort);
|
Type freshTypeVariable(bool _generic, Sort _sort);
|
||||||
Type freshKindVariable(bool _generic, Sort _sort);
|
Type freshKindVariable(bool _generic, Sort _sort);
|
||||||
@ -201,15 +103,15 @@ public:
|
|||||||
Type freshVariable(bool _generic, Sort _sort);
|
Type freshVariable(bool _generic, Sort _sort);
|
||||||
private:
|
private:
|
||||||
size_t m_numTypeVariables = 0;
|
size_t m_numTypeVariables = 0;
|
||||||
std::map<TypeConstant::Constructor, TypeConstructorInfo> m_typeConstructors;
|
std::map<TypeConstructor, TypeConstructorInfo> m_typeConstructors;
|
||||||
TypeEnvironment m_globalTypeEnvironment{*this};
|
TypeEnvironment m_globalTypeEnvironment{*this};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TypeSystemHelpers
|
struct TypeSystemHelpers
|
||||||
{
|
{
|
||||||
TypeSystem const& typeSystem;
|
TypeSystem const& typeSystem;
|
||||||
std::tuple<TypeConstant::Constructor, std::vector<Type>> destTypeExpression(Type _type) const;
|
std::tuple<TypeConstructor, std::vector<Type>> destTypeConstant(Type _type) const;
|
||||||
bool isTypeExpression(Type _type) const;
|
bool isTypeConstant(Type _type) const;
|
||||||
Type tupleType(std::vector<Type> _elements) const;
|
Type tupleType(std::vector<Type> _elements) const;
|
||||||
std::vector<Type> destTupleType(Type _tupleType) const;
|
std::vector<Type> destTupleType(Type _tupleType) const;
|
||||||
Type functionType(Type _argType, Type _resultType) const;
|
Type functionType(Type _argType, Type _resultType) const;
|
||||||
|
@ -172,7 +172,7 @@ bool IRGeneratorForStatements::visit(FunctionCall const& _functionCall)
|
|||||||
auto const& expressionAnnotation = m_context.analysis.annotation<TypeInference>(memberAccess->expression());
|
auto const& expressionAnnotation = m_context.analysis.annotation<TypeInference>(memberAccess->expression());
|
||||||
solAssert(expressionAnnotation.type);
|
solAssert(expressionAnnotation.type);
|
||||||
|
|
||||||
auto typeConstructor = std::get<0>(TypeSystemHelpers{m_context.analysis.typeSystem()}.destTypeExpression(
|
auto typeConstructor = std::get<0>(TypeSystemHelpers{m_context.analysis.typeSystem()}.destTypeConstant(
|
||||||
m_context.analysis.typeSystem().env().resolve(*expressionAnnotation.type)
|
m_context.analysis.typeSystem().env().resolve(*expressionAnnotation.type)
|
||||||
));
|
));
|
||||||
auto const* typeClass = dynamic_cast<Identifier const*>(&memberAccess->expression());
|
auto const* typeClass = dynamic_cast<Identifier const*>(&memberAccess->expression());
|
||||||
|
Loading…
Reference in New Issue
Block a user