|
@ -45,10 +45,14 @@ void CompilerStack::parse() |
|
|
{ |
|
|
{ |
|
|
if (!m_scanner) |
|
|
if (!m_scanner) |
|
|
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Source not available.")); |
|
|
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Source not available.")); |
|
|
m_contractASTNode = Parser().parse(m_scanner); |
|
|
m_sourceUnitASTNode = Parser().parse(m_scanner); |
|
|
m_globalContext = make_shared<GlobalContext>(); |
|
|
m_globalContext = make_shared<GlobalContext>(); |
|
|
m_globalContext->setCurrentContract(*m_contractASTNode); |
|
|
for (ASTPointer<ASTNode> const& node: m_sourceUnitASTNode->getNodes()) |
|
|
NameAndTypeResolver(m_globalContext->getDeclarations()).resolveNamesAndTypes(*m_contractASTNode); |
|
|
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) |
|
|
|
|
|
{ |
|
|
|
|
|
m_globalContext->setCurrentContract(*contract); |
|
|
|
|
|
NameAndTypeResolver(m_globalContext->getDeclarations()).resolveNamesAndTypes(*contract); |
|
|
|
|
|
} |
|
|
m_parseSuccessful = true; |
|
|
m_parseSuccessful = true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -62,10 +66,16 @@ bytes const& CompilerStack::compile(bool _optimize) |
|
|
{ |
|
|
{ |
|
|
if (!m_parseSuccessful) |
|
|
if (!m_parseSuccessful) |
|
|
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful.")); |
|
|
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful.")); |
|
|
m_bytecode.clear(); |
|
|
//@todo returns only the last contract for now
|
|
|
m_compiler = make_shared<Compiler>(); |
|
|
for (ASTPointer<ASTNode> const& node: m_sourceUnitASTNode->getNodes()) |
|
|
m_compiler->compileContract(*m_contractASTNode, m_globalContext->getMagicVariables()); |
|
|
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) |
|
|
return m_bytecode = m_compiler->getAssembledBytecode(_optimize); |
|
|
{ |
|
|
|
|
|
m_bytecode.clear(); |
|
|
|
|
|
m_compiler = make_shared<Compiler>(); |
|
|
|
|
|
m_compiler->compileContract(*contract, m_globalContext->getMagicVariables()); |
|
|
|
|
|
m_bytecode = m_compiler->getAssembledBytecode(_optimize); |
|
|
|
|
|
} |
|
|
|
|
|
return m_bytecode; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
bytes const& CompilerStack::compile(string const& _sourceCode, bool _optimize) |
|
|
bytes const& CompilerStack::compile(string const& _sourceCode, bool _optimize) |
|
@ -87,40 +97,45 @@ string const& CompilerStack::getInterface() |
|
|
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful.")); |
|
|
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful.")); |
|
|
if (m_interface.empty()) |
|
|
if (m_interface.empty()) |
|
|
{ |
|
|
{ |
|
|
stringstream interface; |
|
|
//@todo returns only the last contract for now
|
|
|
interface << '['; |
|
|
for (ASTPointer<ASTNode> const& node: m_sourceUnitASTNode->getNodes()) |
|
|
vector<FunctionDefinition const*> exportedFunctions = m_contractASTNode->getInterfaceFunctions(); |
|
|
if (ContractDefinition const* contract = dynamic_cast<ContractDefinition*>(node.get())) |
|
|
unsigned functionsCount = exportedFunctions.size(); |
|
|
|
|
|
for (FunctionDefinition const* f: exportedFunctions) |
|
|
|
|
|
{ |
|
|
|
|
|
auto streamVariables = [&](vector<ASTPointer<VariableDeclaration>> const& _vars) |
|
|
|
|
|
{ |
|
|
{ |
|
|
unsigned varCount = _vars.size(); |
|
|
stringstream interface; |
|
|
for (ASTPointer<VariableDeclaration> const& var: _vars) |
|
|
interface << '['; |
|
|
|
|
|
vector<FunctionDefinition const*> exportedFunctions = contract->getInterfaceFunctions(); |
|
|
|
|
|
unsigned functionsCount = exportedFunctions.size(); |
|
|
|
|
|
for (FunctionDefinition const* f: exportedFunctions) |
|
|
{ |
|
|
{ |
|
|
interface << "{" |
|
|
auto streamVariables = [&](vector<ASTPointer<VariableDeclaration>> const& _vars) |
|
|
<< "\"name\":" << escaped(var->getName(), false) << "," |
|
|
{ |
|
|
<< "\"type\":" << escaped(var->getType()->toString(), false) |
|
|
unsigned varCount = _vars.size(); |
|
|
|
|
|
for (ASTPointer<VariableDeclaration> const& var: _vars) |
|
|
|
|
|
{ |
|
|
|
|
|
interface << "{" |
|
|
|
|
|
<< "\"name\":" << escaped(var->getName(), false) << "," |
|
|
|
|
|
<< "\"type\":" << escaped(var->getType()->toString(), false) |
|
|
|
|
|
<< "}"; |
|
|
|
|
|
if (--varCount > 0) |
|
|
|
|
|
interface << ","; |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
interface << '{' |
|
|
|
|
|
<< "\"name\":" << escaped(f->getName(), false) << "," |
|
|
|
|
|
<< "\"inputs\":["; |
|
|
|
|
|
streamVariables(f->getParameters()); |
|
|
|
|
|
interface << "]," |
|
|
|
|
|
<< "\"outputs\":["; |
|
|
|
|
|
streamVariables(f->getReturnParameters()); |
|
|
|
|
|
interface << "]" |
|
|
<< "}"; |
|
|
<< "}"; |
|
|
if (--varCount > 0) |
|
|
if (--functionsCount > 0) |
|
|
interface << ","; |
|
|
interface << ","; |
|
|
} |
|
|
} |
|
|
}; |
|
|
interface << ']'; |
|
|
|
|
|
m_interface = interface.str(); |
|
|
interface << '{' |
|
|
} |
|
|
<< "\"name\":" << escaped(f->getName(), false) << "," |
|
|
|
|
|
<< "\"inputs\":["; |
|
|
|
|
|
streamVariables(f->getParameters()); |
|
|
|
|
|
interface << "]," |
|
|
|
|
|
<< "\"outputs\":["; |
|
|
|
|
|
streamVariables(f->getReturnParameters()); |
|
|
|
|
|
interface << "]" |
|
|
|
|
|
<< "}"; |
|
|
|
|
|
if (--functionsCount > 0) |
|
|
|
|
|
interface << ","; |
|
|
|
|
|
} |
|
|
|
|
|
interface << ']'; |
|
|
|
|
|
m_interface = interface.str(); |
|
|
|
|
|
} |
|
|
} |
|
|
return m_interface; |
|
|
return m_interface; |
|
|
} |
|
|
} |
|
|