Provide access to AssemblyStack's AST.

This commit is contained in:
chriseth 2019-02-13 12:21:53 +01:00
parent 10888b21d8
commit a344381d5e
4 changed files with 30 additions and 52 deletions

View File

@ -178,3 +178,11 @@ string AssemblyStack::print() const
solAssert(m_parserResult->code, "");
return m_parserResult->toString(m_language == Language::Yul) + "\n";
}
shared_ptr<Object> AssemblyStack::parserResult() const
{
solAssert(m_analysisSuccessful, "Analysis was not successful.");
solAssert(m_parserResult, "");
solAssert(m_parserResult->code, "");
return m_parserResult;
}

View File

@ -82,6 +82,9 @@ public:
/// Pretty-print the input after having parsed it.
std::string print() const;
/// Return the parsed and analyzed object.
std::shared_ptr<Object> parserResult() const;
private:
bool analyzeParsed();
bool analyzeParsed(yul::Object& _object);

View File

@ -29,6 +29,7 @@
#include <libyul/AsmParser.h>
#include <libyul/AsmAnalysis.h>
#include <libyul/AsmPrinter.h>
#include <libyul/AssemblyStack.h>
#include <libyul/backends/evm/EVMDialect.h>
#include <liblangutil/Scanner.h>
@ -63,33 +64,13 @@ void yul::test::printErrors(ErrorList const& _errors)
pair<shared_ptr<Block>, shared_ptr<yul::AsmAnalysisInfo>> yul::test::parse(string const& _source, bool _yul)
{
shared_ptr<Dialect> dialect = defaultDialect(_yul);
ErrorList errors;
ErrorReporter errorReporter(errors);
auto scanner = make_shared<Scanner>(CharStream(_source, ""));
auto parserResult = yul::Parser(errorReporter, dialect).parse(scanner, false);
if (parserResult)
{
BOOST_REQUIRE(errorReporter.errors().empty());
auto analysisInfo = make_shared<yul::AsmAnalysisInfo>();
yul::AsmAnalyzer analyzer(
*analysisInfo,
errorReporter,
AssemblyStack stack(
dev::test::Options::get().evmVersion(),
boost::none,
dialect
_yul ? AssemblyStack::Language::Yul : AssemblyStack::Language::StrictAssembly
);
if (analyzer.analyze(*parserResult))
{
BOOST_REQUIRE(errorReporter.errors().empty());
return make_pair(parserResult, analysisInfo);
}
}
printErrors(errors);
if (!stack.parseAndAnalyze("", _source) || !stack.errors().empty())
BOOST_FAIL("Invalid source.");
// Unreachable.
return {};
return make_pair(stack.parserResult()->code, stack.parserResult()->analysisInfo);
}
yul::Block yul::test::disambiguate(string const& _source, bool _yul)

View File

@ -46,6 +46,7 @@
#include <libyul/AsmPrinter.h>
#include <libyul/AsmParser.h>
#include <libyul/AsmAnalysis.h>
#include <libyul/AssemblyStack.h>
#include <liblangutil/SourceReferenceFormatter.h>
#include <liblangutil/ErrorReporter.h>
@ -97,9 +98,6 @@ YulOptimizerTest::YulOptimizerTest(string const& _filename)
bool YulOptimizerTest::run(ostream& _stream, string const& _linePrefix, bool const _formatted)
{
yul::AsmPrinter printer{m_yul};
shared_ptr<Block> ast;
shared_ptr<yul::AsmAnalysisInfo> analysisInfo;
if (!parse(_stream, _linePrefix, _formatted))
return false;
@ -257,7 +255,7 @@ bool YulOptimizerTest::run(ostream& _stream, string const& _linePrefix, bool con
return false;
}
m_obtainedResult = m_optimizerStep + "\n" + printer(*m_ast) + "\n";
m_obtainedResult = m_optimizerStep + "\n" + AsmPrinter{m_yul}(*m_ast) + "\n";
if (m_expectation != m_obtainedResult)
{
@ -292,31 +290,19 @@ void YulOptimizerTest::printIndented(ostream& _stream, string const& _output, st
bool YulOptimizerTest::parse(ostream& _stream, string const& _linePrefix, bool const _formatted)
{
m_dialect = m_yul ? yul::Dialect::yul() : yul::EVMDialect::strictAssemblyForEVMObjects();
ErrorList errors;
ErrorReporter errorReporter(errors);
shared_ptr<Scanner> scanner = make_shared<Scanner>(CharStream(m_source, ""));
m_ast = yul::Parser(errorReporter, m_dialect).parse(scanner, false);
if (!m_ast || !errorReporter.errors().empty())
AssemblyStack stack(
dev::test::Options::get().evmVersion(),
m_yul ? AssemblyStack::Language::Yul : AssemblyStack::Language::StrictAssembly
);
if (!stack.parseAndAnalyze("", m_source) || !stack.errors().empty())
{
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << endl;
printErrors(_stream, errorReporter.errors());
return false;
}
m_analysisInfo = make_shared<yul::AsmAnalysisInfo>();
yul::AsmAnalyzer analyzer(
*m_analysisInfo,
errorReporter,
dev::test::Options::get().evmVersion(),
boost::none,
m_dialect
);
if (!analyzer.analyze(*m_ast) || !errorReporter.errors().empty())
{
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error analyzing source." << endl;
printErrors(_stream, errorReporter.errors());
printErrors(_stream, stack.errors());
return false;
}
m_dialect = m_yul ? Dialect::yul() : EVMDialect::strictAssemblyForEVMObjects();
m_ast = stack.parserResult()->code;
m_analysisInfo = stack.parserResult()->analysisInfo;
return true;
}