Skip to content

Commit

Permalink
Merge pull request #14538 from ethereum/experimentalAnalysisBasicInfr…
Browse files Browse the repository at this point in the history
…astructure

New Analysis basic infrastructure
  • Loading branch information
ekpyron authored Sep 13, 2023
2 parents 64a0f62 + 14aed39 commit 9bce5f9
Show file tree
Hide file tree
Showing 16 changed files with 320 additions and 148 deletions.
15 changes: 14 additions & 1 deletion liblangutil/Scanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1019,15 +1019,28 @@ std::tuple<Token, unsigned, unsigned> Scanner::scanIdentifierOrKeyword()
while (isIdentifierPart(m_char) || (m_char == '.' && m_kind == ScannerKind::Yul))
addLiteralCharAndAdvance();
literal.complete();

auto const token = TokenTraits::fromIdentifierOrKeyword(m_tokens[NextNext].literal);
if (m_kind == ScannerKind::Yul)
switch (m_kind)
{
case ScannerKind::Solidity:
// Turn experimental Solidity keywords that are not keywords in legacy Solidity into identifiers.
if (TokenTraits::isExperimentalSolidityOnlyKeyword(std::get<0>(token)))
return std::make_tuple(Token::Identifier, 0, 0);
break;
case ScannerKind::Yul:
// Turn Solidity identifier into a Yul keyword
if (m_tokens[NextNext].literal == "leave")
return std::make_tuple(Token::Leave, 0, 0);
// Turn non-Yul keywords into identifiers.
if (!TokenTraits::isYulKeyword(std::get<0>(token)))
return std::make_tuple(Token::Identifier, 0, 0);
break;
case ScannerKind::ExperimentalSolidity:
// Turn legacy Solidity keywords that are not keywords in experimental Solidity into identifiers.
if (!TokenTraits::isExperimentalSolidityKeyword(std::get<0>(token)))
return std::make_tuple(Token::Identifier, 0, 0);
break;
}
return token;
}
Expand Down
3 changes: 2 additions & 1 deletion liblangutil/Scanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ class ParserRecorder;
enum class ScannerKind
{
Solidity,
Yul
Yul,
ExperimentalSolidity
};

enum class ScannerError
Expand Down
35 changes: 35 additions & 0 deletions liblangutil/Token.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ namespace solidity::langutil
/* Yul-specific tokens, but not keywords. */ \
T(Leave, "leave", 0) \
\
T(NonExperimentalEnd, nullptr, 0) /* used as non-experimental enum end marker */ \
T(ExperimentalEnd, nullptr, 0) /* used as experimental enum end marker */ \
/* Illegal token - not able to scan. */ \
T(Illegal, "ILLEGAL", 0) \
\
Expand Down Expand Up @@ -323,6 +325,39 @@ namespace TokenTraits
tok == Token::TrueLiteral || tok == Token::FalseLiteral || tok == Token::HexStringLiteral || tok == Token::Hex;
}

constexpr bool isExperimentalSolidityKeyword(Token token)
{
return
token == Token::Assembly ||
token == Token::Contract ||
token == Token::External ||
token == Token::Fallback ||
token == Token::Pragma ||
token == Token::Import ||
token == Token::As ||
token == Token::Function ||
token == Token::Let ||
token == Token::Return ||
token == Token::Type ||
token == Token::If ||
token == Token::Else ||
token == Token::Do ||
token == Token::While ||
token == Token::For ||
token == Token::Continue ||
token == Token::Break;
// TODO: see isExperimentalSolidityKeyword below
// || (token > Token::NonExperimentalEnd && token < Token::ExperimentalEnd);
}

constexpr bool isExperimentalSolidityOnlyKeyword(Token)
{
// TODO: use token > Token::NonExperimentalEnd && token < Token::ExperimentalEnd
// as soon as other experimental tokens are added. For now the comparison generates
// a warning from clang because it is always false.
return false;
}

bool isYulKeyword(std::string const& _literal);

Token AssignmentToBinaryOp(Token op);
Expand Down
3 changes: 2 additions & 1 deletion libsolidity/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ set(sources
codegen/ir/IRLValue.h
codegen/ir/IRVariable.cpp
codegen/ir/IRVariable.h
experimental/analysis/Analysis.cpp
experimental/analysis/Analysis.h
formal/ArraySlicePredicate.cpp
formal/ArraySlicePredicate.h
formal/BMC.cpp
Expand Down Expand Up @@ -186,4 +188,3 @@ set(sources

add_library(solidity ${sources})
target_link_libraries(solidity PUBLIC yul evmasm langutil smtutil solutil Boost::boost fmt::fmt-header-only Threads::Threads)

34 changes: 34 additions & 0 deletions libsolidity/experimental/analysis/Analysis.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
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/experimental/analysis/Analysis.h>

#include <liblangutil/ErrorReporter.h>

using namespace solidity::langutil;
using namespace solidity::frontend::experimental;

bool Analysis::check(std::vector<std::shared_ptr<SourceUnit const>> const&)
{
m_errorReporter.error(
6547_error,
Error::Type::UnimplementedFeatureError,
SourceLocation{},
"Experimental Analysis is not implemented yet."
);
return false;
}
49 changes: 49 additions & 0 deletions libsolidity/experimental/analysis/Analysis.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
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 <vector>
#include <memory>

namespace solidity::frontend
{
class SourceUnit;
}

namespace solidity::langutil
{
class ErrorReporter;
}

namespace solidity::frontend::experimental
{

class Analysis
{
public:
Analysis(langutil::ErrorReporter& _errorReporter):
m_errorReporter(_errorReporter)
{}

bool check(std::vector<std::shared_ptr<SourceUnit const>> const& _sourceUnits);

private:
langutil::ErrorReporter& m_errorReporter;
};

}
Loading

0 comments on commit 9bce5f9

Please sign in to comment.