Parsing for inline assembly.

This commit is contained in:
chriseth
2016-03-30 02:37:00 +02:00
parent 8236732e9a
commit 949b00ed59
19 changed files with 630 additions and 16 deletions
+44 -4
View File
@@ -45,6 +45,7 @@
#include <libsolidity/interface/CompilerStack.h>
#include <libsolidity/interface/SourceReferenceFormatter.h>
#include <libsolidity/interface/GasEstimator.h>
#include <libsolidity/inlineasm/AsmParser.h>
#include <libsolidity/formal/Why3Translator.h>
using namespace std;
@@ -430,6 +431,10 @@ Allowed options)",
"Output a single json document containing the specified information."
)
(g_argGas.c_str(), "Print an estimate of the maximal gas usage for each function.")
(
"assemble",
"Switch to assembly mode, ignoring all options and assumes input is assembly."
)
(
"link",
"Switch to linker mode, ignoring all options apart from --libraries "
@@ -509,6 +514,12 @@ bool CommandLineInterface::processInput()
if (!parseLibraryOption(library))
return false;
if (m_args.count("assemble"))
{
// switch to assembly mode
m_onlyAssemble = true;
return assemble();
}
if (m_args.count("link"))
{
// switch to linker mode
@@ -574,6 +585,7 @@ bool CommandLineInterface::processInput()
};
m_compiler.reset(new CompilerStack(m_args.count(g_argAddStandard) > 0, fileReader));
auto scannerFromSourceName = [&](string const& _sourceName) -> solidity::Scanner const& { return m_compiler->scanner(_sourceName); };
try
{
for (auto const& sourceCode: m_sourceCodes)
@@ -593,7 +605,8 @@ bool CommandLineInterface::processInput()
SourceReferenceFormatter::printExceptionInformation(
cerr,
*error,
(error->type() == Error::Type::Warning) ? "Warning" : "Error", *m_compiler
(error->type() == Error::Type::Warning) ? "Warning" : "Error",
scannerFromSourceName
);
if (!successful)
@@ -601,7 +614,7 @@ bool CommandLineInterface::processInput()
}
catch (CompilerError const& _exception)
{
SourceReferenceFormatter::printExceptionInformation(cerr, _exception, "Compiler error", *m_compiler);
SourceReferenceFormatter::printExceptionInformation(cerr, _exception, "Compiler error", scannerFromSourceName);
return false;
}
catch (InternalCompilerError const& _exception)
@@ -615,7 +628,7 @@ bool CommandLineInterface::processInput()
if (_error.type() == Error::Type::DocstringParsingError)
cerr << "Documentation parsing error: " << *boost::get_error_info<errinfo_comment>(_error) << endl;
else
SourceReferenceFormatter::printExceptionInformation(cerr, _error, _error.typeName(), *m_compiler);
SourceReferenceFormatter::printExceptionInformation(cerr, _error, _error.typeName(), scannerFromSourceName);
return false;
}
@@ -759,7 +772,9 @@ void CommandLineInterface::handleAst(string const& _argStr)
void CommandLineInterface::actOnInput()
{
if (m_onlyLink)
if (m_onlyAssemble)
return; //@TODO
else if (m_onlyLink)
writeLinkedFiles();
else
outputCompilationResults();
@@ -812,6 +827,31 @@ void CommandLineInterface::writeLinkedFiles()
writeFile(src.first, src.second);
}
bool CommandLineInterface::assemble()
{
//@TODO later, we will use the convenience interface and should also remove the include above
bool successful = true;
ErrorList errors;
map<string, shared_ptr<Scanner>> scanners;
for (auto const& src: m_sourceCodes)
{
auto scanner = make_shared<Scanner>(CharStream(src.second), src.first);
scanners[src.first] = scanner;
InlineAssemblyParser parser(errors);
if (!parser.parse(scanner))
successful = false;
}
for (auto const& error: errors)
SourceReferenceFormatter::printExceptionInformation(
cerr,
*error,
(error->type() == Error::Type::Warning) ? "Warning" : "Error",
[&](string const& _source) -> Scanner const& { return *scanners.at(_source); }
);
return successful;
}
void CommandLineInterface::outputCompilationResults()
{
handleCombinedJSON();
+4
View File
@@ -50,6 +50,9 @@ private:
bool link();
void writeLinkedFiles();
/// Parse assembly input.
bool assemble();
void outputCompilationResults();
void handleCombinedJSON();
@@ -73,6 +76,7 @@ private:
/// @arg _data to be written
void createFile(std::string const& _fileName, std::string const& _data);
bool m_onlyAssemble = false;
bool m_onlyLink = false;
/// Compiler arguments variable map
+12 -6
View File
@@ -21,6 +21,7 @@
*/
#include <string>
#include <functional>
#include <iostream>
#include <json/json.h>
#include <libdevcore/Common.h>
@@ -47,10 +48,14 @@ extern "C" {
typedef void (*CStyleReadFileCallback)(char const* _path, char** o_contents, char** o_error);
}
string formatError(Exception const& _exception, string const& _name, CompilerStack const& _compiler)
string formatError(
Exception const& _exception,
string const& _name,
function<Scanner const&(string const&)> const& _scannerFromSourceName
)
{
ostringstream errorOutput;
SourceReferenceFormatter::printExceptionInformation(errorOutput, _exception, _name, _compiler);
SourceReferenceFormatter::printExceptionInformation(errorOutput, _exception, _name, _scannerFromSourceName);
return errorOutput.str();
}
@@ -150,6 +155,7 @@ string compile(StringMap const& _sources, bool _optimize, CStyleReadFileCallback
};
}
CompilerStack compiler(true, readCallback);
auto scannerFromSourceName = [&](string const& _sourceName) -> solidity::Scanner const& { return compiler.scanner(_sourceName); };
bool success = false;
try
{
@@ -161,22 +167,22 @@ string compile(StringMap const& _sources, bool _optimize, CStyleReadFileCallback
errors.append(formatError(
*error,
(err->type() == Error::Type::Warning) ? "Warning" : "Error",
compiler
scannerFromSourceName
));
}
success = succ; // keep success false on exception
}
catch (Error const& error)
{
errors.append(formatError(error, error.typeName(), compiler));
errors.append(formatError(error, error.typeName(), scannerFromSourceName));
}
catch (CompilerError const& exception)
{
errors.append(formatError(exception, "Compiler error", compiler));
errors.append(formatError(exception, "Compiler error", scannerFromSourceName));
}
catch (InternalCompilerError const& exception)
{
errors.append(formatError(exception, "Internal compiler error", compiler));
errors.append(formatError(exception, "Internal compiler error", scannerFromSourceName));
}
catch (Exception const& exception)
{