diff --git a/CMakeLists.txt b/CMakeLists.txt index a2d4a48ef..9fafcb9ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,26 +10,26 @@ set(LANGUAGES CACHE BOOL 0) if ("x${PARANOIA}" STREQUAL "x") if ("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug") - set(PARANOIA 1) + set(PARANOIA CACHE BOOL 1) else () - set(PARANOIA 0) + set(PARANOIA CACHE BOOL 0) endif () endif () -if (PARANOIA) - add_definitions(-DETH_PARANOIA) -endif () - if ("x${VMTRACE}" STREQUAL "x") if ("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug") - set(VMTRACE 1) + set(VMTRACE CACHE BOOL 1) else () - set(VMTRACE 0) + set(VMTRACE CACHE BOOL 0) endif () endif () +if (PARANOIA) + add_definitions(-DETH_PARANOIA) +endif () + if (VMTRACE) - add_definitions(-DETH_VMTRACE) + add_definitions(-DETH_VMTRACE) endif () if (LANGUAGES) @@ -87,11 +87,11 @@ else () endif () # Initialize CXXFLAGS. -set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra") -set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g") -set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG") -set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g") +set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -fPIC -DSHAREDLIB") +set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG") +set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE") +set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG -DETH_RELEASE") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG") #add_definitions("-DETH_BUILD_TYPE=${ETH_BUILD_TYPE}") #add_definitions("-DETH_BUILD_PLATFORM=${ETH_BUILD_PLATFORM}") @@ -160,43 +160,56 @@ else () # Always "found", given last block. include_directories(${CRYPTOPP_INCLUDE_DIR}) - if(NOT APPLE) + if (NOT APPLE) link_directories(${CRYPTOPP_LIBRARIES}) endif() - find_path(SERPENT_ID NAMES serpent/funcs.h serpent/util.h PATHS . ..) - find_library(SERPENT_LS NAMES serpent PATHS ../serpent) - if ( SERPENT_ID AND SERPENT_LS ) - message(STATUS "Found serpent (headers in ${SERPENT_ID}, library ${SERPENT_LS})") - add_definitions(-DETH_SERPENT) - include_directories(${SERPENT_ID}) - set( SERPENT_LIBRARIES ${SERPENT_LS} ) - else () - message(STATUS "Serpent not found. No serpent support.") - endif () - find_path( LEVELDB_ID leveldb/db.h /usr/include /usr/local/include ) if ( LEVELDB_ID ) message(STATUS "Found LevelDB Headers") + + # Check for accessory dev libraries leveldb and miniupnpc + find_library( LEVELDB_LS NAMES leveldb + PATHS + /usr/lib + /usr/local/lib + /opt/local/lib + /usr/lib/*/ + ) + if ( LEVELDB_LS ) + message(STATUS "Found LevelDB Library: ${LEVELDB_LS}") + else () + message(FATAL_ERROR "Failed to find the LevelDB Library!") + endif () else () message(FATAL_ERROR "Failed to find the LevelDB headers") endif () - # Check for accessory dev libraries leveldb and miniupnpc - find_library( LEVELDB_LS NAMES leveldb - PATHS - /usr/lib - /usr/local/lib - /opt/local/lib - /usr/lib/*/ + find_path( PYTHON_ID pyconfig.h + /usr/include/python2.7 + /usr/local/include/python2.7 ) - if ( LEVELDB_LS ) - message(STATUS "Found LevelDB Library: ${LEVELDB_LS}") - else () - message(FATAL_ERROR "Failed to find the LevelDB Library!") + if ( PYTHON_ID ) + message(STATUS "Found Python-2.7 Headers: ${PYTHON_ID}") + + # Check for accessory dev libraries leveldb and miniupnpc + find_library( PYTHON_LS NAMES python2.7 + PATHS + /usr/lib + /usr/local/lib + /opt/local/lib + /usr/lib/*/ + ) + if ( PYTHON_LS ) + message(STATUS "Found Python-2.7 Library: ${PYTHON_LS}") + else () + message(FATAL_ERROR "Failed to find the Python-2.7 Library!") + endif () + else () + message(FATAL_ERROR "Failed to find the Python-2.7 headers") endif () find_path( MINIUPNPC_ID miniupnpc/miniwget.h @@ -205,21 +218,21 @@ else () ) if ( MINIUPNPC_ID ) message(STATUS "Found miniupnpc headers") - else () - message(FATAL_ERROR "Failed to find the miniupnpc headers!") - endif () - find_library( MINIUPNPC_LS NAMES miniupnpc - PATHS - /usr/lib - /usr/local/lib - /opt/local/lib - /usr/lib/*/ - ) - if ( MINIUPNPC_LS ) - message(STATUS "Found miniupnpc library: ${MINIUPNPC_LS}") + find_library( MINIUPNPC_LS NAMES miniupnpc + PATHS + /usr/lib + /usr/local/lib + /opt/local/lib + /usr/lib/*/ + ) + if ( MINIUPNPC_LS ) + message(STATUS "Found miniupnpc library: ${MINIUPNPC_LS}") + else () + message(FATAL_ERROR "Failed to find the miniupnpc library!") + endif () else () - message(FATAL_ERROR "Failed to find the miniupnpc library!") + message(FATAL_ERROR "Failed to find the miniupnpc headers!") endif () @@ -269,6 +282,14 @@ else () endif() +if (UNIX) + if (LANGUAGES) + find_package(Boost 1.53 REQUIRED COMPONENTS thread date_time) + else() + find_package(Boost 1.53 REQUIRED COMPONENTS thread date_time system) + endif() +endif() + # Generate header file containing useful build information add_custom_target(BuildInfo.h ALL COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/BuildInfo.sh ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BUILD_TYPE} ${ETH_BUILD_PLATFORM}) include_directories(${CMAKE_CURRENT_BINARY_DIR}) @@ -281,13 +302,17 @@ add_subdirectory(libethential) add_subdirectory(libevmface) add_subdirectory(liblll) add_subdirectory(libserpent) +if (PYTHON_LS) +add_subdirectory(libpyserpent) +endif () +add_subdirectory(lllc) +add_subdirectory(sc) if (NOT LANGUAGES) add_subdirectory(secp256k1) add_subdirectory(libethcore) add_subdirectory(libevm) add_subdirectory(libethereum) add_subdirectory(test) -add_subdirectory(lllc) add_subdirectory(eth) if ("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug") add_subdirectory(exp) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index afb73e77d..59bb63d4a 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -9,9 +9,6 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) include_directories(..) -link_directories(../libethcore) -link_directories(../libethereum) -link_directories(../libqethereum) # Find Qt5 for Apple and update src_list for windows if (APPLE) @@ -56,7 +53,7 @@ else () endif () qt5_use_modules(${EXECUTEABLE} Core Gui Widgets Network WebKit WebKitWidgets) -target_link_libraries(${EXECUTEABLE} qethereum ethereum secp256k1 ${SERPENT_LIBRARIES} ${CRYPTOPP_LIBRARIES}) +target_link_libraries(${EXECUTEABLE} qethereum ethereum evm ethcore secp256k1 ${CRYPTOPP_LIBRARIES} serpent lll evmface ethential) if (APPLE) set_target_properties(${EXECUTEABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") diff --git a/alethzero/Main.ui b/alethzero/Main.ui index adca65854..a9782f8a2 100644 --- a/alethzero/Main.ui +++ b/alethzero/Main.ui @@ -162,10 +162,11 @@ Deb&ug + + - @@ -1432,6 +1433,9 @@ font-family: Monospace, Ubuntu Mono, Lucida Console, Courier New + + false + Single Step &Backwards diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 754481029..a8c024454 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -27,10 +27,8 @@ #include #include #include -#ifdef ETH_SERPENT -#include -#include -#endif +#include +#include #include #include #include @@ -550,7 +548,8 @@ void Main::refreshBlockChain() for (auto h = bc.currentHash(); h != bc.genesisHash() && i; h = bc.details(h).parent, --i) { auto d = bc.details(h); - if (blockMatch(filter, d, h, bc)) + auto bm = blockMatch(filter, d, h, bc); + if (bm) { QListWidgetItem* blockItem = new QListWidgetItem(QString("#%1 %2").arg(d.number).arg(h.abridged().c_str()), ui->blocks); auto hba = QByteArray((char const*)h.data(), h.size); @@ -562,7 +561,7 @@ void Main::refreshBlockChain() for (auto const& i: RLP(bc.block(h))[1]) { Transaction t(i[0].data()); - if (transactionMatch(filter, t)) + if (bm || transactionMatch(filter, t)) { QString s = t.receiveAddress ? QString(" %2 %5> %3: %1 [%4]") @@ -855,9 +854,9 @@ void Main::on_blocks_currentItemChanged() s << "   #" << tx.nonce << ""; s << "
Gas price: " << formatBalance(tx.gasPrice) << ""; s << "
Gas: " << tx.gas << ""; - s << "
V: " << hex << (int)tx.vrs.v << ""; - s << "
R: " << hex << tx.vrs.r << ""; - s << "
S: " << hex << tx.vrs.s << ""; + s << "
V: " << hex << nouppercase << (int)tx.vrs.v << ""; + s << "
R: " << hex << nouppercase << tx.vrs.r << ""; + s << "
S: " << hex << nouppercase << tx.vrs.s << ""; s << "
Msg: " << tx.sha3(false) << ""; if (tx.isCreation()) { @@ -982,7 +981,6 @@ void Main::on_data_textChanged() auto asmcode = eth::compileLLLToAsm(src, false); auto asmcodeopt = eth::compileLLLToAsm(ui->data->toPlainText().toStdString(), true); m_data = eth::compileLLL(ui->data->toPlainText().toStdString(), true, &errors); -#ifdef ETH_SERPENT if (errors.size()) { try @@ -997,7 +995,6 @@ void Main::on_data_textChanged() } } else -#endif lll = "

Opt

" + QString::fromStdString(asmcodeopt).toHtmlEscaped() + "

Pre

" + QString::fromStdString(asmcode).toHtmlEscaped() + "
"; } QString errs; diff --git a/libethcore/CMakeLists.txt b/libethcore/CMakeLists.txt index d2ecdf0b0..925bfdb3b 100644 --- a/libethcore/CMakeLists.txt +++ b/libethcore/CMakeLists.txt @@ -1,19 +1,14 @@ cmake_policy(SET CMP0015 NEW) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") - aux_source_directory(. SRC_LIST) set(EXECUTABLE ethcore) -if(APPLE) - # set(CMAKE_INSTALL_PREFIX ../lib) - add_library(${EXECUTABLE} SHARED ${SRC_LIST}) -else() - add_library(${EXECUTABLE} ${SRC_LIST}) -endif() +# set(CMAKE_INSTALL_PREFIX ../lib) +add_library(${EXECUTABLE} SHARED ${SRC_LIST}) + if (UNIX) - FIND_PACKAGE(Boost 1.53 REQUIRED COMPONENTS thread date_time system filesystem program_options signals serialization chrono unit_test_framework locale) + FIND_PACKAGE(Boost 1.53 REQUIRED COMPONENTS filesystem) endif() file(GLOB HEADERS "*.h") diff --git a/libethential/CMakeLists.txt b/libethential/CMakeLists.txt index 5ac121018..4a4d6294f 100644 --- a/libethential/CMakeLists.txt +++ b/libethential/CMakeLists.txt @@ -6,12 +6,9 @@ aux_source_directory(. SRC_LIST) set(EXECUTABLE ethential) -if(APPLE) - # set(CMAKE_INSTALL_PREFIX ../lib) - add_library(${EXECUTABLE} SHARED ${SRC_LIST}) -else() - add_library(${EXECUTABLE} ${SRC_LIST}) -endif() +# set(CMAKE_INSTALL_PREFIX ../lib) +add_library(${EXECUTABLE} SHARED ${SRC_LIST}) + file(GLOB HEADERS "*.h") include_directories(..) @@ -40,10 +37,6 @@ else () target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) endif () -if (UNIX) - FIND_PACKAGE(Boost 1.53 REQUIRED COMPONENTS thread date_time system filesystem program_options signals serialization chrono unit_test_framework locale) -endif() - message("Installation path: ${CMAKE_INSTALL_PREFIX}") install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index 3f73df2a7..80f25c085 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -6,15 +6,9 @@ aux_source_directory(. SRC_LIST) set(EXECUTABLE ethereum) -if(APPLE) - # set(CMAKE_INSTALL_PREFIX ../lib) - add_library(${EXECUTABLE} SHARED ${SRC_LIST}) -else() - add_library(${EXECUTABLE} ${SRC_LIST}) -endif() -if (UNIX) - FIND_PACKAGE(Boost 1.53 REQUIRED COMPONENTS thread date_time system filesystem program_options signals serialization chrono unit_test_framework locale) -endif() +# set(CMAKE_INSTALL_PREFIX ../lib) +add_library(${EXECUTABLE} SHARED ${SRC_LIST}) + file(GLOB HEADERS "*.h") include_directories(..) diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 77f1088b8..48e16d2e5 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -1195,9 +1195,9 @@ std::ostream& eth::operator<<(std::ostream& _out, State const& _s) for (auto const& j: mem) if (j.second) - contout << std::endl << (delta.count(j.first) ? back.count(j.first) ? " * " : " + " : cached.count(j.first) ? " . " : " ") << std::hex << std::setw(64) << j.first << ": " << std::setw(0) << j.second ; + contout << std::endl << (delta.count(j.first) ? back.count(j.first) ? " * " : " + " : cached.count(j.first) ? " . " : " ") << std::hex << nouppercase << std::setw(64) << j.first << ": " << std::setw(0) << j.second ; else - contout << std::endl << "XXX " << std::hex << std::setw(64) << j.first << ""; + contout << std::endl << "XXX " << std::hex << nouppercase << std::setw(64) << j.first << ""; } else contout << " [SIMPLE]"; @@ -1239,14 +1239,14 @@ std::ostream& eth::operator<<(std::ostream& _out, AccountDiff const& _s) _out << "(" << std::showpos << (((bigint)_s.balance.to()) - ((bigint)_s.balance.from())) << std::noshowpos << ") "; } if (_s.code) - _out << "$" << std::hex << _s.code.to() << " (" << _s.code.from() << ") "; + _out << "$" << std::hex << nouppercase << _s.code.to() << " (" << _s.code.from() << ") "; for (pair> const& i: _s.storage) if (!i.second.from()) - _out << endl << " + " << (h256)i.first << ": " << std::hex << i.second.to(); + _out << endl << " + " << (h256)i.first << ": " << std::hex << nouppercase << i.second.to(); else if (!i.second.to()) - _out << endl << "XXX " << (h256)i.first << " (" << std::hex << i.second.from() << ")"; + _out << endl << "XXX " << (h256)i.first << " (" << std::hex << nouppercase << i.second.from() << ")"; else - _out << endl << " * " << (h256)i.first << ": " << std::hex << i.second.to() << " (" << i.second.from() << ")"; + _out << endl << " * " << (h256)i.first << ": " << std::hex << nouppercase << i.second.to() << " (" << i.second.from() << ")"; return _out; } diff --git a/libevm/CMakeLists.txt b/libevm/CMakeLists.txt index 257710b56..c20ece1bb 100644 --- a/libevm/CMakeLists.txt +++ b/libevm/CMakeLists.txt @@ -6,15 +6,9 @@ aux_source_directory(. SRC_LIST) set(EXECUTABLE evm) -if(APPLE) - # set(CMAKE_INSTALL_PREFIX ../lib) - add_library(${EXECUTABLE} SHARED ${SRC_LIST}) -else() - add_library(${EXECUTABLE} ${SRC_LIST}) -endif() -if (UNIX) - FIND_PACKAGE(Boost 1.53 REQUIRED COMPONENTS thread date_time system filesystem program_options signals serialization chrono unit_test_framework locale) -endif() +# set(CMAKE_INSTALL_PREFIX ../lib) +add_library(${EXECUTABLE} SHARED ${SRC_LIST}) + file(GLOB HEADERS "*.h") include_directories(..) diff --git a/libevmface/CMakeLists.txt b/libevmface/CMakeLists.txt index 30091074d..7da6bf90c 100644 --- a/libevmface/CMakeLists.txt +++ b/libevmface/CMakeLists.txt @@ -6,12 +6,9 @@ aux_source_directory(. SRC_LIST) set(EXECUTABLE evmface) -if(APPLE) - # set(CMAKE_INSTALL_PREFIX ../lib) - add_library(${EXECUTABLE} SHARED ${SRC_LIST}) -else() - add_library(${EXECUTABLE} ${SRC_LIST}) -endif() +# set(CMAKE_INSTALL_PREFIX ../lib) +add_library(${EXECUTABLE} SHARED ${SRC_LIST}) + file(GLOB HEADERS "*.h") include_directories(..) @@ -40,10 +37,6 @@ else () target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) endif () -if (UNIX) - FIND_PACKAGE(Boost 1.53 REQUIRED COMPONENTS thread date_time system filesystem program_options signals serialization chrono unit_test_framework locale) -endif() - message("Installation path: ${CMAKE_INSTALL_PREFIX}") install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) diff --git a/liblll/Assembly.h b/liblll/Assembly.h index 29f899c0e..3e8a83260 100644 --- a/liblll/Assembly.h +++ b/liblll/Assembly.h @@ -70,8 +70,8 @@ class Assembly public: AssemblyItem newTag() { return AssemblyItem(Tag, m_usedTags++); } AssemblyItem newPushTag() { return AssemblyItem(PushTag, m_usedTags++); } - AssemblyItem newData(bytes const& _data) { auto h = sha3(_data); m_data[h] = _data; return AssemblyItem(PushData, h); } - AssemblyItem newPushString(std::string const& _data) { auto h = sha3(_data); m_strings[h] = _data; return AssemblyItem(PushString, h); } + AssemblyItem newData(bytes const& _data) { h256 h = (u256)std::hash()(asString(_data)); m_data[h] = _data; return AssemblyItem(PushData, h); } + AssemblyItem newPushString(std::string const& _data) { h256 h = (u256)std::hash()(_data); m_strings[h] = _data; return AssemblyItem(PushString, h); } AssemblyItem append() { return append(newTag()); } void append(Assembly const& _a); diff --git a/liblll/CMakeLists.txt b/liblll/CMakeLists.txt index 4117e6edc..2356b7d9d 100644 --- a/liblll/CMakeLists.txt +++ b/liblll/CMakeLists.txt @@ -6,27 +6,20 @@ aux_source_directory(. SRC_LIST) set(EXECUTABLE lll) -if(APPLE) - # set(CMAKE_INSTALL_PREFIX ../lib) - add_library(${EXECUTABLE} SHARED ${SRC_LIST}) -else() - add_library(${EXECUTABLE} ${SRC_LIST}) -endif() -if (UNIX) - FIND_PACKAGE(Boost 1.53 REQUIRED COMPONENTS thread date_time system filesystem program_options signals serialization chrono unit_test_framework locale) -endif() +# set(CMAKE_INSTALL_PREFIX ../lib) +add_library(${EXECUTABLE} SHARED ${SRC_LIST}) + file(GLOB HEADERS "*.h") include_directories(..) -target_link_libraries(${EXECUTABLE} ethential) + target_link_libraries(${EXECUTABLE} evmface) +target_link_libraries(${EXECUTABLE} ethential) target_link_libraries(${EXECUTABLE} gmp) + if(${TARGET_PLATFORM} STREQUAL "w64") - include_directories(/usr/x86_64-w64-mingw32/include/cryptopp) - target_link_libraries(${EXECUTABLE} cryptopp) target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) target_link_libraries(${EXECUTABLE} iphlpapi) target_link_libraries(${EXECUTABLE} ws2_32) @@ -34,23 +27,16 @@ if(${TARGET_PLATFORM} STREQUAL "w64") target_link_libraries(${EXECUTABLE} shlwapi) elseif (APPLE) # Latest mavericks boost libraries only come with -mt - target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} boost_system-mt) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt) target_link_libraries(${EXECUTABLE} boost_thread-mt) find_package(Threads REQUIRED) target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) elseif (UNIX) - target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY}) target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY}) target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) else () - target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} boost_system) - target_link_libraries(${EXECUTABLE} boost_filesystem) target_link_libraries(${EXECUTABLE} boost_thread) find_package(Threads REQUIRED) target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) diff --git a/liblll/CodeFragment.cpp b/liblll/CodeFragment.cpp index 2ad23471d..f0aeb860c 100644 --- a/liblll/CodeFragment.cpp +++ b/liblll/CodeFragment.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include "CompilerState.h" using namespace std; using namespace eth; diff --git a/libpyserpent/CMakeLists.txt b/libpyserpent/CMakeLists.txt new file mode 100644 index 000000000..5c4c9d165 --- /dev/null +++ b/libpyserpent/CMakeLists.txt @@ -0,0 +1,58 @@ +cmake_policy(SET CMP0015 NEW) + +aux_source_directory(. SRC_LIST) + +set(EXECUTABLE pyserpent) + +# set(CMAKE_INSTALL_PREFIX ../lib) +add_library(${EXECUTABLE} SHARED ${SRC_LIST}) + +if (UNIX) + FIND_PACKAGE(Boost 1.53 REQUIRED COMPONENTS python) +endif() +file(GLOB HEADERS "*.h") + +include_directories(..) + +add_definitions(-DETH_PYTHON) +include_directories(${PYTHON_ID}) +target_link_libraries(${EXECUTABLE} ${PYTHON_LS}) + +target_link_libraries(${EXECUTABLE} serpent) +target_link_libraries(${EXECUTABLE} lll) +target_link_libraries(${EXECUTABLE} evmface) +target_link_libraries(${EXECUTABLE} ethential) +target_link_libraries(${EXECUTABLE} gmp) +target_link_libraries(${EXECUTABLE} gmp) + +#g++ $(CXXFLAGS) -shared $(PLATFORM_OPTS) $(TARGET).o -L$(BOOST_LIB) -lboost_python -L/usr/lib/python$(PYTHON_VERSION)/config -lpython$(PYTHON_VERSION) $(COMMON_OBJS) -o $(TARGET).so + +if(${TARGET_PLATFORM} STREQUAL "w64") + target_link_libraries(${EXECUTABLE} boost_python_win32-mt-s) + target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) + target_link_libraries(${EXECUTABLE} iphlpapi) + target_link_libraries(${EXECUTABLE} ws2_32) + target_link_libraries(${EXECUTABLE} mswsock) + target_link_libraries(${EXECUTABLE} shlwapi) +elseif (APPLE) + # Latest mavericks boost libraries only come with -mt + target_link_libraries(${EXECUTABLE} boost_python-mt) + target_link_libraries(${EXECUTABLE} boost_thread-mt) + find_package(Threads REQUIRED) + target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) +elseif (UNIX) + target_link_libraries(${EXECUTABLE} ${Boost_PYTHON_LIBRARY}) + target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) + target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) +else () + target_link_libraries(${EXECUTABLE} boost_python) + target_link_libraries(${EXECUTABLE} boost_thread) + find_package(Threads REQUIRED) + target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) +endif () + +message("Installation path: ${CMAKE_INSTALL_PREFIX}") + +install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) +install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) + diff --git a/libpyserpent/pyserpent.cpp b/libpyserpent/pyserpent.cpp new file mode 100644 index 000000000..c8f5a38b9 --- /dev/null +++ b/libpyserpent/pyserpent.cpp @@ -0,0 +1,132 @@ +#include +#include +#include +#include + +// Provide a python wrapper for the C++ functions + +using namespace boost::python; + +//std::vector to python list converter +//http://stackoverflow.com/questions/5314319/how-to-export-stdvector +template +struct VecToList +{ + static PyObject* convert(const std::vector& vec) + { + boost::python::list* l = new boost::python::list(); + for(size_t i = 0; i < vec.size(); i++) + (*l).append(vec[i]); + + return l->ptr(); + } +}; + +// python list to std::vector converter +//http://code.activestate.com/lists/python-cplusplus-sig/16463/ +template +struct Vector_from_python_list +{ + + Vector_from_python_list() + { + using namespace boost::python; + using namespace boost::python::converter; + registry::push_back(&Vector_from_python_list::convertible, + &Vector_from_python_list::construct, + type_id +>()); + + } + + // Determine if obj_ptr can be converted in a std::vector + static void* convertible(PyObject* obj_ptr) + { + if (!PyList_Check(obj_ptr)){ + return 0; + } + return obj_ptr; + } + + // Convert obj_ptr into a std::vector + static void construct( + PyObject* obj_ptr, + boost::python::converter::rvalue_from_python_stage1_data* data) + { + using namespace boost::python; + // Extract the character data from the python string + // const char* value = PyString_AsString(obj_ptr); + list l(handle<>(borrowed(obj_ptr))); + + // // Verify that obj_ptr is a string (should be ensured by convertible()) + // assert(value); + + // Grab pointer to memory into which to construct the new std::vector + void* storage = ( + (boost::python::converter::rvalue_from_python_storage +>*) + + data)->storage.bytes; + + // in-place construct the new std::vector using the character data + // extraced from the python object + std::vector& v = *(new (storage) std::vector()); + + // populate the vector from list contains !!! + int le = len(l); + v.resize(le); + for(int i = 0;i!=le;++i){ + v[i] = extract(l[i]); + } + + // Stash the memory chunk pointer for later use by boost.python + data->convertible = storage; + } +}; + +std::string printMetadata(Metadata m) { + return "["+m.file+" "+intToDecimal(m.ln)+" "+intToDecimal(m.ch)+"]"; +} + +BOOST_PYTHON_FUNCTION_OVERLOADS(tokenize_overloads, tokenize, 1, 2); +BOOST_PYTHON_FUNCTION_OVERLOADS(printast_overloads, printAST, 1, 2); +BOOST_PYTHON_FUNCTION_OVERLOADS(parselll_overloads, parseLLL, 1, 2); +//BOOST_PYTHON_FUNCTION_OVERLOADS(metadata_overloads, Metadata, 0, 3); +BOOST_PYTHON_MODULE(pyserpent) +{ + def("tokenize", tokenize, tokenize_overloads()); + def("parse", parseSerpent); + def("parseLLL", parseLLL, parselll_overloads()); + def("rewrite", rewrite); + def("compile_to_lll", compileToLLL); + def("encode_datalist", encodeDatalist); + def("decode_datalist", decodeDatalist); + def("compile_lll", compileLLL); + def("assemble", assemble); + def("deserialize", deserialize); + def("dereference", dereference); + def("flatten", flatten); + def("serialize", serialize); + def("compile", compile); + def("pretty_compile", prettyCompile); + def("pretty_assemble", prettyAssemble); + //class_("Node",init<>()) + to_python_converter >, + VecToList >(); + to_python_converter >, + VecToList >(); + Vector_from_python_list(); + Vector_from_python_list(); + class_("Metadata",init<>()) + .def(init()) + .def("__str__", printMetadata) + .def("__repr__", printMetadata) + ; + class_("Node",init<>()) + .def(init<>()) + .def("__str__", printAST, printast_overloads()) + .def("__repr__", printAST, printast_overloads()) + ; + //class_("Vector",init<>()) + // .def(init<>()); +} diff --git a/libqethereum/CMakeLists.txt b/libqethereum/CMakeLists.txt index 880aadb17..146ec2e60 100644 --- a/libqethereum/CMakeLists.txt +++ b/libqethereum/CMakeLists.txt @@ -50,12 +50,10 @@ if (APPLE) set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTABLE}) include(BundleUtilities) - - add_library(${EXECUTABLE} SHARED ${RESOURCE_ADDED} ${SRC_LIST}) -else () - add_library(${EXECUTABLE} ${RESOURCE_ADDED} ${SRC_LIST}) endif () +add_library(${EXECUTABLE} SHARED ${RESOURCE_ADDED} ${SRC_LIST}) + qt5_use_modules(${EXECUTABLE} Core Gui WebKit WebKitWidgets Widgets Network Quick Qml) target_link_libraries(${EXECUTABLE} ethereum secp256k1 ${CRYPTOPP_LIBRARIES}) diff --git a/libserpent/CMakeLists.txt b/libserpent/CMakeLists.txt index 0deb6f604..a0768c32f 100644 --- a/libserpent/CMakeLists.txt +++ b/libserpent/CMakeLists.txt @@ -6,30 +6,20 @@ aux_source_directory(. SRC_LIST) set(EXECUTABLE serpent) -if(APPLE) - # set(CMAKE_INSTALL_PREFIX ../lib) - add_library(${EXECUTABLE} SHARED ${SRC_LIST}) -else() - add_library(${EXECUTABLE} ${SRC_LIST}) -endif() -if (UNIX) - FIND_PACKAGE(Boost 1.53 REQUIRED COMPONENTS thread date_time system filesystem program_options signals serialization chrono unit_test_framework locale) -endif() +# set(CMAKE_INSTALL_PREFIX ../lib) +add_library(${EXECUTABLE} SHARED ${SRC_LIST}) + file(GLOB HEADERS "*.h") include_directories(..) -target_link_libraries(${EXECUTABLE} ethential) -target_link_libraries(${EXECUTABLE} evmface) target_link_libraries(${EXECUTABLE} lll) +target_link_libraries(${EXECUTABLE} evmface) +target_link_libraries(${EXECUTABLE} ethential) target_link_libraries(${EXECUTABLE} gmp) if(${TARGET_PLATFORM} STREQUAL "w64") - include_directories(/usr/x86_64-w64-mingw32/include/cryptopp) - target_link_libraries(${EXECUTABLE} cryptopp) - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) target_link_libraries(${EXECUTABLE} iphlpapi) target_link_libraries(${EXECUTABLE} ws2_32) @@ -37,23 +27,13 @@ if(${TARGET_PLATFORM} STREQUAL "w64") target_link_libraries(${EXECUTABLE} shlwapi) elseif (APPLE) # Latest mavericks boost libraries only come with -mt - target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) - target_link_libraries(${EXECUTABLE} boost_system-mt) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt) target_link_libraries(${EXECUTABLE} boost_thread-mt) find_package(Threads REQUIRED) target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) elseif (UNIX) - target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) - target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY}) target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY}) - target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY}) target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) else () - target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) - target_link_libraries(${EXECUTABLE} boost_system) - target_link_libraries(${EXECUTABLE} boost_filesystem) target_link_libraries(${EXECUTABLE} boost_thread) find_package(Threads REQUIRED) target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) diff --git a/lllc/CMakeLists.txt b/lllc/CMakeLists.txt index 1188f1b5b..2146c192a 100644 --- a/lllc/CMakeLists.txt +++ b/lllc/CMakeLists.txt @@ -8,18 +8,6 @@ set(EXECUTABLE lllc) add_executable(${EXECUTABLE} ${SRC_LIST}) -if (JSONRPC_LS) - add_definitions(-DETH_JSONRPC) - include_directories(${JSONRPC_ID}) - target_link_libraries(${EXECUTABLE} ${JSONRPC_LS}) -endif () - -if (READLINE_LS) - add_definitions(-DETH_READLINE) - include_directories(${READLINE_ID}) - target_link_libraries(${EXECUTABLE} ${READLINE_LS}) -endif () - if (${TARGET_PLATFORM} STREQUAL "w64") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") target_link_libraries(${EXECUTABLE} gcc) @@ -28,24 +16,17 @@ if (${TARGET_PLATFORM} STREQUAL "w64") target_link_libraries(${EXECUTABLE} mswsock) target_link_libraries(${EXECUTABLE} shlwapi) target_link_libraries(${EXECUTABLE} iphlpapi) - target_link_libraries(${EXECUTABLE} cryptopp) - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) elseif (UNIX) else () - target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES}) - target_link_libraries(${EXECUTABLE} boost_system) - target_link_libraries(${EXECUTABLE} boost_filesystem) find_package(Threads REQUIRED) target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) endif () target_link_libraries(${EXECUTABLE} lll) -target_link_libraries(${EXECUTABLE} ethcore) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) -target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) +target_link_libraries(${EXECUTABLE} evmface) +target_link_libraries(${EXECUTABLE} ethential) target_link_libraries(${EXECUTABLE} gmp) install( TARGETS ${EXECUTABLE} DESTINATION bin ) diff --git a/sc/CMakeLists.txt b/sc/CMakeLists.txt new file mode 100644 index 000000000..5b5024c40 --- /dev/null +++ b/sc/CMakeLists.txt @@ -0,0 +1,35 @@ +cmake_policy(SET CMP0015 NEW) + +aux_source_directory(. SRC_LIST) + +include_directories(..) + +set(EXECUTABLE sc) + +add_executable(${EXECUTABLE} ${SRC_LIST}) + +if (${TARGET_PLATFORM} STREQUAL "w64") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") + target_link_libraries(${EXECUTABLE} gcc) + target_link_libraries(${EXECUTABLE} gdi32) + target_link_libraries(${EXECUTABLE} ws2_32) + target_link_libraries(${EXECUTABLE} mswsock) + target_link_libraries(${EXECUTABLE} shlwapi) + target_link_libraries(${EXECUTABLE} iphlpapi) + target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) + set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) +elseif (UNIX) +else () + find_package(Threads REQUIRED) + target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) +endif () + +target_link_libraries(${EXECUTABLE} serpent) +target_link_libraries(${EXECUTABLE} lll) +target_link_libraries(${EXECUTABLE} evmface) +target_link_libraries(${EXECUTABLE} ethential) +target_link_libraries(${EXECUTABLE} gmp) + +install( TARGETS ${EXECUTABLE} DESTINATION bin ) + +cmake_policy(SET CMP0015 NEW) diff --git a/sc/cmdline.cpp b/sc/cmdline.cpp new file mode 100644 index 000000000..71d9928b2 --- /dev/null +++ b/sc/cmdline.cpp @@ -0,0 +1,106 @@ +#include +#include +#include +#include +#include + +int main(int argv, char** argc) { + if (argv == 1) { + std::cerr << "Must provide a command and arguments! Try parse, rewrite, compile, assemble\n"; + return 0; + } + std::string flag = ""; + std::string command = argc[1]; + std::string input; + std::string secondInput; + if (std::string(argc[1]) == "-s") { + flag = command.substr(1); + command = argc[2]; + input = ""; + std::string line; + while (std::getline(std::cin, line)) { + input += line + "\n"; + } + secondInput = argv == 3 ? "" : argc[3]; + } + else { + if (argv == 2) { + std::cerr << "Not enough arguments for serpent cmdline\n"; + throw(0); + } + input = argc[2]; + secondInput = argv == 3 ? "" : argc[3]; + } + bool haveSec = secondInput.length() > 0; + if (command == "parse" || command == "parse_serpent") { + std::cout << printAST(parseSerpent(input), haveSec) << "\n"; + } + else if (command == "rewrite") { + std::cout << printAST(rewrite(parseLLL(input, true)), haveSec) << "\n"; + } + else if (command == "compile_to_lll") { + std::cout << printAST(compileToLLL(input), haveSec) << "\n"; + } + else if (command == "build_fragtree") { + std::cout << printAST(buildFragmentTree(parseLLL(input, true))) << "\n"; + } + else if (command == "compile_lll") { + std::cout << binToHex(compileLLL(parseLLL(input, true))) << "\n"; + } + else if (command == "dereference") { + std::cout << printAST(dereference(parseLLL(input, true)), haveSec) <<"\n"; + } + else if (command == "pretty_assemble") { + std::cout << printTokens(prettyAssemble(parseLLL(input, true))) <<"\n"; + } + else if (command == "pretty_compile_lll") { + std::cout << printTokens(prettyCompileLLL(parseLLL(input, true))) << "\n"; + } + else if (command == "pretty_compile") { + std::cout << printTokens(prettyCompile(input)) << "\n"; + } + else if (command == "assemble") { + std::cout << assemble(parseLLL(input, true)) << "\n"; + } + else if (command == "serialize") { + std::cout << binToHex(serialize(tokenize(input))) << "\n"; + } + else if (command == "flatten") { + std::cout << printTokens(flatten(parseLLL(input, true))) << "\n"; + } + else if (command == "deserialize") { + std::cout << printTokens(deserialize(hexToBin(input))) << "\n"; + } + else if (command == "compile") { + std::cout << binToHex(compile(input)) << "\n"; + } + else if (command == "encode_datalist") { + std::vector tokens = tokenize(input); + std::vector o; + for (int i = 0; i < (int)tokens.size(); i++) { + o.push_back(tokens[i].val); + } + std::cout << binToHex(encodeDatalist(o)) << "\n"; + } + else if (command == "decode_datalist") { + std::vector o = decodeDatalist(hexToBin(input)); + std::vector tokens; + for (int i = 0; i < (int)o.size(); i++) + tokens.push_back(token(o[i])); + std::cout << printTokens(tokens) << "\n"; + } + else if (command == "tokenize") { + std::cout << printTokens(tokenize(input)); + } + else if (command == "biject") { + if (argv == 3) + std::cerr << "Not enough arguments for biject\n"; + int pos = decimalToInt(secondInput); + std::vector n = prettyCompile(input); + if (pos >= (int)n.size()) + std::cerr << "Code position too high\n"; + Metadata m = n[pos].metadata; + std::cout << "Opcode: " << n[pos].val << ", file: " << m.file << + ", line: " << m.ln << ", char: " << m.ch << "\n"; + } +} diff --git a/secp256k1/CMakeLists.txt b/secp256k1/CMakeLists.txt index 0c9e87c4e..38086a3e2 100644 --- a/secp256k1/CMakeLists.txt +++ b/secp256k1/CMakeLists.txt @@ -13,14 +13,14 @@ if ("${TARGET_PLATFORM}" STREQUAL "w64") asmOut ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/field_5x52_asm.o ) - add_library(secp256k1 secp256k1.c ${CMAKE_CURRENT_BINARY_DIR}/field_5x52_asm.o) + add_library(secp256k1 SHARED secp256k1.c ${CMAKE_CURRENT_BINARY_DIR}/field_5x52_asm.o) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -DUSE_FIELD_5X52 -DUSE_FIELD_5X52_ASM -DUSE_NUM_GMP -DUSE_FIELD_INV_NUM") elseif(APPLE) # set(CMAKE_INSTALL_PREFIX ../lib) add_library(secp256k1 SHARED secp256k1.c field_5x52_asm.asm) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -DUSE_FIELD_GMP -DUSE_NUM_GMP -DUSE_FIELD_INV_NUM") else() - add_library(secp256k1 secp256k1.c field_5x52_asm.asm) + add_library(secp256k1 SHARED secp256k1.c field_5x52_asm.asm) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -DUSE_FIELD_GMP -DUSE_NUM_GMP -DUSE_FIELD_INV_NUM") endif() diff --git a/serpent/__init__.py b/serpent/__init__.py deleted file mode 100644 index 111721862..000000000 --- a/serpent/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from compiler import * -from parser import * diff --git a/serpent/compiler.py b/serpent/compiler.py deleted file mode 100644 index 22d20d5a9..000000000 --- a/serpent/compiler.py +++ /dev/null @@ -1,446 +0,0 @@ -#!/usr/bin/python -import re -import sys -import os -from parser import parse -from opcodes import opcodes, reverse_opcodes -import json - -label_counter = [0] - - -def mklabel(prefix): - label_counter[0] += 1 - return prefix + str(label_counter[0] - 1) - -# All functions go here -# -# Entries go in a format: -# -# [ val, inputcount, outputcount, code ] - -funtable = [ - ['+', 2, 1, ['<1>', '<0>', 'ADD']], - ['-', 2, 1, ['<1>', '<0>', 'SUB']], - ['*', 2, 1, ['<1>', '<0>', 'MUL']], - ['/', 2, 1, ['<1>', '<0>', 'DIV']], - ['^', 2, 1, ['<1>', '<0>', 'EXP']], - ['%', 2, 1, ['<1>', '<0>', 'MOD']], - ['#/', 2, 1, ['<1>', '<0>', 'SDIV']], - ['#%', 2, 1, ['<1>', '<0>', 'SMOD']], - ['==', 2, 1, ['<1>', '<0>', 'EQ']], - ['<', 2, 1, ['<1>', '<0>', 'LT']], - ['<=', 2, 1, ['<1>', '<0>', 'GT', 'NOT']], - ['>', 2, 1, ['<1>', '<0>', 'GT']], - ['>=', 2, 1, ['<1>', '<0>', 'LT', 'NOT']], - ['!', 1, 1, ['<0>', 'NOT']], - ['or', 2, 1, ['<1>', '<0>', 'DUP', 4, 'PC', - 'ADD', 'JUMPI', 'POP', 'SWAP', 'POP']], - ['||', 2, 1, ['<1>', '<0>', 'DUP', 4, 'PC', - 'ADD', 'JUMPI', 'POP', 'SWAP', 'POP']], - ['and', 2, 1, ['<1>', '<0>', 'NOT', 'NOT', 'MUL']], - ['&&', 2, 1, ['<1>', '<0>', 'NOT', 'NOT', 'MUL']], - ['xor', 2, 1, ['<1>', '<0>', 'XOR']], - ['&', 2, 1, ['<1>', '<0>', 'AND']], - ['|', 2, 1, ['<1>', '<0>', 'OR']], - ['byte', 2, 1, ['<0>', '<1>', 'BYTE']], - # Word array methods - # arr, ind -> val - ['access', 2, 1, ['<0>', '<1>', 32, 'MUL', 'ADD', 'MLOAD']], - # arr, ind, val - ['arrset', 3, 0, ['<2>', '<0>', '<1>', 32, 'MUL', 'ADD', 'MSTORE']], - # val, pointer -> pointer+32 - ['set_and_inc', 2, 1, ['<1>', 'DUP', '<0>', 'SWAP', 'MSTORE', 32, 'ADD']], - # len (32 MUL) len*32 (MSIZE) len*32 MSIZE (SWAP) MSIZE len*32 (MSIZE ADD) - # MSIZE MSIZE+len*32 (1) MSIZE MSIZE+len*32 1 (SWAP SUB) MSIZE - # MSIZE+len*32-1 (0 SWAP MSTORE8) MSIZE - ['array', 1, 1, ['<0>', 32, 'MUL', 'MSIZE', 'SWAP', 'MSIZE', - 'ADD', 1, 'SWAP', 'SUB', 0, 'SWAP', 'MSTORE8']], # len -> arr - # String array methods - # arr, ind -> val - ['getch', 2, 1, ['<1>', '<0>', 'ADD', 'MLOAD', 255, 'AND']], - ['setch', 3, 0, ['<2>', '<1>', '<0>', 'ADD', 'MSTORE']], # arr, ind, val - # len MSIZE (SWAP) MSIZE len (MSIZE ADD) MSIZE MSIZE+len (1) MSIZE - # MSIZE+len 1 (SWAP SUB) MSIZE MSIZE+len-1 (0 SWAP MSTORE8) MSIZE - ['string', 1, 1, ['<0>', 'MSIZE', 'SWAP', 'MSIZE', 'ADD', - 1, 'SWAP', 'SUB', 0, 'SWAP', 'MSTORE8']], # len -> arr - # ['send', 2, 1, [0,0,0,0,0,'<1>','<0>','CALL'] ], # to, value, 0, [] -> /dev/null - # to, value, gas, [] -> /dev/null - ['send', 3, 1, [0, 0, 0, 0, '<2>', '<1>', '<0>', 'CALL']], - # MSIZE 0 MSIZE (MSTORE) MSIZE (DUP) MSIZE MSIZE (...) MSIZE MSIZE 32 <4> - # <3> <2> <1> <0> (CALL) MSIZE FLAG (POP) MSIZE (MLOAD) RESULT - ['msg', 5, 1, ['MSIZE', 0, 'MSIZE', 'MSTORE', 'DUP', 32, 'SWAP', '<4>', 32, 'MUL', '<3>', - '<2>', '<1>', '<0>', 'CALL', 'POP', 'MLOAD']], # to, value, gas, data, datasize -> out32 - # <5>*32 (MSIZE SWAP MSIZE SWAP) MSIZE MSIZE <5>*32 (DUP MSIZE ADD) MSIZE MSIZE <5>*32 MEND+1 (1 SWAP SUB) MSIZE MSIZE <5>*32 MEND (0 SWAP MSTORE8) MSIZE MSIZE <5>*32 (SWAP) MSIZE <5>*32 MSIZE - ['msg', 6, 1, ['<5>', 32, 'MUL', 'MSIZE', 'SWAP', 'MSIZE', 'SWAP', 'DUP', 'MSIZE', 'ADD', 1, 'SWAP', 'SUB', 0, 'SWAP', 'MSTORE8', 'SWAP', - '<4>', 32, 'MUL', '<3>', '<2>', '<1>', '<0>', 'CALL', 'POP']], # to, value, gas, data, datasize, outsize -> out - # value, gas, data, datasize - ['create', 4, 1, ['<3>', '<2>', '<1>', '<0>', 'CREATE']], - ['sha3', 1, 1, [32, 'MSIZE', '<0>', 'MSIZE', 'MSTORE', 'SHA3']], - ['sha3bytes', 1, 1, ['SHA3']], - ['sload', 1, 1, ['<0>', 'SLOAD']], - ['sstore', 2, 0, ['<1>', '<0>', 'SSTORE']], - ['calldataload', 1, 1, ['<0>', 32, 'MUL', 'CALLDATALOAD']], - ['id', 1, 1, ['<0>']], - # 0 MSIZE (SWAP) MSIZE 0 (MSIZE) MSIZE 0 MSIZE (MSTORE) MSIZE (32 SWAP) 32 - # MSIZE - # returns single value - ['return', 1, 0, [ - '<0>', 'MSIZE', 'SWAP', 'MSIZE', 'MSTORE', 32, 'SWAP', 'RETURN']], - ['return', 2, 0, ['<1>', 32, 'MUL', '<0>', 'RETURN']], - ['suicide', 1, 0, ['<0>', 'SUICIDE']], -] - -# Pseudo-variables representing opcodes -pseudovars = { - 'msg.datasize': [32, 'CALLDATASIZE', 'DIV'], - 'msg.sender': ['CALLER'], - 'msg.value': ['CALLVALUE'], - 'tx.gasprice': ['GASPRICE'], - 'tx.origin': ['ORIGIN'], - 'tx.gas': ['GAS'], - 'contract.balance': ['BALANCE'], - 'block.prevhash': ['PREVHASH'], - 'block.coinbase': ['COINBASE'], - 'block.timestamp': ['TIMESTAMP'], - 'block.number': ['NUMBER'], - 'block.difficulty': ['DIFFICULTY'], - 'block.gaslimit': ['GASLIMIT'], -} - - -# A set of methods for detecting raw values (numbers and strings) and -# converting them to integers -def frombytes(b): - return 0 if len(b) == 0 else ord(b[-1]) + 256 * frombytes(b[:-1]) - - -def fromhex(b): - return 0 if len(b) == 0 else '0123456789abcdef'.find(b[-1]) + 16 * fromhex(b[:-1]) - - -def is_numberlike(b): - if isinstance(b, (str, unicode)): - if re.match('^[0-9\-]*$', b): - return True - if b[0] in ["'", '"'] and b[-1] in ["'", '"'] and b[0] == b[-1]: - return True - if b[:2] == '0x': - return True - return False - - -def numberize(b): - if b[0] in ["'", '"']: - return frombytes(b[1:-1]) - elif b[:2] == '0x': - return fromhex(b[2:]) - else: - return int(b) - - -# Apply rewrite rules -def rewrite(ast): - if isinstance(ast, (str, unicode)): - return ast - elif ast[0] == 'set': - if ast[1][0] == 'access': - if ast[1][1] == 'contract.storage': - return ['sstore', rewrite(ast[1][2]), rewrite(ast[2])] - else: - return ['arrset', rewrite(ast[1][1]), rewrite(ast[1][2]), rewrite(ast[2])] - elif ast[0] == 'access': - if ast[1] == 'msg.data': - return ['calldataload', rewrite(ast[2])] - elif ast[1] == 'contract.storage': - return ['sload', rewrite(ast[2])] - elif ast[0] == 'array_lit': - o = ['array', str(len(ast[1:]))] - for a in ast[1:]: - o = ['set_and_inc', rewrite(a), o] - return ['-', o, str(len(ast[1:])*32)] - elif ast[0] == 'return': - if len(ast) == 2 and ast[1][0] == 'array_lit': - return ['return', rewrite(ast[1]), str(len(ast[1][1:]))] - return map(rewrite, ast) - - -# Main compiler code -def arity(ast): - if isinstance(ast, (str, unicode)): - return 1 - elif ast[0] == 'set': - return 0 - elif ast[0] == 'if': - return 0 - elif ast[0] == 'seq': - return 1 if len(ast[1:]) and arity(ast[-1]) == 1 else 0 - else: - for f in funtable: - if ast[0] == f[0]: - return f[2] - - -# Debugging -def print_wrapper(f): - def wrapper(*args, **kwargs): - print args[0] - u = f(*args, **kwargs) - print u - return u - return wrapper - - -# Right-hand-side expressions (ie. the normal kind) -#@print_wrapper -def compile_expr(ast, varhash, lc=[0]): - # Stop keyword - if ast == 'stop': - return ['STOP'] - # Literals - elif isinstance(ast, (str, unicode)): - if is_numberlike(ast): - return [numberize(ast)] - elif ast in pseudovars: - return pseudovars[ast] - else: - if ast not in varhash: - varhash[ast] = len(varhash) * 32 - return [varhash[ast], 'MLOAD'] - # Set (specifically, variables) - elif ast[0] == 'set': - if not isinstance(ast[1], (str, unicode)): - raise Exception("Cannot set the value of " + str(ast[1])) - elif ast[1] in pseudovars: - raise Exception("Cannot set a pseudovariable!") - else: - if ast[1] not in varhash: - varhash[ast[1]] = len(varhash) * 32 - return compile_expr(ast[2], varhash, lc) + [varhash[ast[1]], 'MSTORE'] - # If and if/else statements - elif ast[0] == 'if': - f = compile_expr(ast[1], varhash, lc) - g = compile_expr(ast[2], varhash, lc) - h = compile_expr(ast[3], varhash, lc) if len(ast) > 3 else None - label, ref = 'LABEL_' + str(lc[0]), 'REF_' + str(lc[0]) - lc[0] += 1 - label2, ref2 = 'LABEL_' + str(lc[0]), 'REF_' + str(lc[0]) - lc[0] += 1 - if h: - return f + ['NOT', ref2, 'JUMPI'] + g + [ref, 'JUMP', label2] + h + [label] - else: - return f + ['NOT', ref, 'JUMPI'] + g + [label] - # While loops - elif ast[0] == 'while': - f = compile_expr(ast[1], varhash, lc) - g = compile_expr(ast[2], varhash, lc) - beglab, begref = 'LABEL_' + str(lc[0]), 'REF_' + str(lc[0]) - endlab, endref = 'LABEL_' + str(lc[0] + 1), 'REF_' + str(lc[0] + 1) - lc[0] += 2 - return [beglab] + f + ['NOT', endref, 'JUMPI'] + g + [begref, 'JUMP', endlab] - # Seq - elif ast[0] == 'seq': - o = [] - for arg in ast[1:]: - o.extend(compile_expr(arg, varhash, lc)) - if arity(arg) == 1 and arg != ast[-1]: - o.append('POP') - return o - # Functions and operations - for f in funtable: - if ast[0] == f[0] and len(ast[1:]) == f[1]: - # If arity of all args is 1 - if reduce(lambda x, y: x * arity(y), ast[1:], 1): - iq = f[3][:] - oq = [] - while len(iq): - tok = iq.pop(0) - if isinstance(tok, (str, unicode)) and tok[0] == '<' and tok[-1] == '>': - oq.extend( - compile_expr(ast[1 + int(tok[1:-1])], varhash, lc)) - else: - oq.append(tok) - return oq - else: - raise Exception( - "Arity of argument mismatches for %s: %s" % (f[0], ast)) - raise Exception("invalid op: " + ast[0]) - - -# Stuff to add once to each program -def add_wrappers(c, varhash): - if len(varhash) and 'MSIZE' in c: - return [0, len(varhash) * 32 - 1, 'MSTORE8'] + c - else: - return c - - -# Optimizations -ops = { - 'ADD': lambda x, y: (x + y) % 2 ** 256, - 'MUL': lambda x, y: (x * y) % 2 ** 256, - 'SUB': lambda x, y: (x - y) % 2 ** 256, - 'DIV': lambda x, y: x / y, - 'EXP': lambda x, y: pow(x, y, 2 ** 256), - 'AND': lambda x, y: x & y, - 'OR': lambda x, y: x | y, - 'XOR': lambda x, y: x ^ y -} - - -def multipop(li, n): - if n > 0: - li.pop() - multipop(li, n - 1) - return li - - -def optimize(c): - iq = c[:] - oq = [] - while len(iq): - oq.append(iq.pop(0)) - if oq[-1] in ops and len(oq) >= 3: - if isinstance(oq[-2], (int, long)) and isinstance(oq[-3], (int, long)): - ntok = ops[oq[-1]](oq[-2], oq[-3]) - multipop(oq, 3).append(ntok) - if oq[-1] == 'NOT' and len(oq) >= 2 and oq[-2] == 'NOT': - multipop(oq, 2) - if oq[-1] == 'ADD' and len(oq) >= 3 and oq[-2] == 0 and is_numberlike(oq[-3]): - multipop(oq, 2) - if oq[-1] in ['SUB', 'ADD'] and len(oq) >= 3 and oq[-3] == 0 and is_numberlike(oq[-2]): - ntok = oq[-2] - multipop(oq, 3).append(ntok) - return oq - - -def compile_to_assembly(source, optimize_flag=1): - if isinstance(source, (str, unicode)): - source = parse(source) - varhash = {} - c1 = rewrite(source) - c2 = compile_expr(c1, varhash, [0]) - c3 = add_wrappers(c2, varhash) - c4 = optimize(c3) if optimize_flag else c3 - return c4 - - -def get_vars(source): - if isinstance(source, (str, unicode)): - source = parse(source) - varhash = {} - c1 = rewrite(source) - # fill varhash - compile_expr(c1, varhash, [0]) - return varhash - - -def log256(n): - return 0 if n == 0 else 1 + log256(n / 256) - - -def tobytearr(n, L): - return [] if L == 0 else tobytearr(n / 256, L - 1) + [n % 256] - - -# Dereference labels -def dereference(c): - iq = [x for x in c] - mq = [] - pos = 0 - labelmap = {} - while len(iq): - front = iq.pop(0) - if isinstance(front, str) and front[:6] == 'LABEL_': - labelmap[front[6:]] = pos - else: - mq.append(front) - if isinstance(front, str) and front[:4] == 'REF_': - pos += 5 - elif isinstance(front, (int, long)): - pos += 1 + max(1, log256(front)) - else: - pos += 1 - oq = [] - for m in mq: - if isinstance(m, str) and m[:4] == 'REF_': - oq.append('PUSH4') - oq.extend(tobytearr(labelmap[m[4:]], 4)) - elif isinstance(m, (int, long)): - L = max(1, log256(m)) - oq.append('PUSH' + str(L)) - oq.extend(tobytearr(m, L)) - else: - oq.append(m) - return oq - - -def serialize(source): - def numberize(arg): - if isinstance(arg, (int, long)): - return arg - elif arg in reverse_opcodes: - return reverse_opcodes[arg] - elif arg[:4] == 'PUSH': - return 95 + int(arg[4:]) - elif re.match('^[0-9]*$', arg): - return int(arg) - else: - raise Exception("Cannot serialize: " + str(arg)) - return ''.join(map(chr, map(numberize, source))) - - -def deserialize(source): - o = [] - i, j = 0, -1 - while i < len(source): - p = ord(source[i]) - if j >= 0: - o.append(p) - elif p >= 96 and p <= 127: - o.append('PUSH' + str(p - 95)) - else: - o.append(opcodes[p][0]) - if p >= 96 and p <= 127: - j = p - 95 - j -= 1 - i += 1 - return o - - -def assemble(asm): - return serialize(dereference(asm)) - - -def compile(source): - return assemble(compile_to_assembly(parse(source))) - - -def encode_datalist(vals): - def enc(n): - if isinstance(n, (int, long)): - return ''.join(map(chr, tobytearr(n, 32))) - elif isinstance(n, (str, unicode)) and len(n) == 40: - return '\x00' * 12 + n.decode('hex') - elif isinstance(n, (str, unicode)): - return '\x00' * (32 - len(n)) + n - elif n is True: - return 1 - elif n is False or n is None: - return 0 - if isinstance(vals, (tuple, list)): - return ''.join(map(enc, vals)) - elif vals == '': - return '' - else: - # Assume you're getting in numbers or 0x... - return ''.join(map(enc, map(numberize, vals.split(' ')))) - - -def decode_datalist(arr): - if isinstance(arr, list): - arr = ''.join(map(chr, arr)) - o = [] - for i in range(0, len(arr), 32): - o.append(frombytes(arr[i:i + 32])) - return o diff --git a/serpent/opcodes.py b/serpent/opcodes.py deleted file mode 100644 index 344582411..000000000 --- a/serpent/opcodes.py +++ /dev/null @@ -1,56 +0,0 @@ -opcodes = { - 0x00: ['STOP', 0, 0], - 0x01: ['ADD', 2, 1], - 0x02: ['MUL', 2, 1], - 0x03: ['SUB', 2, 1], - 0x04: ['DIV', 2, 1], - 0x05: ['SDIV', 2, 1], - 0x06: ['MOD', 2, 1], - 0x07: ['SMOD', 2, 1], - 0x08: ['EXP', 2, 1], - 0x09: ['NEG', 2, 1], - 0x0a: ['LT', 2, 1], - 0x0b: ['GT', 2, 1], - 0x0c: ['EQ', 2, 1], - 0x0d: ['NOT', 1, 1], - 0x10: ['AND', 2, 1], - 0x11: ['OR', 2, 1], - 0x12: ['XOR', 2, 1], - 0x13: ['BYTE', 2, 1], - 0x20: ['SHA3', 2, 1], - 0x30: ['ADDRESS', 0, 1], - 0x31: ['BALANCE', 0, 1], - 0x32: ['ORIGIN', 0, 1], - 0x33: ['CALLER', 0, 1], - 0x34: ['CALLVALUE', 0, 1], - 0x35: ['CALLDATALOAD', 1, 1], - 0x36: ['CALLDATASIZE', 0, 1], - 0x37: ['GASPRICE', 0, 1], - 0x40: ['PREVHASH', 0, 1], - 0x41: ['COINBASE', 0, 1], - 0x42: ['TIMESTAMP', 0, 1], - 0x43: ['NUMBER', 0, 1], - 0x44: ['DIFFICULTY', 0, 1], - 0x45: ['GASLIMIT', 0, 1], - 0x50: ['POP', 1, 0], - 0x51: ['DUP', 1, 2], - 0x52: ['SWAP', 2, 2], - 0x53: ['MLOAD', 1, 1], - 0x54: ['MSTORE', 2, 0], - 0x55: ['MSTORE8', 2, 0], - 0x56: ['SLOAD', 1, 1], - 0x57: ['SSTORE', 2, 0], - 0x58: ['JUMP', 1, 0], - 0x59: ['JUMPI', 2, 0], - 0x5a: ['PC', 0, 1], - 0x5b: ['MSIZE', 0, 1], - 0x5c: ['GAS', 0, 1], - 0x60: ['PUSH', 0, 1], #encompasses 96...127 - 0xf0: ['CREATE', 4, 1], - 0xf1: ['CALL', 7, 1], - 0xf2: ['RETURN', 2, 1], - 0xff: ['SUICIDE', 1, 1], -} -reverse_opcodes = {} -for o in opcodes: - reverse_opcodes[opcodes[o][0]] = o diff --git a/serpent/parser.py b/serpent/parser.py deleted file mode 100644 index 015fb46d0..000000000 --- a/serpent/parser.py +++ /dev/null @@ -1,299 +0,0 @@ -import re - -# Number of spaces at the beginning of a line -def spaces(ln): - spaces = 0 - while spaces < len(ln) and ln[spaces] == ' ': spaces += 1 - return spaces - -# Main parse function -def parse(document): - return parse_lines(document.split('\n')) - -def strip_line(ln): - ln2 = ln.strip() - if '//' in ln2: - return ln2[:ln2.find('//')] - else: - return ln2 - -# Parse the statement-level structure, including if and while statements -def parse_lines(lns): - o = [] - i = 0 - while i < len(lns): - main = lns[i] - # Skip empty lines - if len(main.strip()) == 0: - i += 1 - continue - if spaces(main) > 0: - raise Exception("Line "+str(i)+" indented too much!") - main = strip_line(main) - # Grab the child block of an if statement - start_child_block = i+1 - indent = 99999999 - i += 1 - child_lns = [] - while i < len(lns): - if len(strip_line(lns[i])) > 0: - sp = spaces(lns[i]) - if sp == 0: break - indent = min(sp,indent) - child_lns.append(lns[i]) - i += 1 - child_block = map(lambda x:x[indent:],child_lns) - # Calls parse_line to parse the individual line - out = parse_line(main) - # Include the child block into the parsed expression - if out[0] in ['if', 'else', 'while', 'else if']: - if len(child_block) == 0: - raise Exception("If/else/while statement must have sub-clause! (%d)" % i) - else: - out.append(parse_lines(child_block)) - else: - if len(child_block) > 0: - raise Exception("Not an if/else/while statement, can't have sub-clause! (%d)" % i) - # This is somewhat complicated. Essentially, it converts something like - # "if c1 then s1 elif c2 then s2 elif c3 then s3 else s4" (with appropriate - # indenting) to [ if c1 s1 [ if c2 s2 [ if c3 s3 s4 ] ] ] - if out[0] == 'else if': - if len(o) == 0: raise Exception("Cannot start with else if! (%d)" % i) - u = o[-1] - while len(u) == 4: u = u[-1] - u.append(['if'] + out[1:]) - elif out[0] == 'else': - if len(o) == 0: raise Exception("Cannot start with else! (%d)" % i) - u = o[-1] - while len(u) == 4: u = u[-1] - u.append(out[1]) - else: - # Normal case: just add the parsed line to the output - o.append(out) - return o[0] if len(o) == 1 else ['seq'] + o - -# Tokens contain one or more chars of the same type, with a few exceptions -def chartype(c): - if c in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.': - return 'alphanum' - elif c in '\t ': return 'space' - elif c in '()[]': return 'brack' - elif c == '"': return 'dquote' - elif c == "'": return 'squote' - else: return 'symb' - -# Converts something like "b[4] = x+2 > y*-3" to -# [ 'b', '[', '4', ']', '=', 'x', '+', '2', '>', 'y', '*', '-', '3' ] -def tokenize(ln): - tp = 'space' - i = 0 - o = [] - global cur - cur = '' - # Finish a token and start a new one - def nxt(): - global cur - if len(cur) >= 2 and cur[-1] == '-': - o.extend([cur[:-1],'-']) - elif len(cur.strip()) >= 1: - o.append(cur) - cur = '' - # Main loop - while i < len(ln): - c = chartype(ln[i]) - # Inside a string - if tp == 'squote' or tp == "dquote": - if c == tp: - cur += ln[i] - nxt() - i += 1 - tp = 'space' - elif ln[i:i+2] == '\\x': - cur += ln[i+2:i+4].decode('hex') - i += 4 - elif ln[i:i+2] == '\\n': - cur += '\x0a' - i += 2 - elif ln[i] == '\\': - cur += ln[i+1] - i += 2 - else: - cur += ln[i] - i += 1 - # Not inside a string - else: - if c == 'brack' or tp == 'brack': nxt() - elif c == 'space': nxt() - elif c != 'space' and tp == 'space': nxt() - elif c == 'symb' and tp != 'symb': nxt() - elif c == 'alphanum' and tp == 'symb': nxt() - elif c == 'squote' or c == "dquote": nxt() - cur += ln[i] - tp = c - i += 1 - nxt() - if o[-1] in [':',':\n','\n']: o.pop() - if tp in ['squote','dquote']: raise Exception("Unclosed string: "+ln) - return o - -# This is the part where we turn a token list into an abstract syntax tree -precedence = { - '^': 1, - '*': 2, - '/': 3, - '%': 4, - '#/': 2, - '#%': 2, - '+': 3, - '-': 3, - '<': 4, - '<=': 4, - '>': 4, - '>=': 4, - '==': 5, - 'and': 6, - '&&': 6, - 'or': 7, - '||': 7, - '!': 0 -} - -def toktype(token): - if token is None: return None - elif token in ['(','[']: return 'left_paren' - elif token in [')',']']: return 'right_paren' - elif token == ',': return 'comma' - elif token == ':': return 'colon' - elif token in ['!']: return 'unary_operation' - elif not isinstance(token,str): return 'compound' - elif token in precedence: return 'binary_operation' - elif re.match('^[0-9a-zA-Z\-\.]*$',token): return 'alphanum' - elif token[0] in ['"',"'"] and token[0] == token[-1]: return 'alphanum' - else: raise Exception("Invalid token: "+token) - -# https://en.wikipedia.org/wiki/Shunting-yard_algorithm -# -# The algorithm works by maintaining three stacks: iq, stack, oq. Initially, -# the tokens are placed in order on the iq. Then, one by one, the tokens are -# processed. Values are moved immediately to the output queue. Operators are -# pushed onto the stack, but if an operator comes along with lower precendence -# then all operators on the stack with higher precedence are applied first. -# For example: -# iq = 2 + 3 * 5 + 7, stack = \, oq = \ -# iq = + 3 * 5 + 7, stack = \, oq = 2 -# iq = 3 * 5 + 7, stack = +, oq = 2 -# iq = * 5 + 7, stack = +, oq = 2 3 -# iq = 5 + 7, stack = + *, oq = 2 3 (since * > + in precedence) -# iq = + 7, stack = + *, oq = 2 3 5 -# iq = 7, stack = + +, oq = 2 [* 3 5] (since + > * in precedence) -# iq = \, stack = + +, oq = 2 [* 3 5] 7 -# iq = \, stack = +, oq = 2 [+ [* 3 5] 7] -# iq = \, stack = \, oq = [+ 2 [+ [* 3 5] 7] ] -# -# Functions, where function arguments begin with a left bracket preceded by -# the function name, are separated by commas, and end with a right bracket, -# are also included in this algorithm, though in a different way -def shunting_yard(tokens): - iq = [x for x in tokens] - oq = [] - stack = [] - prev,tok = None,None - # The normal Shunting-Yard algorithm simply converts expressions into - # reverse polish notation. Here, we try to be slightly more ambitious - # and build up the AST directly on the output queue - # eg. say oq = [ 2, 5, 3 ] and we add "+" then "*" - # we get first [ 2, [ +, 5, 3 ] ] then [ [ *, 2, [ +, 5, 3 ] ] ] - def popstack(stack,oq): - tok = stack.pop() - typ = toktype(tok) - if typ == 'binary_operation': - a,b = oq.pop(), oq.pop() - oq.append([ tok, b, a]) - elif typ == 'unary_operation': - a = oq.pop() - oq.append([ tok, a ]) - elif typ == 'right_paren': - args = [] - while toktype(oq[-1]) != 'left_paren': - args.insert(0,oq.pop()) - oq.pop() - if tok == ']' and args[0] != 'id': - oq.append(['access'] + args) - elif tok == ']': - oq.append(['array_lit'] + args[1:]) - elif tok == ')' and len(args) and args[0] != 'id': - oq.append(args) - else: - oq.append(args[1]) - # The main loop - while len(iq) > 0: - prev = tok - tok = iq.pop(0) - typ = toktype(tok) - if typ == 'alphanum': - oq.append(tok) - elif typ == 'left_paren': - # Handle cases like 3 * (2 + 5) by using 'id' as a default function - # name - if toktype(prev) != 'alphanum' and toktype(prev) != 'right_paren': - oq.append('id') - # Say the statement is "... f(45...". At the start, we would have f - # as the last item on the oq. So we move it onto the stack, put the - # leftparen on the oq, and move f back to the stack, so we have ( f - # as the last two items on the oq. We also put the leftparen on the - # stack so we have a separator on both the stack and the oq - stack.append(oq.pop()) - oq.append(tok) - oq.append(stack.pop()) - stack.append(tok) - elif typ == 'right_paren': - # eg. f(27, 3 * 5 + 4). First, we finish evaluating all the - # arithmetic inside the last argument. Then, we run popstack - # to coalesce all of the function arguments sitting on the - # oq into a single list - while len(stack) and toktype(stack[-1]) != 'left_paren': - popstack(stack,oq) - if len(stack): - stack.pop() - stack.append(tok) - popstack(stack,oq) - elif typ == 'unary_operation' or typ == 'binary_operation': - # -5 -> 0 - 5 - if tok == '-' and toktype(prev) not in ['alphanum', 'right_paren']: - oq.append('0') - # Handle BEDMAS operator precedence - prec = precedence[tok] - while len(stack) and toktype(stack[-1]) == 'binary_operation' and precedence[stack[-1]] < prec: - popstack(stack,oq) - stack.append(tok) - elif typ == 'comma': - # Finish evaluating all arithmetic before the comma - while len(stack) and toktype(stack[-1]) != 'left_paren': - popstack(stack,oq) - elif typ == 'colon': - # Colon is like a comma except it stays in the argument list - while len(stack) and toktype(stack[-1]) != 'right_paren': - popstack(stack,oq) - oq.append(tok) - while len(stack): - popstack(stack,oq) - if len(oq) == 1: - return oq[0] - else: - raise Exception("Wrong number of items left on stack: "+str(oq)) - -def parse_line(ln): - tokens = tokenize(ln.strip()) - if tokens[0] == 'if' or tokens[0] == 'while': - return [ tokens[0], shunting_yard(tokens[1:]) ] - elif len(tokens) >= 2 and tokens[0] == 'else' and tokens[1] == 'if': - return [ 'else if', shunting_yard(tokens[2:]) ] - elif len(tokens) >= 1 and tokens[0] == 'elif': - return [ 'else if', shunting_yard(tokens[1:]) ] - elif len(tokens) == 1 and tokens[0] == 'else': - return [ 'else' ] - elif '=' in tokens: - eqplace = tokens.index('=') - return [ 'set', shunting_yard(tokens[:eqplace]), shunting_yard(tokens[eqplace+1:]) ] - else: - return shunting_yard(tokens) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index be6e1f92d..7e49a51ee 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -8,6 +8,8 @@ link_directories(../libethereum) add_executable(testeth ${SRC_LIST}) +FIND_PACKAGE(Boost 1.53 REQUIRED COMPONENTS unit_test_framework) + if (${TARGET_PLATFORM} STREQUAL "w64") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") target_link_libraries(testeth gcc) diff --git a/test/trie.cpp b/test/trie.cpp index 1ba698333..51735ed90 100644 --- a/test/trie.cpp +++ b/test/trie.cpp @@ -55,13 +55,18 @@ BOOST_AUTO_TEST_CASE(trie_tests) js::read_string(s, v); for (auto& i: v.get_obj()) { + cnote << i.first; js::mObject& o = i.second.get_obj(); -// cnote << i.first; vector> ss; - for (auto& i: o["in"].get_obj()) + for (auto i: o["in"].get_obj()) + { ss.push_back(make_pair(i.first, i.second.get_str())); - cnote << ss; - for (unsigned j = 0; j < eth::test::fac((unsigned)ss.size()); ++j) + if (!ss.back().first.find("0x")) + ss.back().first = asString(fromHex(ss.back().first.substr(2))); + if (!ss.back().second.find("0x")) + ss.back().second = asString(fromHex(ss.back().second.substr(2))); + } + for (unsigned j = 0; j < min(1000u, eth::test::fac((unsigned)ss.size())); ++j) { next_permutation(ss.begin(), ss.end()); MemoryDB m; @@ -70,7 +75,6 @@ BOOST_AUTO_TEST_CASE(trie_tests) BOOST_REQUIRE(t.check(true)); for (auto const& k: ss) { -// cdebug << k.first << k.second; t.insert(k.first, k.second); BOOST_REQUIRE(t.check(true)); }