mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
tmp
This commit is contained in:
parent
14a34ae088
commit
315270f3bb
@ -50,6 +50,8 @@ set(sources
|
||||
analysis/experimental/Analysis.h
|
||||
analysis/experimental/TypeInference.cpp
|
||||
analysis/experimental/TypeInference.h
|
||||
analysis/experimental/TypeRegistration.cpp
|
||||
analysis/experimental/TypeRegistration.h
|
||||
analysis/experimental/SyntaxRestrictor.cpp
|
||||
analysis/experimental/SyntaxRestrictor.h
|
||||
ast/AST.cpp
|
||||
|
@ -19,26 +19,87 @@
|
||||
|
||||
#include <libsolidity/analysis/experimental/SyntaxRestrictor.h>
|
||||
#include <libsolidity/analysis/experimental/TypeInference.h>
|
||||
#include <libsolidity/analysis/experimental/TypeRegistration.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity::langutil;
|
||||
using namespace solidity::frontend::experimental;
|
||||
|
||||
// TODO: creating all of them for all nodes up front may be wasteful, we should improve the mechanism.
|
||||
struct Analysis::AnnotationContainer
|
||||
{
|
||||
TypeRegistration::Annotation typeRegistrationAnnotation;
|
||||
TypeInference::Annotation typeInferenceAnnotation;
|
||||
};
|
||||
|
||||
template<>
|
||||
TypeRegistration::Annotation& solidity::frontend::experimental::detail::AnnotationFetcher<TypeRegistration>::get(ASTNode const& _node)
|
||||
{
|
||||
return analysis.annotationContainer(_node).typeRegistrationAnnotation;
|
||||
}
|
||||
|
||||
template<>
|
||||
TypeInference::Annotation& solidity::frontend::experimental::detail::AnnotationFetcher<TypeInference>::get(ASTNode const& _node)
|
||||
{
|
||||
return analysis.annotationContainer(_node).typeInferenceAnnotation;
|
||||
}
|
||||
|
||||
Analysis::AnnotationContainer& Analysis::annotationContainer(ASTNode const& _node)
|
||||
{
|
||||
solAssert(_node.id() > 0);
|
||||
size_t id = static_cast<size_t>(_node.id());
|
||||
solAssert(id < m_maxAstId);
|
||||
return m_annotations[id];
|
||||
}
|
||||
|
||||
Analysis::Analysis(langutil::ErrorReporter& _errorReporter, uint64_t _maxAstId):
|
||||
m_errorReporter(_errorReporter),
|
||||
m_maxAstId(_maxAstId)
|
||||
m_maxAstId(_maxAstId),
|
||||
m_annotations(std::make_unique<AnnotationContainer[]>(static_cast<size_t>(_maxAstId)))
|
||||
{
|
||||
}
|
||||
|
||||
Analysis::~Analysis()
|
||||
{}
|
||||
|
||||
template<size_t... Is>
|
||||
std::tuple<std::integral_constant<size_t, Is>...> makeIndexTuple(std::index_sequence<Is...>) {
|
||||
return std::make_tuple( std::integral_constant<size_t, Is>{}...);
|
||||
}
|
||||
|
||||
bool Analysis::check(vector<shared_ptr<SourceUnit const>> const& _sourceUnits)
|
||||
{
|
||||
SyntaxRestrictor syntaxRestrictor{m_errorReporter};
|
||||
using AnalysisSteps = std::tuple<SyntaxRestrictor, TypeRegistration, TypeInference>;
|
||||
|
||||
return std::apply([&](auto... _indexTuple) {
|
||||
return ([&](auto&& _step) {
|
||||
for (auto source: _sourceUnits)
|
||||
if (!syntaxRestrictor.check(*source))
|
||||
if (!_step.analyze(*source))
|
||||
return false;
|
||||
return true;
|
||||
}(std::tuple_element_t<decltype(_indexTuple)::value, AnalysisSteps>{*this}) && ...);
|
||||
}, makeIndexTuple(std::make_index_sequence<std::tuple_size_v<AnalysisSteps>>{}));
|
||||
|
||||
/*
|
||||
{
|
||||
SyntaxRestrictor syntaxRestrictor{*this};
|
||||
for (auto source: _sourceUnits)
|
||||
if (!syntaxRestrictor.analyze(*source))
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
TypeRegistration typeRegistration{*this};
|
||||
for (auto source: _sourceUnits)
|
||||
if (!typeRegistration.analyze(*source))
|
||||
return false;
|
||||
}
|
||||
{
|
||||
TypeInference typeInference{*this};
|
||||
for (auto source: _sourceUnits)
|
||||
if (!typeInference.analyze(*source))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
*/
|
||||
}
|
||||
|
@ -17,6 +17,8 @@
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
#pragma once
|
||||
|
||||
#include <libsolidity/ast/experimental/TypeSystem.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
@ -24,6 +26,7 @@
|
||||
namespace solidity::frontend
|
||||
{
|
||||
class SourceUnit;
|
||||
class ASTNode;
|
||||
}
|
||||
|
||||
namespace solidity::langutil
|
||||
@ -33,19 +36,43 @@ class ErrorReporter;
|
||||
|
||||
namespace solidity::frontend::experimental
|
||||
{
|
||||
class TypeSystem;
|
||||
|
||||
class Analysis;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template<typename Step>
|
||||
struct AnnotationFetcher
|
||||
{
|
||||
Analysis& analysis;
|
||||
typename Step::Annotation& get(ASTNode const& _node);
|
||||
};
|
||||
}
|
||||
|
||||
class Analysis
|
||||
{
|
||||
struct AnnotationContainer;
|
||||
public:
|
||||
Analysis(langutil::ErrorReporter& _errorReporter, uint64_t _maxAstId);
|
||||
Analysis(Analysis const&) = delete;
|
||||
~Analysis();
|
||||
Analysis const& operator=(Analysis const&) = delete;
|
||||
bool check(std::vector<std::shared_ptr<SourceUnit const>> const& _sourceUnits);
|
||||
langutil::ErrorReporter& errorReporter() { return m_errorReporter; }
|
||||
uint64_t maxAstId() const { return m_maxAstId; }
|
||||
TypeSystem& typeSystem() { return m_typeSystem; }
|
||||
template<typename Step>
|
||||
typename Step::Annotation& annotation(ASTNode const& _node)
|
||||
{
|
||||
return detail::AnnotationFetcher<Step>{*this}.get(_node);
|
||||
}
|
||||
AnnotationContainer& annotationContainer(ASTNode const& _node);
|
||||
private:
|
||||
langutil::ErrorReporter& m_errorReporter;
|
||||
TypeSystem m_typeSystem;
|
||||
uint64_t m_maxAstId = 0;
|
||||
std::unique_ptr<AnnotationContainer[]> m_annotations;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -18,13 +18,18 @@
|
||||
|
||||
#include <libsolidity/analysis/experimental/SyntaxRestrictor.h>
|
||||
|
||||
#include <libsolidity/analysis/experimental/Analysis.h>
|
||||
|
||||
#include <liblangutil/Exceptions.h>
|
||||
|
||||
using namespace solidity::frontend;
|
||||
using namespace solidity::frontend::experimental;
|
||||
using namespace solidity::langutil;
|
||||
|
||||
bool SyntaxRestrictor::check(ASTNode const& _astRoot)
|
||||
SyntaxRestrictor::SyntaxRestrictor(Analysis& _analysis): m_errorReporter(_analysis.errorReporter())
|
||||
{}
|
||||
|
||||
bool SyntaxRestrictor::analyze(ASTNode const& _astRoot)
|
||||
{
|
||||
_astRoot.accept(*this);
|
||||
return !Error::containsErrors(m_errorReporter.errors());
|
||||
|
@ -24,14 +24,14 @@
|
||||
|
||||
namespace solidity::frontend::experimental
|
||||
{
|
||||
class Analysis;
|
||||
|
||||
class SyntaxRestrictor: public ASTConstVisitor
|
||||
{
|
||||
public:
|
||||
/// @param _errorReporter provides the error logging functionality.
|
||||
explicit SyntaxRestrictor(langutil::ErrorReporter& _errorReporter): m_errorReporter(_errorReporter) {}
|
||||
SyntaxRestrictor(Analysis& _analysis);
|
||||
|
||||
bool check(ASTNode const& _astRoot);
|
||||
bool analyze(ASTNode const& _astRoot);
|
||||
|
||||
private:
|
||||
/// Default visit will reject all AST nodes that are not explicitly allowed.
|
||||
|
@ -34,22 +34,12 @@ using namespace solidity::langutil;
|
||||
|
||||
TypeInference::TypeInference(Analysis& _analysis):
|
||||
m_analysis(_analysis),
|
||||
m_errorReporter(_analysis.errorReporter())
|
||||
m_errorReporter(_analysis.errorReporter()),
|
||||
m_typeSystem(_analysis.typeSystem())
|
||||
{
|
||||
for (auto [type, name, arity]: std::initializer_list<std::tuple<BuiltinType, const char*, uint64_t>> {
|
||||
{BuiltinType::Void, "void", 0},
|
||||
{BuiltinType::Function, "fun", 2},
|
||||
{BuiltinType::Unit, "unit", 0},
|
||||
{BuiltinType::Pair, "pair", 2},
|
||||
{BuiltinType::Word, "word", 0},
|
||||
{BuiltinType::Integer, "integer", 0}
|
||||
})
|
||||
m_typeSystem.declareBuiltinType(type, name, arity);
|
||||
m_voidType = m_typeSystem.builtinType(BuiltinType::Void, {});
|
||||
m_wordType = m_typeSystem.builtinType(BuiltinType::Word, {});
|
||||
m_integerType = m_typeSystem.builtinType(BuiltinType::Integer, {});
|
||||
|
||||
m_typeAnnotations.resize(_analysis.maxAstId());
|
||||
}
|
||||
|
||||
bool TypeInference::analyze(SourceUnit const& _sourceUnit)
|
||||
@ -72,7 +62,7 @@ bool TypeInference::visit(FunctionDefinition const& _functionDefinition)
|
||||
auto typeFromParameterList = [&](ParameterList const* _list) {
|
||||
if (!_list)
|
||||
return m_typeSystem.builtinType(BuiltinType::Unit, {});
|
||||
return TypeSystemHelpers{m_typeSystem}.tupleType(_list->parameters() | ranges::view::transform([&](auto _param) {
|
||||
return TypeSystemHelpers{m_typeSystem}.tupleType(_list->parameters() | ranges::views::transform([&](auto _param) {
|
||||
auto& argAnnotation = annotation(*_param);
|
||||
solAssert(argAnnotation.type);
|
||||
return *argAnnotation.type;
|
||||
@ -173,7 +163,6 @@ experimental::Type TypeInference::fromTypeName(TypeName const& _typeName)
|
||||
else
|
||||
m_errorReporter.typeError(0000_error, _typeName.location(), "Unsupported type name.");
|
||||
return m_typeSystem.freshTypeVariable(false);
|
||||
|
||||
}
|
||||
void TypeInference::unify(Type _a, Type _b)
|
||||
{
|
||||
@ -256,12 +245,9 @@ void TypeInference::endVisit(Assignment const& _assignment)
|
||||
assignmentAnnotation.type = m_typeSystem.resolve(*lhsAnnotation.type);
|
||||
}
|
||||
|
||||
TypeInference::TypeAnnotation& TypeInference::annotation(ASTNode const& _node)
|
||||
TypeInference::Annotation& TypeInference::annotation(ASTNode const& _node)
|
||||
{
|
||||
auto& annotation = m_typeAnnotations.at(static_cast<size_t>(_node.id()));
|
||||
if (!annotation)
|
||||
annotation = make_unique<TypeAnnotation>();
|
||||
return *annotation;
|
||||
return m_analysis.annotation<TypeInference>(_node);
|
||||
}
|
||||
|
||||
bool TypeInference::visit(Identifier const& _identifier)
|
||||
|
@ -22,8 +22,6 @@
|
||||
|
||||
#include <liblangutil/ErrorReporter.h>
|
||||
|
||||
#include <range/v3/span.hpp>
|
||||
|
||||
namespace solidity::frontend::experimental
|
||||
{
|
||||
|
||||
@ -35,6 +33,12 @@ public:
|
||||
TypeInference(Analysis& _analysis);
|
||||
|
||||
bool analyze(SourceUnit const& _sourceUnit);
|
||||
|
||||
|
||||
struct Annotation
|
||||
{
|
||||
std::optional<Type> type;
|
||||
};
|
||||
private:
|
||||
bool visit(Block const&) override { return true; }
|
||||
bool visit(VariableDeclarationStatement const&) override { return true; }
|
||||
@ -67,22 +71,15 @@ private:
|
||||
Type fromTypeName(TypeName const& _typeName);
|
||||
Analysis& m_analysis;
|
||||
langutil::ErrorReporter& m_errorReporter;
|
||||
TypeSystem m_typeSystem;
|
||||
TypeSystem& m_typeSystem;
|
||||
Type m_voidType;
|
||||
Type m_wordType;
|
||||
Type m_integerType;
|
||||
std::optional<Type> m_currentFunctionType;
|
||||
|
||||
struct TypeAnnotation
|
||||
{
|
||||
std::optional<Type> type;
|
||||
};
|
||||
|
||||
TypeAnnotation& annotation(ASTNode const& _node);
|
||||
Annotation& annotation(ASTNode const& _node);
|
||||
|
||||
void unify(Type _a, Type _b);
|
||||
|
||||
std::vector<std::unique_ptr<TypeAnnotation>> m_typeAnnotations;
|
||||
};
|
||||
|
||||
}
|
102
libsolidity/analysis/experimental/TypeRegistration.cpp
Normal file
102
libsolidity/analysis/experimental/TypeRegistration.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
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/analysis/experimental/TypeRegistration.h>
|
||||
#include <libsolidity/analysis/experimental/Analysis.h>
|
||||
#include <liblangutil/Exceptions.h>
|
||||
|
||||
#include <libyul/AsmAnalysis.h>
|
||||
#include <libyul/AsmAnalysisInfo.h>
|
||||
#include <libyul/AST.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity::frontend;
|
||||
using namespace solidity::frontend::experimental;
|
||||
using namespace solidity::langutil;
|
||||
|
||||
TypeRegistration::TypeRegistration(Analysis& _analysis):
|
||||
m_analysis(_analysis),
|
||||
m_errorReporter(_analysis.errorReporter()),
|
||||
m_typeSystem(_analysis.typeSystem())
|
||||
{
|
||||
for (auto [type, name, arity]: std::initializer_list<std::tuple<BuiltinType, const char*, uint64_t>> {
|
||||
{BuiltinType::Void, "void", 0},
|
||||
{BuiltinType::Function, "fun", 2},
|
||||
{BuiltinType::Unit, "unit", 0},
|
||||
{BuiltinType::Pair, "pair", 2},
|
||||
{BuiltinType::Word, "word", 0},
|
||||
{BuiltinType::Integer, "integer", 0}
|
||||
})
|
||||
m_typeSystem.declareBuiltinType(type, name, arity);
|
||||
}
|
||||
|
||||
bool TypeRegistration::analyze(SourceUnit const& _sourceUnit)
|
||||
{
|
||||
_sourceUnit.accept(*this);
|
||||
return !m_errorReporter.hasErrors();
|
||||
}
|
||||
|
||||
bool TypeRegistration::visit(TypeClassDefinition const& _typeClassDefinition)
|
||||
{
|
||||
if (!m_visitedClasses.insert(_typeClassDefinition.id()).second)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
bool TypeRegistration::visit(TypeClassInstantiation const& _typeClassInstantiation)
|
||||
{
|
||||
auto const* classDefintion = dynamic_cast<TypeClassDefinition const*>(_typeClassInstantiation.sort().annotation().referencedDeclaration);
|
||||
if (!classDefintion)
|
||||
m_errorReporter.fatalTypeError(0000_error, _typeClassInstantiation.sort().location(), "Expected a type class.");
|
||||
classDefintion->accept(*this);
|
||||
|
||||
// TypeClass typeClass{classDefintion};
|
||||
|
||||
auto fromTypeName = [&](TypeName const& _typeName) -> Type {
|
||||
if (auto const* elementaryTypeName = dynamic_cast<ElementaryTypeName const*>(&_typeName))
|
||||
{
|
||||
switch(elementaryTypeName->typeName().token())
|
||||
{
|
||||
case Token::Word:
|
||||
return m_typeSystem.builtinType(BuiltinType::Word, {});
|
||||
case Token::Void:
|
||||
return m_typeSystem.builtinType(BuiltinType::Void, {});
|
||||
case Token::Integer:
|
||||
return m_typeSystem.builtinType(BuiltinType::Integer, {});
|
||||
default:
|
||||
m_errorReporter.typeError(0000_error, _typeName.location(), "Only elementary types are supported.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
m_errorReporter.typeError(0000_error, _typeName.location(), "Unsupported type name.");
|
||||
return m_typeSystem.freshTypeVariable(false);
|
||||
};
|
||||
auto type = fromTypeName(_typeClassInstantiation.typeConstructor());
|
||||
_typeClassInstantiation.argumentSorts();
|
||||
|
||||
// m_typeSystem.instantiateClass();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
TypeRegistration::Annotation& TypeRegistration::annotation(ASTNode const& _node)
|
||||
{
|
||||
return m_analysis.annotation<TypeRegistration>(_node);
|
||||
}
|
51
libsolidity/analysis/experimental/TypeRegistration.h
Normal file
51
libsolidity/analysis/experimental/TypeRegistration.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
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 <libsolidity/ast/ASTVisitor.h>
|
||||
#include <libsolidity/ast/experimental/TypeSystem.h>
|
||||
|
||||
#include <liblangutil/ErrorReporter.h>
|
||||
|
||||
namespace solidity::frontend::experimental
|
||||
{
|
||||
|
||||
class Analysis;
|
||||
|
||||
class TypeRegistration: public ASTConstVisitor
|
||||
{
|
||||
public:
|
||||
struct Annotation
|
||||
{
|
||||
Type type;
|
||||
};
|
||||
TypeRegistration(Analysis& _analysis);
|
||||
|
||||
bool analyze(SourceUnit const& _sourceUnit);
|
||||
private:
|
||||
bool visit(TypeClassDefinition const& _typeClassDefinition) override;
|
||||
bool visit(TypeClassInstantiation const& _typeClassInstantiation) override;
|
||||
Annotation& annotation(ASTNode const& _node);
|
||||
|
||||
Analysis& m_analysis;
|
||||
langutil::ErrorReporter& m_errorReporter;
|
||||
TypeSystem& m_typeSystem;
|
||||
std::set<int64_t> m_visitedClasses;
|
||||
};
|
||||
|
||||
}
|
@ -70,7 +70,7 @@ std::string TypeSystem::typeToString(Type const& _type) const
|
||||
{
|
||||
auto tupleTypes = TypeSystemHelpers{*this}.destTupleType(_type);
|
||||
stream << "(";
|
||||
for (auto type: tupleTypes | ranges::view::drop_last(1))
|
||||
for (auto type: tupleTypes | ranges::views::drop_last(1))
|
||||
stream << typeToString(type) << ", ";
|
||||
stream << typeToString(tupleTypes.back()) << ")";
|
||||
break;
|
||||
@ -136,16 +136,16 @@ experimental::Type TypeSystem::freshTypeVariable(bool _generic)
|
||||
void TypeSystem::instantiate(TypeVariable _variable, Type _type)
|
||||
{
|
||||
validate(_variable);
|
||||
solAssert(!m_typeVariables.at(_variable.index()).has_value());
|
||||
solAssert(!m_typeVariables.at(static_cast<size_t>(_variable.index())).has_value());
|
||||
solAssert(_variable.m_parent == this);
|
||||
m_typeVariables[_variable.index()] = _type;
|
||||
m_typeVariables[static_cast<size_t>(_variable.index())] = _type;
|
||||
}
|
||||
|
||||
experimental::Type TypeSystem::resolve(Type _type) const
|
||||
{
|
||||
Type result = _type;
|
||||
while(auto const* var = std::get_if<TypeVariable>(&result))
|
||||
if (auto value = m_typeVariables.at(var->index()))
|
||||
if (auto value = m_typeVariables.at(static_cast<size_t>(var->index())))
|
||||
result = *value;
|
||||
else
|
||||
break;
|
||||
@ -182,7 +182,7 @@ experimental::Type TypeSystem::fresh(Type _type, bool _generalize)
|
||||
[&](TypeExpression const& _type) -> Type {
|
||||
return TypeExpression{
|
||||
_type.constructor,
|
||||
_type.arguments | ranges::view::transform([&](Type _argType) {
|
||||
_type.arguments | ranges::views::transform([&](Type _argType) {
|
||||
return _recurse(_argType, _generalize, _recurse);
|
||||
}) | ranges::to<vector<Type>>
|
||||
};
|
||||
@ -203,6 +203,13 @@ experimental::Type TypeSystem::fresh(Type _type, bool _generalize)
|
||||
return freshImpl(_type, _generalize, freshImpl);
|
||||
}
|
||||
|
||||
void TypeSystem::instantiateClass(TypeExpression::Constructor _typeConstructor, vector<TypeClass> _argumentSorts, TypeClass _class)
|
||||
{
|
||||
(void)_typeConstructor;
|
||||
(void)_argumentSorts;
|
||||
(void)_class;
|
||||
}
|
||||
|
||||
experimental::Type TypeSystemHelpers::tupleType(vector<Type> _elements) const
|
||||
{
|
||||
if (_elements.empty())
|
||||
@ -210,7 +217,7 @@ experimental::Type TypeSystemHelpers::tupleType(vector<Type> _elements) const
|
||||
if (_elements.size() == 1)
|
||||
return _elements.front();
|
||||
Type result = _elements.back();
|
||||
for (Type type: _elements | ranges::view::reverse | ranges::view::drop_exactly(1))
|
||||
for (Type type: _elements | ranges::views::reverse | ranges::views::drop_exactly(1))
|
||||
result = typeSystem.builtinType(BuiltinType::Pair, {type, result});
|
||||
return result;
|
||||
}
|
||||
|
@ -55,7 +55,6 @@ struct TypeExpression
|
||||
using Constructor = std::variant<BuiltinType, Declaration const*>;
|
||||
Constructor constructor;
|
||||
std::vector<Type> arguments;
|
||||
|
||||
};
|
||||
|
||||
struct TypeVariable
|
||||
@ -71,6 +70,21 @@ private:
|
||||
TypeVariable(TypeSystem const& _parent, uint64_t _index, bool _generic): m_parent(&_parent), m_index(_index), m_generic(_generic) {}
|
||||
};
|
||||
|
||||
struct TypeClass
|
||||
{
|
||||
Declaration const* declaration = nullptr;
|
||||
};
|
||||
|
||||
struct Sort
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
struct Arity
|
||||
{
|
||||
std::vector<Arity> _argumentSorts;
|
||||
TypeClass _class;
|
||||
};
|
||||
class TypeSystem
|
||||
{
|
||||
public:
|
||||
@ -90,6 +104,7 @@ public:
|
||||
Type fresh(Type _type, bool _generalize);
|
||||
struct UnificationFailure { Type a; Type b; };
|
||||
[[nodiscard]] std::vector<UnificationFailure> unify(Type _a, Type _b);
|
||||
void instantiateClass(TypeExpression::Constructor _typeConstructor, std::vector<TypeClass> _argumentSorts, TypeClass _class);
|
||||
private:
|
||||
void instantiate(TypeVariable _variable, Type _type);
|
||||
void validate(TypeVariable _variable) const;
|
||||
@ -101,6 +116,7 @@ private:
|
||||
};
|
||||
std::map<BuiltinType, TypeConstructorInfo> m_builtinTypes;
|
||||
std::vector<std::optional<Type>> m_typeVariables;
|
||||
std::map<TypeExpression::Constructor, Sort> m_sorts;
|
||||
};
|
||||
|
||||
struct TypeSystemHelpers
|
||||
|
@ -100,7 +100,7 @@ string IRGenerator::generate(FunctionDefinition const& _function)
|
||||
std::stringstream code;
|
||||
code << "function " << IRNames::function(_function) << "(";
|
||||
if (_function.parameters().size() > 1)
|
||||
for (auto const& arg: _function.parameters() | ranges::view::drop_last(1))
|
||||
for (auto const& arg: _function.parameters() | ranges::views::drop_last(1))
|
||||
code << IRNames::localVariable(*arg) << ", ";
|
||||
if (!_function.parameters().empty())
|
||||
code << IRNames::localVariable(*_function.parameters().back());
|
||||
@ -109,7 +109,7 @@ string IRGenerator::generate(FunctionDefinition const& _function)
|
||||
{
|
||||
code << " -> ";
|
||||
if (_function.returnParameters().size() > 1)
|
||||
for (auto const& arg: _function.returnParameters() | ranges::view::drop_last(1))
|
||||
for (auto const& arg: _function.returnParameters() | ranges::views::drop_last(1))
|
||||
code << IRNames::localVariable(*arg) << ", ";
|
||||
if (!_function.returnParameters().empty())
|
||||
code << IRNames::localVariable(*_function.returnParameters().back());
|
||||
|
@ -46,14 +46,14 @@ public:
|
||||
std::optional<uint8_t> _eofVersion,
|
||||
RevertStrings /*_revertStrings*/,
|
||||
std::map<std::string, unsigned> /*_sourceIndices*/,
|
||||
langutil::DebugInfoSelection const& _debugInfoSelection,
|
||||
langutil::CharStreamProvider const* _soliditySourceProvider,
|
||||
langutil::DebugInfoSelection const& /*_debugInfoSelection*/,
|
||||
langutil::CharStreamProvider const* /*_soliditySourceProvider*/,
|
||||
Analysis const& _analysis
|
||||
):
|
||||
m_evmVersion(_evmVersion),
|
||||
m_eofVersion(_eofVersion),
|
||||
m_debugInfoSelection(_debugInfoSelection),
|
||||
m_soliditySourceProvider(_soliditySourceProvider),
|
||||
// m_debugInfoSelection(_debugInfoSelection),
|
||||
// m_soliditySourceProvider(_soliditySourceProvider),
|
||||
m_context{_analysis, {}, {}}
|
||||
{}
|
||||
|
||||
@ -69,8 +69,8 @@ private:
|
||||
langutil::EVMVersion const m_evmVersion;
|
||||
std::optional<uint8_t> const m_eofVersion;
|
||||
OptimiserSettings const m_optimiserSettings;
|
||||
langutil::DebugInfoSelection m_debugInfoSelection = {};
|
||||
langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr;
|
||||
// langutil::DebugInfoSelection m_debugInfoSelection = {};
|
||||
// langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr;
|
||||
IRGenerationContext m_context;
|
||||
};
|
||||
|
||||
|
@ -145,7 +145,6 @@ void IRGeneratorForStatements::endVisit(Return const& _return)
|
||||
m_code << IRNames::localVariable(*returnParameters.front()) << " := " << IRNames::localVariable(*value) << "\n";
|
||||
}
|
||||
|
||||
_return.annotation().functionReturnParameters;
|
||||
m_code << "leave\n";
|
||||
}
|
||||
|
||||
@ -163,7 +162,7 @@ bool IRGeneratorForStatements::visit(FunctionCall const& _functionCall)
|
||||
m_code << "let " << IRNames::localVariable(_functionCall) << " := " << IRNames::function(*functionDefinition) << "(";
|
||||
auto const& arguments = _functionCall.arguments();
|
||||
if (arguments.size() > 1)
|
||||
for (auto arg: arguments | ranges::view::drop_last(1))
|
||||
for (auto arg: arguments | ranges::views::drop_last(1))
|
||||
m_code << IRNames::localVariable(*arg) << ", ";
|
||||
if (!arguments.empty())
|
||||
m_code << IRNames::localVariable(*arguments.back());
|
||||
|
Loading…
Reference in New Issue
Block a user