diff --git a/solc/main.cpp b/solc/main.cpp index c79ba52a6..96e834ff1 100644 --- a/solc/main.cpp +++ b/solc/main.cpp @@ -53,23 +53,28 @@ void version() exit(0); } -enum class AstOutput +enum class OutputType { STDOUT, FILE, BOTH }; -std::istream& operator>>(std::istream& _in, AstOutput& io_output) +#define outputTypeStr "Legal values:\n"\ + "\tstdout: Print it to standard output\n"\ + "\tfile: Print it to a file with same name\n"\ + "\tboth: Print both to a file and the stdout\n" + +std::istream& operator>>(std::istream& _in, OutputType& io_output) { std::string token; _in >> token; if (token == "stdout") - io_output = AstOutput::STDOUT; + io_output = OutputType::STDOUT; else if (token == "file") - io_output = AstOutput::FILE; + io_output = OutputType::FILE; else if (token == "both") - io_output = AstOutput::BOTH; + io_output = OutputType::BOTH; else throw boost::program_options::invalid_option_value(token); return _in; @@ -84,10 +89,10 @@ int main(int argc, char** argv) ("version", "Show version and exit") ("optimize", po::value()->default_value(false), "Optimize bytecode for size") ("input-file", po::value>(), "input file") - ("ast", po::value(), - "Request to output the AST of the contract. Legal values:\n" - "\tstdout: Print it to standar output\n" - "\tfile: Print it to a file with same name\n"); + ("ast", po::value(), + "Request to output the AST of the contract. " outputTypeStr) + ("asm", po::value(), + "Request to output the EVM assembly of the contract. " outputTypeStr); // All positional options should be interpreted as input files po::positional_options_description p; @@ -176,8 +181,8 @@ int main(int argc, char** argv) // do we need AST output? if (vm.count("ast")) { - auto choice = vm["ast"].as(); - if (choice != AstOutput::FILE) + auto choice = vm["ast"].as(); + if (choice != OutputType::FILE) { cout << "Syntax trees:" << endl << endl; for (auto const& sourceCode: sourceCodes) @@ -188,7 +193,7 @@ int main(int argc, char** argv) } } - if (choice != AstOutput::STDOUT) + if (choice != OutputType::STDOUT) { for (auto const& sourceCode: sourceCodes) { @@ -201,14 +206,33 @@ int main(int argc, char** argv) } } - vector contracts = compiler.getContractNames(); + // do we need EVM assembly? + if (vm.count("asm")) + { + auto choice = vm["asm"].as(); + for (string const& contract: contracts) + { + if (choice != OutputType::FILE) + { + cout << endl << "======= " << contract << " =======" << endl + << "EVM assembly:" << endl; + compiler.streamAssembly(cout, contract); + } + + if (choice != OutputType::STDOUT) + { + ofstream outFile(contract + ".evm"); + compiler.streamAssembly(outFile, contract); + outFile.close(); + } + } + } + + cout << endl << "Contracts:" << endl; for (string const& contract: contracts) { - cout << endl << "======= " << contract << " =======" << endl - << "EVM assembly:" << endl; - compiler.streamAssembly(cout, contract); cout << "Opcodes:" << endl << eth::disassemble(compiler.getBytecode(contract)) << endl << "Binary: " << toHex(compiler.getBytecode(contract)) << endl