diff options
author | Christian <c@ethdev.com> | 2014-12-03 14:46:55 +0800 |
---|---|---|
committer | Christian <c@ethdev.com> | 2014-12-03 17:44:46 +0800 |
commit | 5b6a211b8aea80fc857e043fe5eb33f43c3f7df4 (patch) | |
tree | 3f50bd614fff7fcf75c71f82a82733d4dfc4ef82 | |
parent | e7201a032429534b4cde33c21c00777c04448b15 (diff) | |
download | dexon-solidity-5b6a211b8aea80fc857e043fe5eb33f43c3f7df4.tar.gz dexon-solidity-5b6a211b8aea80fc857e043fe5eb33f43c3f7df4.tar.zst dexon-solidity-5b6a211b8aea80fc857e043fe5eb33f43c3f7df4.zip |
Import directive.
-rw-r--r-- | solidityCompiler.cpp | 26 | ||||
-rw-r--r-- | solidityExpressionCompiler.cpp | 47 | ||||
-rw-r--r-- | solidityNameAndTypeResolution.cpp | 11 | ||||
-rw-r--r-- | solidityParser.cpp | 55 |
4 files changed, 102 insertions, 37 deletions
diff --git a/solidityCompiler.cpp b/solidityCompiler.cpp index 3e86919a..883cecf2 100644 --- a/solidityCompiler.cpp +++ b/solidityCompiler.cpp @@ -46,16 +46,22 @@ namespace bytes compileContract(const string& _sourceCode) { Parser parser; - ASTPointer<ContractDefinition> contract; - BOOST_REQUIRE_NO_THROW(contract = parser.parse(make_shared<Scanner>(CharStream(_sourceCode)))); - NameAndTypeResolver resolver({}); - BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract)); - - Compiler compiler; - compiler.compileContract(*contract, {}); - // debug - //compiler.streamAssembly(cout); - return compiler.getAssembledBytecode(); + ASTPointer<SourceUnit> sourceUnit; + BOOST_REQUIRE_NO_THROW(sourceUnit = parser.parse(make_shared<Scanner>(CharStream(_sourceCode)))); + for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes()) + if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) + { + NameAndTypeResolver resolver({}); + BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract)); + + Compiler compiler; + compiler.compileContract(*contract, {}); + // debug + //compiler.streamAssembly(cout); + return compiler.getAssembledBytecode(); + } + BOOST_FAIL("No contract found in source."); + return bytes(); } /// Checks that @a _compiledCode is present starting from offset @a _offset in @a _expectation. diff --git a/solidityExpressionCompiler.cpp b/solidityExpressionCompiler.cpp index 6ea66bad..b077e262 100644 --- a/solidityExpressionCompiler.cpp +++ b/solidityExpressionCompiler.cpp @@ -86,27 +86,32 @@ bytes compileFirstExpression(const string& _sourceCode, vector<vector<string>> _ vector<vector<string>> _localVariables = {}) { Parser parser; - ASTPointer<ContractDefinition> contract; - BOOST_REQUIRE_NO_THROW(contract = parser.parse(make_shared<Scanner>(CharStream(_sourceCode)))); - NameAndTypeResolver resolver({}); - BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract)); - FirstExpressionExtractor extractor(*contract); - BOOST_REQUIRE(extractor.getExpression() != nullptr); - - CompilerContext context; - for (vector<string> const& function: _functions) - context.addFunction(dynamic_cast<FunctionDefinition const&>(resolveDeclaration(function, resolver))); - for (vector<string> const& variable: _localVariables) - context.addVariable(dynamic_cast<VariableDeclaration const&>(resolveDeclaration(variable, resolver))); - - ExpressionCompiler::compileExpression(context, *extractor.getExpression()); - - for (vector<string> const& function: _functions) - context << context.getFunctionEntryLabel(dynamic_cast<FunctionDefinition const&>(resolveDeclaration(function, resolver))); - bytes instructions = context.getAssembledBytecode(); - // debug - // cout << eth::disassemble(instructions) << endl; - return instructions; + ASTPointer<SourceUnit> sourceUnit; + BOOST_REQUIRE_NO_THROW(sourceUnit = parser.parse(make_shared<Scanner>(CharStream(_sourceCode)))); + for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes()) + if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) + { + NameAndTypeResolver resolver({}); + BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract)); + FirstExpressionExtractor extractor(*contract); + BOOST_REQUIRE(extractor.getExpression() != nullptr); + + CompilerContext context; + for (vector<string> const& function: _functions) + context.addFunction(dynamic_cast<FunctionDefinition const&>(resolveDeclaration(function, resolver))); + for (vector<string> const& variable: _localVariables) + context.addVariable(dynamic_cast<VariableDeclaration const&>(resolveDeclaration(variable, resolver))); + + ExpressionCompiler::compileExpression(context, *extractor.getExpression()); + + for (vector<string> const& function: _functions) + context << context.getFunctionEntryLabel(dynamic_cast<FunctionDefinition const&>(resolveDeclaration(function, resolver))); + bytes instructions = context.getAssembledBytecode(); + // debug + // cout << eth::disassemble(instructions) << endl; + return instructions; + } + BOOST_FAIL("No contract found in source."); } } // end anonymous namespace diff --git a/solidityNameAndTypeResolution.cpp b/solidityNameAndTypeResolution.cpp index 8804c519..219fa259 100644 --- a/solidityNameAndTypeResolution.cpp +++ b/solidityNameAndTypeResolution.cpp @@ -41,10 +41,13 @@ namespace void parseTextAndResolveNames(std::string const& _source) { Parser parser; - ASTPointer<ContractDefinition> contract = parser.parse( - std::make_shared<Scanner>(CharStream(_source))); - NameAndTypeResolver resolver({}); - resolver.resolveNamesAndTypes(*contract); + ASTPointer<SourceUnit> sourceUnit = parser.parse(std::make_shared<Scanner>(CharStream(_source))); + for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes()) + if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) + { + NameAndTypeResolver resolver({}); + resolver.resolveNamesAndTypes(*contract); + } } } diff --git a/solidityParser.cpp b/solidityParser.cpp index 6a97a5d9..a9e2d531 100644 --- a/solidityParser.cpp +++ b/solidityParser.cpp @@ -21,13 +21,15 @@ */ #include <string> - +#include <memory> #include <libdevcore/Log.h> #include <libsolidity/Scanner.h> #include <libsolidity/Parser.h> #include <libsolidity/Exceptions.h> #include <boost/test/unit_test.hpp> +using namespace std; + namespace dev { namespace solidity @@ -40,7 +42,12 @@ namespace ASTPointer<ContractDefinition> parseText(std::string const& _source) { Parser parser; - return parser.parse(std::make_shared<Scanner>(CharStream(_source))); + ASTPointer<SourceUnit> sourceUnit = parser.parse(std::make_shared<Scanner>(CharStream(_source))); + for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes()) + if (ASTPointer<ContractDefinition> contract = dynamic_pointer_cast<ContractDefinition>(node)) + return contract; + BOOST_FAIL("No contract found in source."); + return ASTPointer<ContractDefinition>(); } } @@ -380,6 +387,50 @@ BOOST_AUTO_TEST_CASE(statement_starting_with_type_conversion) BOOST_CHECK_NO_THROW(parseText(text)); } +BOOST_AUTO_TEST_CASE(import_directive) +{ + char const* text = "import \"abc\";\n" + "contract test {\n" + " function fun() {\n" + " uint64(2);\n" + " }\n" + "}\n"; + BOOST_CHECK_NO_THROW(parseText(text)); +} + +BOOST_AUTO_TEST_CASE(multiple_contracts) +{ + char const* text = "contract test {\n" + " function fun() {\n" + " uint64(2);\n" + " }\n" + "}\n" + "contract test2 {\n" + " function fun() {\n" + " uint64(2);\n" + " }\n" + "}\n"; + BOOST_CHECK_NO_THROW(parseText(text)); +} + +BOOST_AUTO_TEST_CASE(multiple_contracts_and_imports) +{ + char const* text = "import \"abc\";\n" + "contract test {\n" + " function fun() {\n" + " uint64(2);\n" + " }\n" + "}\n" + "import \"def\";\n" + "contract test2 {\n" + " function fun() {\n" + " uint64(2);\n" + " }\n" + "}\n" + "import \"ghi\";\n"; + BOOST_CHECK_NO_THROW(parseText(text)); +} + BOOST_AUTO_TEST_SUITE_END() } |