diff options
author | Christian <c@ethdev.com> | 2015-01-28 20:39:04 +0800 |
---|---|---|
committer | Christian <c@ethdev.com> | 2015-01-28 20:39:04 +0800 |
commit | 95d8d7b1f00d3521d20a3735472e359d03d71816 (patch) | |
tree | 0662c5bed06b9cdffae7bc90d1f9466534f59c9c | |
parent | 34d07fc5837745ee3c8fbc571d0e2f0d02041cf1 (diff) | |
download | dexon-solidity-95d8d7b1f00d3521d20a3735472e359d03d71816.tar dexon-solidity-95d8d7b1f00d3521d20a3735472e359d03d71816.tar.gz dexon-solidity-95d8d7b1f00d3521d20a3735472e359d03d71816.tar.bz2 dexon-solidity-95d8d7b1f00d3521d20a3735472e359d03d71816.tar.lz dexon-solidity-95d8d7b1f00d3521d20a3735472e359d03d71816.tar.xz dexon-solidity-95d8d7b1f00d3521d20a3735472e359d03d71816.tar.zst dexon-solidity-95d8d7b1f00d3521d20a3735472e359d03d71816.zip |
Cleaner solution to provide standard sources.
-rw-r--r-- | AST.cpp | 3 | ||||
-rw-r--r-- | CompilerStack.cpp | 88 | ||||
-rw-r--r-- | CompilerStack.h | 10 |
3 files changed, 32 insertions, 69 deletions
@@ -414,8 +414,7 @@ void FunctionCall::checkTypeRequirements() //@todo for structs, we have to check the number of arguments to be equal to the // number of non-mapping members if (m_arguments.size() != 1) - BOOST_THROW_EXCEPTION(createTypeError("More than one argument for " - "explicit type conersion.")); + BOOST_THROW_EXCEPTION(createTypeError("More than one argument for explicit type conversion.")); if (!m_arguments.front()->getType()->isExplicitlyConvertibleTo(*type.getActualType())) BOOST_THROW_EXCEPTION(createTypeError("Explicit type conversion not allowed.")); m_type = type.getActualType(); diff --git a/CompilerStack.cpp b/CompilerStack.cpp index 2917a382..044e0dea 100644 --- a/CompilerStack.cpp +++ b/CompilerStack.cpp @@ -40,18 +40,39 @@ namespace dev namespace solidity { +const map<string, string> StandardSources = map<string, string>{ + {"coin", R"(import "CoinReg";import "Config";import "configUser";contract coin is configUser{function coin(string3 name, uint denom) {CoinReg(Config(configAddr()).lookup(3)).register(name, denom);}})"}, + {"Coin", R"(contract Coin{function isApprovedFor(address _target,address _proxy)constant returns(bool _r){}function isApproved(address _proxy)constant returns(bool _r){}function sendCoinFrom(address _from,uint256 _val,address _to){}function coinBalanceOf(address _a)constant returns(uint256 _r){}function sendCoin(uint256 _val,address _to){}function coinBalance()constant returns(uint256 _r){}function approve(address _a){}})"}, + {"CoinReg", R"(contract CoinReg{function count()constant returns(uint256 r){}function info(uint256 i)constant returns(address addr,string3 name,uint256 denom){}function register(string3 name,uint256 denom){}function unregister(){}})"}, + {"configUser", R"(contract configUser{function configAddr()constant returns(address a){ return 0xc6d9d2cd449a754c494264e1809c50e34d64562b;}})"}, + {"Config", R"(contract Config{function lookup(uint256 service)constant returns(address a){}function kill(){}function unregister(uint256 id){}function register(uint256 id,address service){}})"}, + {"mortal", R"(import "owned";contract mortal is owned {function kill() { if (msg.sender == owner) suicide(owner); }})"}, + {"named", R"(import "Config";import "NameReg";import "configUser";contract named is configUser {function named(string32 name) {NameReg(Config(configAddr()).lookup(1)).register(name);}})"}, + {"NameReg", R"(contract NameReg{function register(string32 name){}function addressOf(string32 name)constant returns(address addr){}function unregister(){}function nameOf(address addr)constant returns(string32 name){}})"}, + {"owned", R"(contract owned{function owned(){owner = msg.sender;}modifier onlyowner(){if(msg.sender==owner)_}address owner;})"}, + {"service", R"(import "Config";import "configUser";contract service is configUser{function service(uint _n){Config(configAddr()).register(_n, this);}})"}, + {"std", R"(import "owned";import "mortal";import "Config";import "configUser";import "NameReg";import "named";)"} +}; + +CompilerStack::CompilerStack(bool _addStandardSources): + m_addStandardSources(_addStandardSources), m_parseSuccessful(false) +{ + if (m_addStandardSources) + addSources(StandardSources); +} + bool CompilerStack::addSource(string const& _name, string const& _content) { bool existed = m_sources.count(_name) != 0; reset(true); - m_sources[_name].scanner = make_shared<Scanner>(CharStream(expanded(_content)), _name); + m_sources[_name].scanner = make_shared<Scanner>(CharStream(_content), _name); return existed; } void CompilerStack::setSource(string const& _sourceCode) { reset(); - addSource("", expanded(_sourceCode)); + addSource("", _sourceCode); } void CompilerStack::parse() @@ -91,7 +112,6 @@ void CompilerStack::parse() void CompilerStack::parse(string const& _sourceCode) { setSource(_sourceCode); - addSources(StandardSources); parse(); } @@ -125,64 +145,6 @@ void CompilerStack::compile(bool _optimize) } } -const map<string, string> StandardSources = map<string, string>{ -/* { "Config", "contract Config{function lookup(uint256 service)constant returns(address a){}function kill(){}function unregister(uint256 id){}function register(uint256 id,address service){}}" }, - { "owned", "contract owned{function owned(){owner = msg.sender;}address owner;}" }, - { "mortal", "import \"owned\";\ncontract mortal is owned {function kill() { if (msg.sender == owner) suicide(owner); }}" }, - { "NameReg", "contract NameReg{function register(string32 name){}function addressOf(string32 name)constant returns(address addr){}function unregister(){}function nameOf(address addr)constant returns(string32 name){}}" }, - { "named", "import \"Config\";\nimport \"NameReg\";\ncontract named {function named(string32 name) {NameReg(Config().lookup(1)).register(name);}}" }, - { "std", "import \"owned\";\nimport \"mortal\";\nimport \"Config\";\nimport \"NameReg\";\nimport \"named\";\n" }, -*/}; - -////// BEGIN: TEMPORARY ONLY -/// remove once import works properly and we have genesis contracts - -string CompilerStack::expanded(string const& _sourceCode) -{ - const map<string, string> c_standardSources = map<string, string>{ - { "Config", "contract Config{function lookup(uint256 service)constant returns(address a){}function kill(){}function unregister(uint256 id){}function register(uint256 id,address service){}}" }, - { "Coin", "contract Coin{function isApprovedFor(address _target,address _proxy)constant returns(bool _r){}function isApproved(address _proxy)constant returns(bool _r){}function sendCoinFrom(address _from,uint256 _val,address _to){}function coinBalanceOf(address _a)constant returns(uint256 _r){}function sendCoin(uint256 _val,address _to){}function coinBalance()constant returns(uint256 _r){}function approve(address _a){}}"}, - { "CoinReg", "contract CoinReg{function count()constant returns(uint256 r){}function info(uint256 i)constant returns(address addr,string3 name,uint256 denom){}function register(string3 name,uint256 denom){}function unregister(){}}" }, - { "coin", "#require CoinReg\ncontract coin {function coin(string3 name, uint denom) {CoinReg(Config().lookup(3)).register(name, denom);}}" }, - { "service", "#require Config\ncontract service{function service(uint _n){Config().register(_n, this);}}" }, - { "owned", "contract owned{function owned(){owner = msg.sender;}modifier onlyowner(){if(msg.sender==owner)_}address owner;}" }, - { "mortal", "#require owned\ncontract mortal is owned {function kill() { if (msg.sender == owner) suicide(owner); }}" }, - { "NameReg", "contract NameReg{function register(string32 name){}function addressOf(string32 name)constant returns(address addr){}function unregister(){}function nameOf(address addr)constant returns(string32 name){}}" }, - { "named", "#require Config NameReg\ncontract named {function named(string32 name) {NameReg(Config().lookup(1)).register(name);}}" }, - { "std", "#require owned mortal Config NameReg named" }, - }; - - string sub; - set<string> got; - function<string(string const&)> localExpanded; - localExpanded = [&](string const& s) -> string - { - string ret = s; - for (size_t p = 0; p != string::npos;) - if ((p = ret.find("#require ")) != string::npos) - { - string n = ret.substr(p + 9, ret.find_first_of('\n', p + 9) - p - 9); - ret.replace(p, n.size() + 9, ""); - vector<string> rs; - boost::split(rs, n, boost::is_any_of(" \t,"), boost::token_compress_on); - for (auto const& r: rs) - if (!got.count(r)) - { - if (c_standardSources.count(r)) - sub.append("\n" + localExpanded(c_standardSources.at(r)) + "\n"); - got.insert(r); - } - } - // TODO: remove once we have genesis contracts. - else if ((p = ret.find("Config()")) != string::npos) - ret.replace(p, 8, "Config(0xc6d9d2cd449a754c494264e1809c50e34d64562b)"); - return ret; - }; - return sub + localExpanded(_sourceCode); -} - -////// END: TEMPORARY ONLY - bytes const& CompilerStack::compile(string const& _sourceCode, bool _optimize) { parse(_sourceCode); @@ -278,7 +240,11 @@ void CompilerStack::reset(bool _keepSources) for (auto sourcePair: m_sources) sourcePair.second.reset(); else + { m_sources.clear(); + if (m_addStandardSources) + addSources(StandardSources); + } m_globalContext.reset(); m_sourceOrder.clear(); m_contracts.clear(); diff --git a/CompilerStack.h b/CompilerStack.h index 09a1ad34..cae0f4e2 100644 --- a/CompilerStack.h +++ b/CompilerStack.h @@ -59,7 +59,8 @@ extern const std::map<std::string, std::string> StandardSources; class CompilerStack: boost::noncopyable { public: - CompilerStack(): m_parseSuccessful(false) {} + /// Creates a new compiler stack. Adds standard sources if @a _addStandardSources. + explicit CompilerStack(bool _addStandardSources = true); /// Adds a source object (e.g. file) to the parser. After this, parse has to be called again. /// @returns true if a source object by the name already existed and was replaced. @@ -68,7 +69,7 @@ public: void setSource(std::string const& _sourceCode); /// Parses all source units that were added void parse(); - /// Sets the given source code as the only source unit and parses it. + /// Sets the given source code as the only source unit apart from standard sources and parses it. void parse(std::string const& _sourceCode); /// Returns a list of the contract names in the sources. std::vector<std::string> getContractNames() const; @@ -141,16 +142,13 @@ private: Contract(); }; - /// Expand source code with preprocessor-like includes. - /// @todo Replace with better framework. - std::string expanded(std::string const& _sourceCode); - void reset(bool _keepSources = false); void resolveImports(); Contract const& getContract(std::string const& _contractName = "") const; Source const& getSource(std::string const& _sourceName = "") const; + bool m_addStandardSources; ///< If true, standard sources are added. bool m_parseSuccessful; std::map<std::string const, Source> m_sources; std::shared_ptr<GlobalContext> m_globalContext; |