From a4e46e665aac0aa26afa37a22eaf44941d856d9f Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Mon, 26 May 2014 11:22:19 +0200
Subject: Major reorganisation. New libs (libethsupport, libevm, liblll). New
 LLLC binary.

---
 Assembly.cpp      |   0
 Assembly.h        |   0
 CMakeLists.txt    |  70 ++++++
 CodeFragment.cpp  | 701 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 CodeFragment.h    | 157 ++++++++++++
 Compiler.cpp      |  61 +++++
 Compiler.h        |  35 +++
 CompilerState.cpp |  37 +++
 CompilerState.h   |  49 ++++
 Parser.cpp        |  91 +++++++
 Parser.h          |  38 +++
 11 files changed, 1239 insertions(+)
 create mode 100644 Assembly.cpp
 create mode 100644 Assembly.h
 create mode 100644 CMakeLists.txt
 create mode 100644 CodeFragment.cpp
 create mode 100644 CodeFragment.h
 create mode 100644 Compiler.cpp
 create mode 100644 Compiler.h
 create mode 100644 CompilerState.cpp
 create mode 100644 CompilerState.h
 create mode 100644 Parser.cpp
 create mode 100644 Parser.h

diff --git a/Assembly.cpp b/Assembly.cpp
new file mode 100644
index 00000000..e69de29b
diff --git a/Assembly.h b/Assembly.h
new file mode 100644
index 00000000..e69de29b
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 00000000..dc5fc222
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,70 @@
+cmake_policy(SET CMP0015 NEW)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
+
+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()
+file(GLOB HEADERS "*.h") 
+
+include_directories(..)
+include_directories(${MINIUPNPC_ID})
+include_directories(${LEVELDB_ID})
+
+target_link_libraries(${EXECUTABLE} ethcore)
+target_link_libraries(${EXECUTABLE} ethsupport)
+target_link_libraries(${EXECUTABLE} secp256k1)
+target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS})
+target_link_libraries(${EXECUTABLE} ${LEVELDB_LS})
+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)
+	target_link_libraries(${EXECUTABLE} mswsock)
+	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})
+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/CodeFragment.cpp b/CodeFragment.cpp
new file mode 100644
index 00000000..854a27c4
--- /dev/null
+++ b/CodeFragment.cpp
@@ -0,0 +1,701 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file CodeFragment.cpp
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#include "Parser.h"
+#include "CodeFragment.h"
+
+#include <boost/algorithm/string.hpp>
+#include <boost/spirit/include/support_utree.hpp>
+#include <libethsupport/Log.h>
+#include <libethcore/Instruction.h>
+#include <libethcore/CommonEth.h>
+#include "CompilerState.h"
+using namespace std;
+using namespace eth;
+namespace qi = boost::spirit::qi;
+namespace px = boost::phoenix;
+namespace sp = boost::spirit;
+
+void eth::debugOutAST(ostream& _out, sp::utree const& _this)
+{
+	switch (_this.which())
+	{
+	case sp::utree_type::list_type:
+		switch (_this.tag())
+		{
+		case 0: _out << "( "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << ")"; break;
+		case 1: _out << "@ "; debugOutAST(_out, _this.front()); break;
+		case 2: _out << "@@ "; debugOutAST(_out, _this.front()); break;
+		case 3: _out << "[ "; debugOutAST(_out, _this.front()); _out << " ] "; debugOutAST(_out, _this.back()); break;
+		case 4: _out << "[[ "; debugOutAST(_out, _this.front()); _out << " ]] "; debugOutAST(_out, _this.back()); break;
+		case 5: _out << "{ "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << "}"; break;
+		default:;
+		}
+
+		break;
+	case sp::utree_type::int_type: _out << _this.get<int>(); break;
+	case sp::utree_type::string_type: _out << "\"" << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>() << "\""; break;
+	case sp::utree_type::symbol_type: _out << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>(); break;
+	case sp::utree_type::any_type: _out << *_this.get<bigint*>(); break;
+	default: _out << "nil";
+	}
+}
+
+CodeLocation::CodeLocation(CodeFragment* _f)
+{
+	m_f = _f;
+	m_pos = _f->m_code.size();
+}
+
+unsigned CodeLocation::get() const
+{
+	assert(m_f->m_code[m_pos - 1] == (byte)Instruction::PUSH4);
+	bytesConstRef r(&m_f->m_code[m_pos], 4);
+	cdebug << toHex(r);
+	return fromBigEndian<uint32_t>(r);
+}
+
+void CodeLocation::set(unsigned _val)
+{
+	assert(m_f->m_code[m_pos - 1] == (byte)Instruction::PUSH4);
+	assert(!get());
+	bytesRef r(&m_f->m_code[m_pos], 4);
+	toBigEndian(_val, r);
+}
+
+void CodeLocation::anchor()
+{
+	set(m_f->m_code.size());
+}
+
+void CodeLocation::increase(unsigned _val)
+{
+	assert(m_f->m_code[m_pos - 1] == (byte)Instruction::PUSH4);
+	bytesRef r(&m_f->m_code[m_pos], 4);
+	toBigEndian(get() + _val, r);
+}
+
+void CodeFragment::appendFragment(CodeFragment const& _f)
+{
+	m_locs.reserve(m_locs.size() + _f.m_locs.size());
+	m_code.reserve(m_code.size() + _f.m_code.size());
+
+	unsigned os = m_code.size();
+
+	for (auto i: _f.m_code)
+		m_code.push_back(i);
+
+	for (auto i: _f.m_locs)
+	{
+		CodeLocation(this, i + os).increase(os);
+		m_locs.push_back(i + os);
+	}
+
+	for (auto i: _f.m_data)
+		m_data.insert(make_pair(i.first, i.second + os));
+
+	m_deposit += _f.m_deposit;
+}
+
+CodeFragment CodeFragment::compile(string const& _src, CompilerState& _s)
+{
+	CodeFragment ret;
+	sp::utree o;
+	parseTreeLLL(_src, o);
+	if (!o.empty())
+		ret = CodeFragment(o, _s);
+	_s.treesToKill.push_back(o);
+	return ret;
+}
+
+void CodeFragment::consolidateData()
+{
+	m_code.push_back(0);
+	bytes ld;
+	for (auto const& i: m_data)
+	{
+		if (ld != i.first)
+		{
+			ld = i.first;
+			for (auto j: ld)
+				m_code.push_back(j);
+		}
+		CodeLocation(this, i.second).set(m_code.size() - ld.size());
+	}
+	m_data.clear();
+}
+
+void CodeFragment::appendFragment(CodeFragment const& _f, unsigned _deposit)
+{
+	if ((int)_deposit > _f.m_deposit)
+		error<InvalidDeposit>();
+	else
+	{
+		appendFragment(_f);
+		while (_deposit++ < (unsigned)_f.m_deposit)
+			appendInstruction(Instruction::POP);
+	}
+}
+
+CodeLocation CodeFragment::appendPushLocation(unsigned _locationValue)
+{
+	m_code.push_back((byte)Instruction::PUSH4);
+	CodeLocation ret(this, m_code.size());
+	m_locs.push_back(m_code.size());
+	m_code.resize(m_code.size() + 4);
+	bytesRef r(&m_code[m_code.size() - 4], 4);
+	toBigEndian(_locationValue, r);
+	m_deposit++;
+	return ret;
+}
+
+unsigned CodeFragment::appendPush(u256 _literalValue)
+{
+	unsigned br = max<unsigned>(1, bytesRequired(_literalValue));
+	m_code.push_back((byte)Instruction::PUSH1 + br - 1);
+	m_code.resize(m_code.size() + br);
+	for (unsigned i = 0; i < br; ++i)
+	{
+		m_code[m_code.size() - 1 - i] = (byte)(_literalValue & 0xff);
+		_literalValue >>= 8;
+	}
+	m_deposit++;
+	return br + 1;
+}
+
+void CodeFragment::appendInstruction(Instruction _i)
+{
+	m_code.push_back((byte)_i);
+	m_deposit += c_instructionInfo.at(_i).ret - c_instructionInfo.at(_i).args;
+}
+
+CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowASM)
+{
+/*	cdebug << "CodeFragment. Locals:";
+	for (auto const& i: _s.defs)
+		cdebug << i.first << ":" << toHex(i.second.m_code);
+	cdebug << "Args:";
+	for (auto const& i: _s.args)
+		cdebug << i.first << ":" << toHex(i.second.m_code);
+	cdebug << "Outers:";
+	for (auto const& i: _s.outers)
+		cdebug << i.first << ":" << toHex(i.second.m_code);
+	debugOutAST(cout, _t);
+	cout << endl << flush;
+*/
+	switch (_t.which())
+	{
+	case sp::utree_type::list_type:
+		constructOperation(_t, _s);
+		break;
+	case sp::utree_type::string_type:
+	{
+		auto sr = _t.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
+		string s(sr.begin(), sr.end());
+		if (s.size() > 32)
+			error<StringTooLong>();
+		h256 valHash;
+		memcpy(valHash.data(), s.data(), s.size());
+		memset(valHash.data() + s.size(), 0, 32 - s.size());
+		appendPush(valHash);
+		break;
+	}
+	case sp::utree_type::symbol_type:
+	{
+		auto sr = _t.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
+		string s(sr.begin(), sr.end());
+		string us = boost::algorithm::to_upper_copy(s);
+		if (_allowASM)
+		{
+			if (c_instructions.count(us))
+			{
+				auto it = c_instructions.find(us);
+				m_deposit = c_instructionInfo.at(it->second).ret - c_instructionInfo.at(it->second).args;
+				m_code.push_back((byte)it->second);
+			}
+		}
+		if (_s.defs.count(s))
+			appendFragment(_s.defs.at(s));
+		else if (_s.args.count(s))
+			appendFragment(_s.args.at(s));
+		else if (_s.outers.count(s))
+			appendFragment(_s.outers.at(s));
+		else if (us.find_first_of("1234567890") != 0 && us.find_first_not_of("QWERTYUIOPASDFGHJKLZXCVBNM1234567890_") == string::npos)
+		{
+			auto it = _s.vars.find(s);
+			if (it == _s.vars.end())
+			{
+				bool ok;
+				tie(it, ok) = _s.vars.insert(make_pair(s, _s.vars.size() * 32));
+			}
+			appendPush(it->second);
+		}
+		else
+			error<BareSymbol>();
+
+		break;
+	}
+	case sp::utree_type::any_type:
+	{
+		bigint i = *_t.get<bigint*>();
+		if (i < 0 || i > bigint(u256(0) - 1))
+			error<IntegerOutOfRange>();
+		appendPush((u256)i);
+		break;
+	}
+	default: break;
+	}
+}
+
+void CodeFragment::appendPushDataLocation(bytes const& _data)
+{
+	m_code.push_back((byte)Instruction::PUSH4);
+	m_data.insert(make_pair(_data, m_code.size()));
+	m_code.resize(m_code.size() + 4);
+	memset(&m_code.back() - 3, 0, 4);
+	m_deposit++;
+}
+
+std::string CodeFragment::asPushedString() const
+{
+	string ret;
+	if (m_code.size())
+	{
+		unsigned bc = m_code[0] - (byte)Instruction::PUSH1 + 1;
+		if (m_code[0] >= (byte)Instruction::PUSH1 && m_code[0] <= (byte)Instruction::PUSH32)
+		{
+			for (unsigned s = 0; s < bc && m_code[1 + s]; ++s)
+				ret.push_back(m_code[1 + s]);
+			return ret;
+		}
+	}
+	error<ExpectedLiteral>();
+	return ret;
+}
+
+void CodeFragment::optimise()
+{
+//	map<string, function<bytes(vector<u256> const&)>> pattern = { { "PUSH,PUSH,ADD", [](vector<u256> const& v) { return CodeFragment(appendPush(v[0] + v[1])); } } };
+}
+
+void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
+{
+	if (_t.empty())
+		error<EmptyList>();
+	else if (_t.tag() == 0 && _t.front().which() != sp::utree_type::symbol_type)
+		error<DataNotExecutable>();
+	else
+	{
+		string s;
+		string us;
+		switch (_t.tag())
+		{
+		case 0:
+		{
+			auto sr = _t.front().get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
+			s = string(sr.begin(), sr.end());
+			us = boost::algorithm::to_upper_copy(s);
+			break;
+		}
+		case 1:
+			us = "MLOAD";
+			break;
+		case 2:
+			us = "SLOAD";
+			break;
+		case 3:
+			us = "MSTORE";
+			break;
+		case 4:
+			us = "SSTORE";
+			break;
+		case 5:
+			us = "SEQ";
+			break;
+		default:;
+		}
+
+		// Operations who args are not standard stack-pushers.
+		bool nonStandard = true;
+		if (us == "ASM")
+		{
+			int c = 0;
+			for (auto const& i: _t)
+				if (c++)
+					appendFragment(CodeFragment(i, _s, true));
+		}
+		else if (us == "INCLUDE")
+		{
+			if (_t.size() != 2)
+				error<IncorrectParameterCount>();
+			string n;
+			auto i = *++_t.begin();
+			if (i.tag())
+				error<InvalidName>();
+			if (i.which() == sp::utree_type::string_type)
+			{
+				auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
+				n = string(sr.begin(), sr.end());
+			}
+			else if (i.which() == sp::utree_type::symbol_type)
+			{
+				auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
+				n = _s.getDef(string(sr.begin(), sr.end())).asPushedString();
+			}
+			appendFragment(CodeFragment::compile(asString(contents(n)), _s));
+		}
+		else if (us == "DEF")
+		{
+			string n;
+			unsigned ii = 0;
+			if (_t.size() != 3 && _t.size() != 4)
+				error<IncorrectParameterCount>();
+			for (auto const& i: _t)
+			{
+				if (ii == 1)
+				{
+					if (i.tag())
+						error<InvalidName>();
+					if (i.which() == sp::utree_type::string_type)
+					{
+						auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
+						n = string(sr.begin(), sr.end());
+					}
+					else if (i.which() == sp::utree_type::symbol_type)
+					{
+						auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
+						n = _s.getDef(string(sr.begin(), sr.end())).asPushedString();
+					}
+				}
+				else if (ii == 2)
+					if (_t.size() == 3)
+						_s.defs[n] = CodeFragment(i, _s);
+					else
+						for (auto const& j: i)
+						{
+							if (j.tag() || j.which() != sp::utree_type::symbol_type)
+								error<InvalidMacroArgs>();
+							auto sr = j.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
+							_s.macros[n].args.push_back(string(sr.begin(), sr.end()));
+						}
+				else if (ii == 3)
+				{
+					_s.macros[n].code = i;
+					_s.macros[n].env = _s.outers;
+					for (auto const& i: _s.args)
+						_s.macros[n].env[i.first] = i.second;
+					for (auto const& i: _s.defs)
+						_s.macros[n].env[i.first] = i.second;
+				}
+				++ii;
+			}
+
+		}
+		else if (us == "LIT")
+		{
+			if (_t.size() < 3)
+				error<IncorrectParameterCount>();
+			unsigned ii = 0;
+			CodeFragment pos;
+			bytes data;
+			for (auto const& i: _t)
+			{
+				if (ii == 1)
+				{
+					pos = CodeFragment(i, _s);
+					if (pos.m_deposit != 1)
+						error<InvalidDeposit>();
+				}
+				else if (ii == 2 && !i.tag() && i.which() == sp::utree_type::string_type)
+				{
+					auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
+					data = bytes((byte const*)sr.begin(), (byte const*)sr.end());
+				}
+				else if (ii >= 2 && !i.tag() && i.which() == sp::utree_type::any_type)
+				{
+					bigint bi = *i.get<bigint*>();
+					if (bi < 0)
+						error<IntegerOutOfRange>();
+					else if (bi > bigint(u256(0) - 1))
+					{
+						if (ii == 2 && _t.size() == 3)
+						{
+							// One big int - allow it as hex.
+							data.resize(bytesRequired(bi));
+							toBigEndian(bi, data);
+						}
+						else
+							error<IntegerOutOfRange>();
+					}
+					else
+					{
+						data.resize(data.size() + 32);
+						*(h256*)(&data.back() - 31) = (u256)bi;
+					}
+				}
+				else if (ii)
+					error<InvalidLiteral>();
+				++ii;
+			}
+			appendPush(data.size());
+			appendInstruction(Instruction::DUP);
+			appendPushDataLocation(data);
+			appendFragment(pos, 1);
+			appendInstruction(Instruction::CODECOPY);
+		}
+		else
+			nonStandard = false;
+
+		if (nonStandard)
+			return;
+
+		std::map<std::string, Instruction> const c_arith = { { "+", Instruction::ADD }, { "-", Instruction::SUB }, { "*", Instruction::MUL }, { "/", Instruction::DIV }, { "%", Instruction::MOD }, { "&", Instruction::AND }, { "|", Instruction::OR }, { "^", Instruction::XOR } };
+		std::map<std::string, pair<Instruction, bool>> const c_binary = { { "<", { Instruction::LT, false } }, { "<=", { Instruction::GT, true } }, { ">", { Instruction::GT, false } }, { ">=", { Instruction::LT, true } }, { "S<", { Instruction::SLT, false } }, { "S<=", { Instruction::SGT, true } }, { "S>", { Instruction::SGT, false } }, { "S>=", { Instruction::SLT, true } }, { "=", { Instruction::EQ, false } }, { "!=", { Instruction::EQ, true } } };
+		std::map<std::string, Instruction> const c_unary = { { "!", Instruction::NOT } };
+
+		vector<CodeFragment> code;
+		CompilerState ns = _s;
+		ns.vars.clear();
+		int c = _t.tag() ? 1 : 0;
+		for (auto const& i: _t)
+			if (c++)
+			{
+				if (us == "LLL" && c == 1)
+					code.push_back(CodeFragment(i, ns));
+				else
+					code.push_back(CodeFragment(i, _s));
+			}
+		auto requireSize = [&](unsigned s) { if (code.size() != s) error<IncorrectParameterCount>(); };
+		auto requireMinSize = [&](unsigned s) { if (code.size() < s) error<IncorrectParameterCount>(); };
+		auto requireMaxSize = [&](unsigned s) { if (code.size() > s) error<IncorrectParameterCount>(); };
+		auto requireDeposit = [&](unsigned i, int s) { if (code[i].m_deposit != s) error<InvalidDeposit>(); };
+
+		if (_s.macros.count(s) && _s.macros.at(s).args.size() == code.size())
+		{
+			Macro const& m = _s.macros.at(s);
+			CompilerState cs = _s;
+			for (auto const& i: m.env)
+				cs.outers[i.first] = i.second;
+			for (auto const& i: cs.defs)
+				cs.outers[i.first] = i.second;
+			cs.defs.clear();
+			for (unsigned i = 0; i < m.args.size(); ++i)
+			{
+				requireDeposit(i, 1);
+				cs.args[m.args[i]] = code[i];
+			}
+			appendFragment(CodeFragment(m.code, cs));
+			for (auto const& i: cs.defs)
+				_s.defs[i.first] = i.second;
+			for (auto const& i: cs.macros)
+				_s.macros.insert(i);
+		}
+		else if (c_instructions.count(us))
+		{
+			auto it = c_instructions.find(us);
+			int ea = c_instructionInfo.at(it->second).args;
+			if (ea >= 0)
+				requireSize(ea);
+			else
+				requireMinSize(-ea);
+
+			for (unsigned i = code.size(); i; --i)
+				appendFragment(code[i - 1], 1);
+			appendInstruction(it->second);
+		}
+		else if (c_arith.count(us))
+		{
+			auto it = c_arith.find(us);
+			requireMinSize(1);
+			for (unsigned i = code.size(); i; --i)
+			{
+				requireDeposit(i - 1, 1);
+				appendFragment(code[i - 1], 1);
+			}
+			for (unsigned i = 1; i < code.size(); ++i)
+				appendInstruction(it->second);
+		}
+		else if (c_binary.count(us))
+		{
+			auto it = c_binary.find(us);
+			requireSize(2);
+			requireDeposit(0, 1);
+			requireDeposit(1, 1);
+			appendFragment(code[1], 1);
+			appendFragment(code[0], 1);
+			appendInstruction(it->second.first);
+			if (it->second.second)
+				appendInstruction(Instruction::NOT);
+		}
+		else if (c_unary.count(us))
+		{
+			auto it = c_unary.find(us);
+			requireSize(1);
+			requireDeposit(0, 1);
+			appendFragment(code[0], 1);
+			appendInstruction(it->second);
+		}
+		else if (us == "IF")
+		{
+			requireSize(3);
+			requireDeposit(0, 1);
+			appendFragment(code[0]);
+			auto pos = appendJumpI();
+			onePath();
+			appendFragment(code[2]);
+			auto end = appendJump();
+			otherPath();
+			pos.anchor();
+			appendFragment(code[1]);
+			donePaths();
+			end.anchor();
+		}
+		else if (us == "WHEN" || us == "UNLESS")
+		{
+			requireSize(2);
+			requireDeposit(0, 1);
+			appendFragment(code[0]);
+			if (us == "WHEN")
+				appendInstruction(Instruction::NOT);
+			auto end = appendJumpI();
+			onePath();
+			otherPath();
+			appendFragment(code[1], 0);
+			donePaths();
+			end.anchor();
+		}
+		else if (us == "WHILE")
+		{
+			requireSize(2);
+			requireDeposit(0, 1);
+			auto begin = CodeLocation(this);
+			appendFragment(code[0], 1);
+			appendInstruction(Instruction::NOT);
+			auto end = appendJumpI();
+			appendFragment(code[1], 0);
+			appendJump(begin);
+			end.anchor();
+		}
+		else if (us == "FOR")
+		{
+			requireSize(4);
+			requireDeposit(1, 1);
+			appendFragment(code[0], 0);
+			auto begin = CodeLocation(this);
+			appendFragment(code[1], 1);
+			appendInstruction(Instruction::NOT);
+			auto end = appendJumpI();
+			appendFragment(code[3], 0);
+			appendFragment(code[2], 0);
+			appendJump(begin);
+			end.anchor();
+		}
+		else if (us == "LLL")
+		{
+			requireMinSize(2);
+			requireMaxSize(3);
+			requireDeposit(1, 1);
+
+			CodeLocation codeloc(this, m_code.size() + 6);
+			bytes const& subcode = code[0].code();
+			appendPush(subcode.size());
+			appendInstruction(Instruction::DUP);
+			if (code.size() == 3)
+			{
+				requireDeposit(2, 1);
+				appendFragment(code[2], 1);
+				appendInstruction(Instruction::LT);
+				appendInstruction(Instruction::NOT);
+				appendInstruction(Instruction::MUL);
+				appendInstruction(Instruction::DUP);
+			}
+			appendPushDataLocation(subcode);
+			appendFragment(code[1], 1);
+			appendInstruction(Instruction::CODECOPY);
+		}
+		else if (us == "&&" || us == "||")
+		{
+			requireMinSize(1);
+			for (unsigned i = 0; i < code.size(); ++i)
+				requireDeposit(i, 1);
+
+			vector<CodeLocation> ends;
+			if (code.size() > 1)
+			{
+				appendPush(us == "||" ? 1 : 0);
+				for (unsigned i = 1; i < code.size(); ++i)
+				{
+					// Check if true - predicate
+					appendFragment(code[i - 1], 1);
+					if (us == "&&")
+						appendInstruction(Instruction::NOT);
+					ends.push_back(appendJumpI());
+				}
+				appendInstruction(Instruction::POP);
+			}
+
+			// Check if true - predicate
+			appendFragment(code.back(), 1);
+
+			// At end now.
+			for (auto& i: ends)
+				i.anchor();
+		}
+		else if (us == "~")
+		{
+			requireSize(1);
+			requireDeposit(0, 1);
+			appendFragment(code[0], 1);
+			appendPush(1);
+			appendPush(0);
+			appendInstruction(Instruction::SUB);
+			appendInstruction(Instruction::SUB);
+		}
+		else if (us == "SEQ")
+		{
+			unsigned ii = 0;
+			for (auto const& i: code)
+				if (++ii < code.size())
+					appendFragment(i, 0);
+				else
+					appendFragment(i);
+		}
+		else if (us == "RAW")
+		{
+			for (auto const& i: code)
+				appendFragment(i);
+			while (m_deposit > 1)
+				appendInstruction(Instruction::POP);
+		}
+		else if (us.find_first_of("1234567890") != 0 && us.find_first_not_of("QWERTYUIOPASDFGHJKLZXCVBNM1234567890_") == string::npos)
+		{
+			auto it = _s.vars.find(s);
+			if (it == _s.vars.end())
+			{
+				bool ok;
+				tie(it, ok) = _s.vars.insert(make_pair(s, _s.vars.size() * 32));
+			}
+			appendPush(it->second);
+		}
+		else
+			error<InvalidOperation>();
+	}
+}
diff --git a/CodeFragment.h b/CodeFragment.h
new file mode 100644
index 00000000..82630dbe
--- /dev/null
+++ b/CodeFragment.h
@@ -0,0 +1,157 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file CodeFragment.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#pragma once
+
+#include <libethsupport/Common.h>
+#include <libethcore/Instruction.h>
+#include "Exceptions.h"
+
+namespace boost { namespace spirit { class utree; } }
+namespace sp = boost::spirit;
+
+namespace eth
+{
+
+class CompilerState;
+class CodeFragment;
+
+void debugOutAST(std::ostream& _out, sp::utree const& _this);
+
+class CodeLocation
+{
+	friend class CodeFragment;
+
+public:
+	CodeLocation(CodeFragment* _f);
+	CodeLocation(CodeFragment* _f, unsigned _p): m_f(_f), m_pos(_p) {}
+
+	unsigned get() const;
+	void increase(unsigned _val);
+	void set(unsigned _val);
+	void set(CodeLocation _loc) { assert(_loc.m_f == m_f); set(_loc.m_pos); }
+	void anchor();
+
+	CodeLocation operator+(unsigned _i) const { return CodeLocation(m_f, m_pos + _i); }
+
+private:
+	CodeFragment* m_f;
+	unsigned m_pos;
+};
+
+class CompilerState;
+
+enum AssemblyItemType { Operation, Push, PushString, PushTag, Tag, PushData };
+
+class AssemblyItem
+{
+public:
+	AssemblyItem(u256 _push): m_type(Push), m_data(_push) {}
+	AssemblyItem(std::string const& _push): m_type(PushString), m_pushString(_push) {}
+	AssemblyItem(AssemblyItemType _type, AssemblyItem const& _tag): m_type(_type), m_data(_tag.m_data) { assert(_type == PushTag); assert(_tag.m_type == Tag); }
+	AssemblyItem(Instruction _i): m_type(Operation), m_data((byte)_i) {}
+	AssemblyItem(AssemblyItemType _type, u256 _data): m_type(_type), m_data(_data) {}
+
+	AssemblyItemType type() const { return m_type; }
+	u256 data() const { return m_data; }
+	std::string const& pushString() const { return m_pushString; }
+
+private:
+	AssemblyItemType m_type;
+	u256 m_data;
+	std::string m_pushString;
+};
+
+class Assembly
+{
+public:
+	AssemblyItem newTag() { return AssemblyItem(Tag, m_usedTags++); }
+	AssemblyItem newData(bytes const& _data) { auto h = sha3(_data); m_data[h] = _data; return AssemblyItem(PushData, h); }
+	bytes assemble() const;
+	void append(Assembly const& _a);
+
+private:
+	u256 m_usedTags = 0;
+	std::vector<AssemblyItem> m_items;
+	std::map<h256, bytes> m_data;
+};
+
+class CodeFragment
+{
+	friend class CodeLocation;
+
+public:
+	CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowASM = false);
+	CodeFragment(bytes const& _c = bytes()): m_code(_c) {}
+
+	static CodeFragment compile(std::string const& _src, CompilerState& _s);
+
+	/// Consolidates data and returns code.
+	bytes const& code() { optimise(); consolidateData(); return m_code; }
+
+	unsigned appendPush(u256 _l);
+	void appendFragment(CodeFragment const& _f);
+	void appendFragment(CodeFragment const& _f, unsigned _i);
+	void appendInstruction(Instruction _i);
+
+	CodeLocation appendPushLocation(unsigned _l = 0);
+	void appendPushLocation(CodeLocation _l) { assert(_l.m_f == this); appendPushLocation(_l.m_pos); }
+	void appendPushDataLocation(bytes const& _data);
+
+	CodeLocation appendJump() { auto ret = appendPushLocation(0); appendInstruction(Instruction::JUMP); return ret; }
+	CodeLocation appendJumpI() { auto ret = appendPushLocation(0); appendInstruction(Instruction::JUMPI); return ret; }
+	CodeLocation appendJump(CodeLocation _l) { auto ret = appendPushLocation(_l.m_pos); appendInstruction(Instruction::JUMP); return ret; }
+	CodeLocation appendJumpI(CodeLocation _l) { auto ret = appendPushLocation(_l.m_pos); appendInstruction(Instruction::JUMPI); return ret; }
+
+	void appendFile(std::string const& _fn);
+
+	std::string asPushedString() const;
+
+	void onePath() { assert(!m_totalDeposit && !m_baseDeposit); m_baseDeposit = m_deposit; m_totalDeposit = INT_MAX; }
+	void otherPath() { donePath(); m_totalDeposit = m_deposit; m_deposit = m_baseDeposit; }
+	void donePaths() { donePath(); m_totalDeposit = m_baseDeposit = 0; }
+	void ignored() { m_baseDeposit = m_deposit; }
+	void endIgnored() { m_deposit = m_baseDeposit; m_baseDeposit = 0; }
+
+	bool operator==(CodeFragment const& _f) const { return _f.m_code == m_code && _f.m_data == m_data; }
+	bool operator!=(CodeFragment const& _f) const { return !operator==(_f); }
+	unsigned size() const { return m_code.size(); }
+
+	void consolidateData();
+	void optimise();
+
+private:
+	template <class T> void error() const { throw T(); }
+	void constructOperation(sp::utree const& _t, CompilerState& _s);
+
+	void donePath() { if (m_totalDeposit != INT_MAX && m_totalDeposit != m_deposit) error<InvalidDeposit>(); }
+
+	int m_deposit = 0;
+	int m_baseDeposit = 0;
+	int m_totalDeposit = 0;
+	bytes m_code;
+	std::vector<unsigned> m_locs;
+	std::multimap<bytes, unsigned> m_data;
+};
+
+static const CodeFragment NullCodeFragment;
+
+}
diff --git a/Compiler.cpp b/Compiler.cpp
new file mode 100644
index 00000000..afe84eb4
--- /dev/null
+++ b/Compiler.cpp
@@ -0,0 +1,61 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file Compiler.cpp
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#include "Compiler.h"
+#include "Parser.h"
+#include "CompilerState.h"
+#include "CodeFragment.h"
+
+using namespace std;
+using namespace eth;
+
+bytes eth::compileLLL(string const& _s, vector<string>* _errors)
+{
+	try
+	{
+		CompilerState cs;
+		bytes ret = CodeFragment::compile(_s, cs).code();
+		for (auto i: cs.treesToKill)
+			killBigints(i);
+		return ret;
+	}
+	catch (Exception const& _e)
+	{
+		if (_errors)
+			_errors->push_back(_e.description());
+	}
+	catch (std::exception)
+	{
+		if (_errors)
+			_errors->push_back("Parse error.");
+	}
+	return bytes();
+}
+
+string eth::parseLLL(string const& _src)
+{
+	sp::utree o;
+	parseTreeLLL(_src, o);
+	ostringstream ret;
+	debugOutAST(ret, o);
+	killBigints(o);
+	return ret.str();
+}
diff --git a/Compiler.h b/Compiler.h
new file mode 100644
index 00000000..e58e12ba
--- /dev/null
+++ b/Compiler.h
@@ -0,0 +1,35 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file Compiler.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#pragma once
+
+#include <string>
+#include <vector>
+#include <libethsupport/Common.h>
+
+namespace eth
+{
+
+std::string parseLLL(std::string const& _src);
+bytes compileLLL(std::string const& _s, std::vector<std::string>* _errors = nullptr);
+
+}
+
diff --git a/CompilerState.cpp b/CompilerState.cpp
new file mode 100644
index 00000000..d2894475
--- /dev/null
+++ b/CompilerState.cpp
@@ -0,0 +1,37 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file CompilerState.cpp
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#include "CompilerState.h"
+
+using namespace std;
+using namespace eth;
+
+CodeFragment const& CompilerState::getDef(std::string const& _s)
+{
+	if (defs.count(_s))
+		return defs.at(_s);
+	else if (args.count(_s))
+		return args.at(_s);
+	else if (outers.count(_s))
+		return outers.at(_s);
+	else
+		return NullCodeFragment;
+}
diff --git a/CompilerState.h b/CompilerState.h
new file mode 100644
index 00000000..d53c2bcd
--- /dev/null
+++ b/CompilerState.h
@@ -0,0 +1,49 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file CompilerState.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#pragma once
+
+#include <boost/spirit/include/support_utree.hpp>
+#include "CodeFragment.h"
+
+namespace eth
+{
+
+struct Macro
+{
+	std::vector<std::string> args;
+	boost::spirit::utree code;
+	std::map<std::string, CodeFragment> env;
+};
+
+struct CompilerState
+{
+	CodeFragment const& getDef(std::string const& _s);
+
+	std::map<std::string, unsigned> vars;
+	std::map<std::string, CodeFragment> defs;
+	std::map<std::string, CodeFragment> args;
+	std::map<std::string, CodeFragment> outers;
+	std::map<std::string, Macro> macros;
+	std::vector<boost::spirit::utree> treesToKill;
+};
+
+}
diff --git a/Parser.cpp b/Parser.cpp
new file mode 100644
index 00000000..2a0146a6
--- /dev/null
+++ b/Parser.cpp
@@ -0,0 +1,91 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file Parser.cpp
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#include "Parser.h"
+
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/phoenix.hpp>
+#include <boost/spirit/include/support_utree.hpp>
+#include <libethcore/CommonEth.h>
+
+using namespace std;
+using namespace eth;
+namespace qi = boost::spirit::qi;
+namespace px = boost::phoenix;
+namespace sp = boost::spirit;
+
+void eth::killBigints(sp::utree const& _this)
+{
+	switch (_this.which())
+	{
+	case sp::utree_type::list_type: for (auto const& i: _this) killBigints(i); break;
+	case sp::utree_type::any_type: delete _this.get<bigint*>(); break;
+	default:;
+	}
+}
+
+void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
+{
+	using qi::ascii::space;
+	typedef sp::basic_string<std::string, sp::utree_type::symbol_type> symbol_type;
+	typedef string::const_iterator it;
+
+	qi::rule<it, qi::ascii::space_type, sp::utree()> element;
+	qi::rule<it, string()> str = '"' > qi::lexeme[+(~qi::char_(std::string("\"") + '\0'))] > '"';
+	qi::rule<it, string()> strsh = '\'' > qi::lexeme[+(~qi::char_(std::string(" ;())") + '\0'))];
+	qi::rule<it, symbol_type()> symbol = qi::lexeme[+(~qi::char_(std::string(" @[]{}:();\"\x01-\x1f\x7f") + '\0'))];
+	qi::rule<it, string()> intstr = qi::lexeme[ qi::no_case["0x"][qi::_val = "0x"] >> *qi::char_("0-9a-fA-F")[qi::_val += qi::_1]] | qi::lexeme[+qi::char_("0-9")[qi::_val += qi::_1]];
+	qi::rule<it, bigint()> integer = intstr;
+	qi::rule<it, bigint()> multiplier = qi::lit("wei")[qi::_val = 1] | qi::lit("szabo")[qi::_val = szabo] | qi::lit("finney")[qi::_val = finney] | qi::lit("ether")[qi::_val = ether];
+	qi::rule<it, qi::ascii::space_type, bigint()> quantity = integer[qi::_val = qi::_1] >> -multiplier[qi::_val *= qi::_1];
+	qi::rule<it, qi::ascii::space_type, sp::utree()> atom = quantity[qi::_val = px::construct<sp::any_ptr>(px::new_<bigint>(qi::_1))] | (str | strsh)[qi::_val = qi::_1] | symbol[qi::_val = qi::_1];
+	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> seq = '{' > *element > '}';
+	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> mload = '@' > element;
+	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> sload = qi::lit("@@") > element;
+	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> mstore = '[' > element > ']' > -qi::lit(":") > element;
+	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> sstore = qi::lit("[[") > element > qi::lit("]]") > -qi::lit(":") > element;
+	qi::rule<it, qi::ascii::space_type, sp::utree()> extra = sload[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 2)] | mload[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 1)] | sstore[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 4)] | mstore[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 3)] | seq[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 5)];
+	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> list = '(' > *element > ')';
+	element = atom | list | extra;
+
+	string s;
+	s.reserve(_s.size());
+	bool incomment = false;
+	bool instring = false;
+	bool insstring = false;
+	for (auto i: _s)
+	{
+		if (i == ';' && !instring && !insstring)
+			incomment = true;
+		else if (i == '\n')
+			incomment = instring = insstring = false;
+		else if (i == '"' && !insstring)
+			instring = !instring;
+		else if (i == '\'')
+			insstring = true;
+		else if (i == ' ')
+			insstring = false;
+		if (!incomment)
+			s.push_back(i);
+	}
+	qi::phrase_parse(s.cbegin(), s.cend(), element, space, o_out);
+}
+
diff --git a/Parser.h b/Parser.h
new file mode 100644
index 00000000..3b275657
--- /dev/null
+++ b/Parser.h
@@ -0,0 +1,38 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file Parser.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#pragma once
+
+#include <string>
+#include <vector>
+#include <libethsupport/Common.h>
+
+namespace boost { namespace spirit { class utree; } }
+namespace sp = boost::spirit;
+
+namespace eth
+{
+
+void killBigints(sp::utree const& _this);
+void parseTreeLLL(std::string const& _s, sp::utree& o_out);
+
+}
+
-- 
cgit v1.2.3


From 48f6bad8a3f0290f0439545c799d725a2d5b2d54 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Mon, 26 May 2014 11:34:43 +0200
Subject: Ever more repotting.

---
 Assembly.h       | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 CodeFragment.cpp | 34 -----------------------------
 CodeFragment.h   | 60 +--------------------------------------------------
 CodeLocation.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
 CodeLocation.h   | 54 ++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 180 insertions(+), 93 deletions(-)
 create mode 100644 CodeLocation.cpp
 create mode 100644 CodeLocation.h

diff --git a/Assembly.h b/Assembly.h
index e69de29b..28d2974b 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -0,0 +1,66 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file CodeFragment.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#pragma once
+
+#include <libethsupport/Common.h>
+#include <libethcore/Instruction.h>
+#include "Exceptions.h"
+
+namespace eth
+{
+
+enum AssemblyItemType { Operation, Push, PushString, PushTag, Tag, PushData };
+
+class AssemblyItem
+{
+public:
+	AssemblyItem(u256 _push): m_type(Push), m_data(_push) {}
+	AssemblyItem(std::string const& _push): m_type(PushString), m_pushString(_push) {}
+	AssemblyItem(AssemblyItemType _type, AssemblyItem const& _tag): m_type(_type), m_data(_tag.m_data) { assert(_type == PushTag); assert(_tag.m_type == Tag); }
+	AssemblyItem(Instruction _i): m_type(Operation), m_data((byte)_i) {}
+	AssemblyItem(AssemblyItemType _type, u256 _data): m_type(_type), m_data(_data) {}
+
+	AssemblyItemType type() const { return m_type; }
+	u256 data() const { return m_data; }
+	std::string const& pushString() const { return m_pushString; }
+
+private:
+	AssemblyItemType m_type;
+	u256 m_data;
+	std::string m_pushString;
+};
+
+class Assembly
+{
+public:
+	AssemblyItem newTag() { return AssemblyItem(Tag, m_usedTags++); }
+	AssemblyItem newData(bytes const& _data) { auto h = sha3(_data); m_data[h] = _data; return AssemblyItem(PushData, h); }
+	bytes assemble() const;
+	void append(Assembly const& _a);
+
+private:
+	u256 m_usedTags = 0;
+	std::vector<AssemblyItem> m_items;
+	std::map<h256, bytes> m_data;
+};
+
+}
diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index 854a27c4..cc76c432 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -59,40 +59,6 @@ void eth::debugOutAST(ostream& _out, sp::utree const& _this)
 	}
 }
 
-CodeLocation::CodeLocation(CodeFragment* _f)
-{
-	m_f = _f;
-	m_pos = _f->m_code.size();
-}
-
-unsigned CodeLocation::get() const
-{
-	assert(m_f->m_code[m_pos - 1] == (byte)Instruction::PUSH4);
-	bytesConstRef r(&m_f->m_code[m_pos], 4);
-	cdebug << toHex(r);
-	return fromBigEndian<uint32_t>(r);
-}
-
-void CodeLocation::set(unsigned _val)
-{
-	assert(m_f->m_code[m_pos - 1] == (byte)Instruction::PUSH4);
-	assert(!get());
-	bytesRef r(&m_f->m_code[m_pos], 4);
-	toBigEndian(_val, r);
-}
-
-void CodeLocation::anchor()
-{
-	set(m_f->m_code.size());
-}
-
-void CodeLocation::increase(unsigned _val)
-{
-	assert(m_f->m_code[m_pos - 1] == (byte)Instruction::PUSH4);
-	bytesRef r(&m_f->m_code[m_pos], 4);
-	toBigEndian(get() + _val, r);
-}
-
 void CodeFragment::appendFragment(CodeFragment const& _f)
 {
 	m_locs.reserve(m_locs.size() + _f.m_locs.size());
diff --git a/CodeFragment.h b/CodeFragment.h
index 82630dbe..cee7da3b 100644
--- a/CodeFragment.h
+++ b/CodeFragment.h
@@ -23,6 +23,7 @@
 
 #include <libethsupport/Common.h>
 #include <libethcore/Instruction.h>
+#include "CodeLocation.h"
 #include "Exceptions.h"
 
 namespace boost { namespace spirit { class utree; } }
@@ -31,69 +32,10 @@ namespace sp = boost::spirit;
 namespace eth
 {
 
-class CompilerState;
-class CodeFragment;
-
 void debugOutAST(std::ostream& _out, sp::utree const& _this);
 
-class CodeLocation
-{
-	friend class CodeFragment;
-
-public:
-	CodeLocation(CodeFragment* _f);
-	CodeLocation(CodeFragment* _f, unsigned _p): m_f(_f), m_pos(_p) {}
-
-	unsigned get() const;
-	void increase(unsigned _val);
-	void set(unsigned _val);
-	void set(CodeLocation _loc) { assert(_loc.m_f == m_f); set(_loc.m_pos); }
-	void anchor();
-
-	CodeLocation operator+(unsigned _i) const { return CodeLocation(m_f, m_pos + _i); }
-
-private:
-	CodeFragment* m_f;
-	unsigned m_pos;
-};
-
 class CompilerState;
 
-enum AssemblyItemType { Operation, Push, PushString, PushTag, Tag, PushData };
-
-class AssemblyItem
-{
-public:
-	AssemblyItem(u256 _push): m_type(Push), m_data(_push) {}
-	AssemblyItem(std::string const& _push): m_type(PushString), m_pushString(_push) {}
-	AssemblyItem(AssemblyItemType _type, AssemblyItem const& _tag): m_type(_type), m_data(_tag.m_data) { assert(_type == PushTag); assert(_tag.m_type == Tag); }
-	AssemblyItem(Instruction _i): m_type(Operation), m_data((byte)_i) {}
-	AssemblyItem(AssemblyItemType _type, u256 _data): m_type(_type), m_data(_data) {}
-
-	AssemblyItemType type() const { return m_type; }
-	u256 data() const { return m_data; }
-	std::string const& pushString() const { return m_pushString; }
-
-private:
-	AssemblyItemType m_type;
-	u256 m_data;
-	std::string m_pushString;
-};
-
-class Assembly
-{
-public:
-	AssemblyItem newTag() { return AssemblyItem(Tag, m_usedTags++); }
-	AssemblyItem newData(bytes const& _data) { auto h = sha3(_data); m_data[h] = _data; return AssemblyItem(PushData, h); }
-	bytes assemble() const;
-	void append(Assembly const& _a);
-
-private:
-	u256 m_usedTags = 0;
-	std::vector<AssemblyItem> m_items;
-	std::map<h256, bytes> m_data;
-};
-
 class CodeFragment
 {
 	friend class CodeLocation;
diff --git a/CodeLocation.cpp b/CodeLocation.cpp
new file mode 100644
index 00000000..2c9ca264
--- /dev/null
+++ b/CodeLocation.cpp
@@ -0,0 +1,59 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file CodeLocation.cpp
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#include "CodeLocation.h"
+#include "CodeFragment.h"
+using namespace std;
+using namespace eth;
+
+CodeLocation::CodeLocation(CodeFragment* _f)
+{
+	m_f = _f;
+	m_pos = _f->m_code.size();
+}
+
+unsigned CodeLocation::get() const
+{
+	assert(m_f->m_code[m_pos - 1] == (byte)Instruction::PUSH4);
+	bytesConstRef r(&m_f->m_code[m_pos], 4);
+	return fromBigEndian<uint32_t>(r);
+}
+
+void CodeLocation::set(unsigned _val)
+{
+	assert(m_f->m_code[m_pos - 1] == (byte)Instruction::PUSH4);
+	assert(!get());
+	bytesRef r(&m_f->m_code[m_pos], 4);
+	toBigEndian(_val, r);
+}
+
+void CodeLocation::anchor()
+{
+	set(m_f->m_code.size());
+}
+
+void CodeLocation::increase(unsigned _val)
+{
+	assert(m_f->m_code[m_pos - 1] == (byte)Instruction::PUSH4);
+	bytesRef r(&m_f->m_code[m_pos], 4);
+	toBigEndian(get() + _val, r);
+}
+
diff --git a/CodeLocation.h b/CodeLocation.h
new file mode 100644
index 00000000..c8cf5ee8
--- /dev/null
+++ b/CodeLocation.h
@@ -0,0 +1,54 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file CodeLocation.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#pragma once
+
+#include <libethsupport/Common.h>
+#include <libethcore/Instruction.h>
+#include "Exceptions.h"
+
+namespace eth
+{
+
+class CodeFragment;
+
+class CodeLocation
+{
+	friend class CodeFragment;
+
+public:
+	CodeLocation(CodeFragment* _f);
+	CodeLocation(CodeFragment* _f, unsigned _p): m_f(_f), m_pos(_p) {}
+
+	unsigned get() const;
+	void increase(unsigned _val);
+	void set(unsigned _val);
+	void set(CodeLocation _loc) { assert(_loc.m_f == m_f); set(_loc.m_pos); }
+	void anchor();
+
+	CodeLocation operator+(unsigned _i) const { return CodeLocation(m_f, m_pos + _i); }
+
+private:
+	CodeFragment* m_f;
+	unsigned m_pos;
+};
+
+}
-- 
cgit v1.2.3


From e2d327308d9024cbbb80ea21c056f38591319234 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Mon, 26 May 2014 12:12:22 +0200
Subject: Assembler. Debug trace stuff.

---
 Assembly.cpp     | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 Assembly.h       | 13 ++++++++++---
 CodeFragment.cpp | 25 -------------------------
 CodeFragment.h   |  2 --
 Parser.cpp       | 25 +++++++++++++++++++++++++
 Parser.h         |  1 +
 6 files changed, 89 insertions(+), 30 deletions(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index e69de29b..317a92fc 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -0,0 +1,53 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file Assembly.cpp
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#include "Assembly.h"
+
+#include <libethcore/CommonEth.h>
+
+using namespace std;
+using namespace eth;
+
+void Assembly::append(Assembly const& _a)
+{
+	for (AssemblyItem i: _a.m_items)
+	{
+		if (i.type() == Tag || i.type() == PushTag)
+			i.m_data += m_usedTags;
+		m_items.push_back(i);
+	}
+	for (auto const& i: _a.m_data)
+		m_data.insert(i);
+}
+
+ostream& Assembly::streamOut(ostream& _out) const
+{
+	for (auto const& i: m_items)
+	{
+	}
+	return _out;
+}
+
+bytes Assembly::assemble() const
+{
+	bytes ret;
+	return ret;
+}
diff --git a/Assembly.h b/Assembly.h
index 28d2974b..cbce3ca8 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -21,6 +21,7 @@
 
 #pragma once
 
+#include <iostream>
 #include <libethsupport/Common.h>
 #include <libethcore/Instruction.h>
 #include "Exceptions.h"
@@ -30,23 +31,24 @@ namespace eth
 
 enum AssemblyItemType { Operation, Push, PushString, PushTag, Tag, PushData };
 
+class Assembly;
+
 class AssemblyItem
 {
+	friend class Assembly;
+
 public:
 	AssemblyItem(u256 _push): m_type(Push), m_data(_push) {}
-	AssemblyItem(std::string const& _push): m_type(PushString), m_pushString(_push) {}
 	AssemblyItem(AssemblyItemType _type, AssemblyItem const& _tag): m_type(_type), m_data(_tag.m_data) { assert(_type == PushTag); assert(_tag.m_type == Tag); }
 	AssemblyItem(Instruction _i): m_type(Operation), m_data((byte)_i) {}
 	AssemblyItem(AssemblyItemType _type, u256 _data): m_type(_type), m_data(_data) {}
 
 	AssemblyItemType type() const { return m_type; }
 	u256 data() const { return m_data; }
-	std::string const& pushString() const { return m_pushString; }
 
 private:
 	AssemblyItemType m_type;
 	u256 m_data;
-	std::string m_pushString;
 };
 
 class Assembly
@@ -54,8 +56,13 @@ class Assembly
 public:
 	AssemblyItem newTag() { return AssemblyItem(Tag, 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 b = asBytes(_data); auto h = sha3(b); m_data[h] = b; return AssemblyItem(PushString, h); }
+
+	void append(AssemblyItem const& _i) { m_items.push_back(_i); }
+
 	bytes assemble() const;
 	void append(Assembly const& _a);
+	std::ostream& streamOut(std::ostream& _out) const;
 
 private:
 	u256 m_usedTags = 0;
diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index cc76c432..c4b7ae0b 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -34,31 +34,6 @@ namespace qi = boost::spirit::qi;
 namespace px = boost::phoenix;
 namespace sp = boost::spirit;
 
-void eth::debugOutAST(ostream& _out, sp::utree const& _this)
-{
-	switch (_this.which())
-	{
-	case sp::utree_type::list_type:
-		switch (_this.tag())
-		{
-		case 0: _out << "( "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << ")"; break;
-		case 1: _out << "@ "; debugOutAST(_out, _this.front()); break;
-		case 2: _out << "@@ "; debugOutAST(_out, _this.front()); break;
-		case 3: _out << "[ "; debugOutAST(_out, _this.front()); _out << " ] "; debugOutAST(_out, _this.back()); break;
-		case 4: _out << "[[ "; debugOutAST(_out, _this.front()); _out << " ]] "; debugOutAST(_out, _this.back()); break;
-		case 5: _out << "{ "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << "}"; break;
-		default:;
-		}
-
-		break;
-	case sp::utree_type::int_type: _out << _this.get<int>(); break;
-	case sp::utree_type::string_type: _out << "\"" << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>() << "\""; break;
-	case sp::utree_type::symbol_type: _out << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>(); break;
-	case sp::utree_type::any_type: _out << *_this.get<bigint*>(); break;
-	default: _out << "nil";
-	}
-}
-
 void CodeFragment::appendFragment(CodeFragment const& _f)
 {
 	m_locs.reserve(m_locs.size() + _f.m_locs.size());
diff --git a/CodeFragment.h b/CodeFragment.h
index cee7da3b..9f312cda 100644
--- a/CodeFragment.h
+++ b/CodeFragment.h
@@ -32,8 +32,6 @@ namespace sp = boost::spirit;
 namespace eth
 {
 
-void debugOutAST(std::ostream& _out, sp::utree const& _this);
-
 class CompilerState;
 
 class CodeFragment
diff --git a/Parser.cpp b/Parser.cpp
index 2a0146a6..10d2188a 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -42,6 +42,31 @@ void eth::killBigints(sp::utree const& _this)
 	}
 }
 
+void eth::debugOutAST(ostream& _out, sp::utree const& _this)
+{
+	switch (_this.which())
+	{
+	case sp::utree_type::list_type:
+		switch (_this.tag())
+		{
+		case 0: _out << "( "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << ")"; break;
+		case 1: _out << "@ "; debugOutAST(_out, _this.front()); break;
+		case 2: _out << "@@ "; debugOutAST(_out, _this.front()); break;
+		case 3: _out << "[ "; debugOutAST(_out, _this.front()); _out << " ] "; debugOutAST(_out, _this.back()); break;
+		case 4: _out << "[[ "; debugOutAST(_out, _this.front()); _out << " ]] "; debugOutAST(_out, _this.back()); break;
+		case 5: _out << "{ "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << "}"; break;
+		default:;
+		}
+
+		break;
+	case sp::utree_type::int_type: _out << _this.get<int>(); break;
+	case sp::utree_type::string_type: _out << "\"" << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>() << "\""; break;
+	case sp::utree_type::symbol_type: _out << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>(); break;
+	case sp::utree_type::any_type: _out << *_this.get<bigint*>(); break;
+	default: _out << "nil";
+	}
+}
+
 void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
 {
 	using qi::ascii::space;
diff --git a/Parser.h b/Parser.h
index 3b275657..059ffe6a 100644
--- a/Parser.h
+++ b/Parser.h
@@ -33,6 +33,7 @@ namespace eth
 
 void killBigints(sp::utree const& _this);
 void parseTreeLLL(std::string const& _s, sp::utree& o_out);
+void debugOutAST(std::ostream& _out, sp::utree const& _this);
 
 }
 
-- 
cgit v1.2.3


From 8e3e592ec6a3b39835e540766774025e3f34c590 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Mon, 26 May 2014 12:26:08 +0200
Subject: Add missing files.

---
 Assembly.cpp | 16 +++++++++++++---
 Assembly.h   |  2 ++
 Exceptions.h | 44 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 59 insertions(+), 3 deletions(-)
 create mode 100644 Exceptions.h

diff --git a/Assembly.cpp b/Assembly.cpp
index 317a92fc..a8491376 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -40,9 +40,19 @@ void Assembly::append(Assembly const& _a)
 
 ostream& Assembly::streamOut(ostream& _out) const
 {
-	for (auto const& i: m_items)
-	{
-	}
+	for (AssemblyItem const& i: m_items)
+		switch (i.m_type)
+		{
+		case Operation:
+			_out << c_instructionInfo.at((Instruction)(byte)i.m_data).name << endl;
+			break;
+		case Push:
+			_out << i.m_data << endl;
+			break;
+/*		case PushString:
+			_out << i.m_data << endl;
+			break;*/
+		}
 	return _out;
 }
 
diff --git a/Assembly.h b/Assembly.h
index cbce3ca8..ca3beaf5 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -46,6 +46,8 @@ public:
 	AssemblyItemType type() const { return m_type; }
 	u256 data() const { return m_data; }
 
+	std::ostream& streamOut(std::ostream& _out) const;
+
 private:
 	AssemblyItemType m_type;
 	u256 m_data;
diff --git a/Exceptions.h b/Exceptions.h
new file mode 100644
index 00000000..79b7cd52
--- /dev/null
+++ b/Exceptions.h
@@ -0,0 +1,44 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file Exceptions.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#pragma once
+
+#include <libethcore/Exceptions.h>
+
+namespace eth
+{
+
+/// Compile a Low-level Lisp-like Language program into EVM-code.
+class CompilerException: public Exception {};
+class InvalidOperation: public CompilerException {};
+class IntegerOutOfRange: public CompilerException {};
+class StringTooLong: public CompilerException {};
+class EmptyList: public CompilerException {};
+class DataNotExecutable: public CompilerException {};
+class IncorrectParameterCount: public CompilerException {};
+class InvalidDeposit: public CompilerException {};
+class InvalidName: public CompilerException {};
+class InvalidMacroArgs: public CompilerException {};
+class InvalidLiteral: public CompilerException {};
+class BareSymbol: public CompilerException {};
+class ExpectedLiteral: public CompilerException {};
+
+}
-- 
cgit v1.2.3


From 51e6c251641eef12ba93b725974faa35b514d636 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Mon, 26 May 2014 19:41:46 +0200
Subject: New Assembler.

---
 Assembly.cpp     | 175 +++++++++++++++++++++++++++-
 Assembly.h       |  54 ++++++++-
 CodeFragment.cpp | 338 +++++++++++++++++--------------------------------------
 CodeFragment.h   |  51 ++-------
 CodeLocation.cpp |  59 ----------
 CodeLocation.h   |  54 ---------
 Compiler.cpp     |  27 ++++-
 Compiler.h       |   3 +-
 8 files changed, 357 insertions(+), 404 deletions(-)
 delete mode 100644 CodeLocation.cpp
 delete mode 100644 CodeLocation.h

diff --git a/Assembly.cpp b/Assembly.cpp
index a8491376..1f53cfb5 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -26,38 +26,201 @@
 using namespace std;
 using namespace eth;
 
+int AssemblyItem::deposit() const
+{
+	switch (m_type)
+	{
+	case Operation:
+		return c_instructionInfo.at((Instruction)(byte)m_data).ret - c_instructionInfo.at((Instruction)(byte)m_data).args;
+	case Push: case PushString: case PushTag: case PushData:
+		return 1;
+	case Tag:
+		return 0;
+	}
+	assert(false);
+}
+
+unsigned Assembly::bytesRequired() const
+{
+	for (unsigned br = 1;; ++br)
+	{
+		unsigned ret = 1;
+		for (auto const& i: m_data)
+			ret += i.second.size();
+
+		for (AssemblyItem const& i: m_items)
+			switch (i.m_type)
+			{
+			case Operation:
+				ret++;
+				break;
+			case PushString:
+				ret += 33;
+				break;
+			case Push:
+				ret += 1 + max<unsigned>(1, eth::bytesRequired(i.m_data));
+				break;
+			case PushTag:
+			case PushData:
+				ret += 1 + br;
+			case Tag:;
+			}
+		if (eth::bytesRequired(ret) <= br)
+			return ret;
+	}
+}
+
 void Assembly::append(Assembly const& _a)
 {
 	for (AssemblyItem i: _a.m_items)
 	{
 		if (i.type() == Tag || i.type() == PushTag)
 			i.m_data += m_usedTags;
-		m_items.push_back(i);
+		append(i);
 	}
+	m_usedTags += _a.m_usedTags;
 	for (auto const& i: _a.m_data)
 		m_data.insert(i);
+	for (auto const& i: _a.m_strings)
+		m_strings.insert(i);
+
+	assert(!_a.m_baseDeposit);
+	assert(!_a.m_totalDeposit);
+}
+
+void Assembly::append(Assembly const& _a, int _deposit)
+{
+	if (_deposit > _a.m_deposit)
+		throw InvalidDeposit();
+	else
+	{
+		append(_a);
+		while (_deposit++ < _a.m_deposit)
+			append(Instruction::POP);
+	}
 }
 
 ostream& Assembly::streamOut(ostream& _out) const
 {
+	_out << ".code:" << endl;
 	for (AssemblyItem const& i: m_items)
 		switch (i.m_type)
 		{
 		case Operation:
-			_out << c_instructionInfo.at((Instruction)(byte)i.m_data).name << endl;
+			_out << "  " << c_instructionInfo.at((Instruction)(byte)i.m_data).name << endl;
 			break;
 		case Push:
-			_out << i.m_data << endl;
+			_out << "  PUSH " << i.m_data << endl;
+			break;
+		case PushString:
+			_out << "  PUSH \"" << m_strings.at((h256)i.m_data) << "\"" << endl;
+			break;
+		case PushTag:
+			_out << "  PUSH [tag" << i.m_data << "]" << endl;
+			break;
+		case Tag:
+			_out << "tag" << i.m_data << ": " << endl;
+			break;
+		case PushData:
+			_out << "  PUSH [" << h256(i.m_data).abridged() << "]" << endl;
 			break;
-/*		case PushString:
-			_out << i.m_data << endl;
-			break;*/
 		}
+
+	if (m_data.size())
+	{
+		_out << ".data:" << endl;
+		for (auto const& i: m_data)
+			_out << "  " << i.first.abridged() << ": " << toHex(i.second) << endl;
+	}
 	return _out;
 }
 
+AssemblyItem const& Assembly::append(AssemblyItem const& _i)
+{
+	m_deposit += _i.deposit();
+	m_items.push_back(_i);
+	return back();
+}
+
 bytes Assembly::assemble() const
 {
 	bytes ret;
+
+	unsigned totalBytes = bytesRequired();
+	ret.reserve(totalBytes);
+	vector<unsigned> tagPos(m_usedTags);
+	map<unsigned, unsigned> tagRef;
+	multimap<h256, unsigned> dataRef;
+	unsigned bytesPerTag = eth::bytesRequired(totalBytes);
+	byte tagPush = (byte)Instruction::PUSH1 - 1 + bytesPerTag;
+
+	for (AssemblyItem const& i: m_items)
+		switch (i.m_type)
+		{
+		case Operation:
+			ret.push_back((byte)i.m_data);
+			break;
+		case PushString:
+		{
+			ret.push_back((byte)Instruction::PUSH32);
+			unsigned ii = 0;
+			for (auto j: m_strings.at((h256)i.m_data))
+				if (++ii > 32)
+					break;
+				else
+					ret.push_back((byte)j);
+			while (ii++ < 32)
+				ret.push_back(0);
+			break;
+		}
+		case Push:
+		{
+			byte b = max<unsigned>(1, eth::bytesRequired(i.m_data));
+			ret.push_back((byte)Instruction::PUSH1 - 1 + b);
+			ret.resize(ret.size() + b);
+			bytesRef byr(&ret.back() + 1 - b, b);
+			toBigEndian(i.m_data, byr);
+			break;
+		}
+		case PushTag:
+		{
+			ret.push_back(tagPush);
+			tagRef[ret.size()] = (unsigned)i.m_data;
+			ret.resize(ret.size() + bytesPerTag);
+			break;
+		}
+		case PushData:
+		{
+			ret.push_back(tagPush);
+			dataRef.insert(make_pair((h256)i.m_data, ret.size()));
+			ret.resize(ret.size() + bytesPerTag);
+			break;
+		}
+		case Tag:
+			tagPos[(unsigned)i.m_data] = ret.size();
+			break;
+		}
+
+	for (auto const& i: tagRef)
+	{
+		bytesRef r(ret.data() + i.first, bytesPerTag);
+		toBigEndian(tagPos[i.second], r);
+	}
+
+	if (m_data.size())
+	{
+		ret.push_back(0);
+		for (auto const& i: m_data)
+		{
+			auto its = dataRef.equal_range(i.first);
+			for (auto it = its.first; it != its.second; ++it)
+			{
+				bytesRef r(ret.data() + it->second, bytesPerTag);
+				toBigEndian(ret.size(), r);
+			}
+			for (auto b: i.second)
+				ret.push_back(b);
+		}
+	}
 	return ret;
 }
diff --git a/Assembly.h b/Assembly.h
index ca3beaf5..86b37622 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -22,6 +22,7 @@
 #pragma once
 
 #include <iostream>
+#include <sstream>
 #include <libethsupport/Common.h>
 #include <libethcore/Instruction.h>
 #include "Exceptions.h"
@@ -39,14 +40,16 @@ class AssemblyItem
 
 public:
 	AssemblyItem(u256 _push): m_type(Push), m_data(_push) {}
-	AssemblyItem(AssemblyItemType _type, AssemblyItem const& _tag): m_type(_type), m_data(_tag.m_data) { assert(_type == PushTag); assert(_tag.m_type == Tag); }
 	AssemblyItem(Instruction _i): m_type(Operation), m_data((byte)_i) {}
 	AssemblyItem(AssemblyItemType _type, u256 _data): m_type(_type), m_data(_data) {}
 
+	AssemblyItem tag() const { assert(m_type == PushTag || m_type == Tag); return AssemblyItem(Tag, m_data); }
+	AssemblyItem pushTag() const { assert(m_type == PushTag || m_type == Tag); return AssemblyItem(PushTag, m_data); }
+
 	AssemblyItemType type() const { return m_type; }
 	u256 data() const { return m_data; }
 
-	std::ostream& streamOut(std::ostream& _out) const;
+	int deposit() const;
 
 private:
 	AssemblyItemType m_type;
@@ -57,19 +60,58 @@ 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 b = asBytes(_data); auto h = sha3(b); m_data[h] = b; return AssemblyItem(PushString, h); }
+	AssemblyItem newPushString(std::string const& _data) { auto h = sha3(_data); m_strings[h] = _data; return AssemblyItem(PushString, h); }
+
+	AssemblyItem append() { return append(newTag()); }
+	void append(Assembly const& _a);
+	void append(Assembly const& _a, int _deposit);
+	AssemblyItem const& append(AssemblyItem const& _i);
+	AssemblyItem const& append(std::string const& _data) { return append(newPushString(_data)); }
+	AssemblyItem const& append(bytes const& _data) { return append(newData(_data)); }
+
+	AssemblyItem appendJump() { auto ret = append(newPushTag()); append(Instruction::JUMP); return ret; }
+	AssemblyItem appendJumpI() { auto ret = append(newPushTag()); append(Instruction::JUMPI); return ret; }
+	AssemblyItem appendJump(AssemblyItem const& _tag) { auto ret = append(_tag.pushTag()); append(Instruction::JUMP); return ret; }
+	AssemblyItem appendJumpI(AssemblyItem const& _tag) { auto ret = append(_tag.pushTag()); append(Instruction::JUMPI); return ret; }
+
+	template <class T> Assembly& operator<<(T const& _d) { append(_d); return *this; }
+
+	AssemblyItem const& back() { return m_items.back(); }
+	std::string backString() const { return m_items.back().m_type == PushString ? m_strings.at((h256)m_items.back().m_data) : std::string(); }
 
-	void append(AssemblyItem const& _i) { m_items.push_back(_i); }
+	void onePath() { assert(!m_totalDeposit && !m_baseDeposit); m_baseDeposit = m_deposit; m_totalDeposit = INT_MAX; }
+	void otherPath() { donePath(); m_totalDeposit = m_deposit; m_deposit = m_baseDeposit; }
+	void donePaths() { donePath(); m_totalDeposit = m_baseDeposit = 0; }
+	void ignored() { m_baseDeposit = m_deposit; }
+	void endIgnored() { m_deposit = m_baseDeposit; m_baseDeposit = 0; }
 
+	void popTo(int _deposit) { while (m_deposit > _deposit) append(Instruction::POP); }
+
+	std::string out() const { std::stringstream ret; streamOut(ret); return ret.str(); }
+	int deposit() const { return m_deposit; }
 	bytes assemble() const;
-	void append(Assembly const& _a);
 	std::ostream& streamOut(std::ostream& _out) const;
 
 private:
-	u256 m_usedTags = 0;
+	void donePath() { if (m_totalDeposit != INT_MAX && m_totalDeposit != m_deposit) throw InvalidDeposit(); }
+	unsigned bytesRequired() const;
+
+	unsigned m_usedTags = 0;
 	std::vector<AssemblyItem> m_items;
 	std::map<h256, bytes> m_data;
+	std::map<h256, std::string> m_strings;
+
+	int m_deposit = 0;
+	int m_baseDeposit = 0;
+	int m_totalDeposit = 0;
 };
 
+inline std::ostream& operator<<(std::ostream& _out, Assembly const& _a)
+{
+	_a.streamOut(_out);
+	return _out;
+}
+
 }
diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index c4b7ae0b..59ff729e 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -34,100 +34,6 @@ namespace qi = boost::spirit::qi;
 namespace px = boost::phoenix;
 namespace sp = boost::spirit;
 
-void CodeFragment::appendFragment(CodeFragment const& _f)
-{
-	m_locs.reserve(m_locs.size() + _f.m_locs.size());
-	m_code.reserve(m_code.size() + _f.m_code.size());
-
-	unsigned os = m_code.size();
-
-	for (auto i: _f.m_code)
-		m_code.push_back(i);
-
-	for (auto i: _f.m_locs)
-	{
-		CodeLocation(this, i + os).increase(os);
-		m_locs.push_back(i + os);
-	}
-
-	for (auto i: _f.m_data)
-		m_data.insert(make_pair(i.first, i.second + os));
-
-	m_deposit += _f.m_deposit;
-}
-
-CodeFragment CodeFragment::compile(string const& _src, CompilerState& _s)
-{
-	CodeFragment ret;
-	sp::utree o;
-	parseTreeLLL(_src, o);
-	if (!o.empty())
-		ret = CodeFragment(o, _s);
-	_s.treesToKill.push_back(o);
-	return ret;
-}
-
-void CodeFragment::consolidateData()
-{
-	m_code.push_back(0);
-	bytes ld;
-	for (auto const& i: m_data)
-	{
-		if (ld != i.first)
-		{
-			ld = i.first;
-			for (auto j: ld)
-				m_code.push_back(j);
-		}
-		CodeLocation(this, i.second).set(m_code.size() - ld.size());
-	}
-	m_data.clear();
-}
-
-void CodeFragment::appendFragment(CodeFragment const& _f, unsigned _deposit)
-{
-	if ((int)_deposit > _f.m_deposit)
-		error<InvalidDeposit>();
-	else
-	{
-		appendFragment(_f);
-		while (_deposit++ < (unsigned)_f.m_deposit)
-			appendInstruction(Instruction::POP);
-	}
-}
-
-CodeLocation CodeFragment::appendPushLocation(unsigned _locationValue)
-{
-	m_code.push_back((byte)Instruction::PUSH4);
-	CodeLocation ret(this, m_code.size());
-	m_locs.push_back(m_code.size());
-	m_code.resize(m_code.size() + 4);
-	bytesRef r(&m_code[m_code.size() - 4], 4);
-	toBigEndian(_locationValue, r);
-	m_deposit++;
-	return ret;
-}
-
-unsigned CodeFragment::appendPush(u256 _literalValue)
-{
-	unsigned br = max<unsigned>(1, bytesRequired(_literalValue));
-	m_code.push_back((byte)Instruction::PUSH1 + br - 1);
-	m_code.resize(m_code.size() + br);
-	for (unsigned i = 0; i < br; ++i)
-	{
-		m_code[m_code.size() - 1 - i] = (byte)(_literalValue & 0xff);
-		_literalValue >>= 8;
-	}
-	m_deposit++;
-	return br + 1;
-}
-
-void CodeFragment::appendInstruction(Instruction _i)
-{
-	m_code.push_back((byte)_i);
-	m_deposit += c_instructionInfo.at(_i).ret - c_instructionInfo.at(_i).args;
-}
-
 CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowASM)
 {
 /*	cdebug << "CodeFragment. Locals:";
@@ -151,12 +57,7 @@ CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowAS
 	{
 		auto sr = _t.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
 		string s(sr.begin(), sr.end());
-		if (s.size() > 32)
-			error<StringTooLong>();
-		h256 valHash;
-		memcpy(valHash.data(), s.data(), s.size());
-		memset(valHash.data() + s.size(), 0, 32 - s.size());
-		appendPush(valHash);
+		m_asm.append(s);
 		break;
 	}
 	case sp::utree_type::symbol_type:
@@ -164,21 +65,14 @@ CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowAS
 		auto sr = _t.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
 		string s(sr.begin(), sr.end());
 		string us = boost::algorithm::to_upper_copy(s);
-		if (_allowASM)
-		{
-			if (c_instructions.count(us))
-			{
-				auto it = c_instructions.find(us);
-				m_deposit = c_instructionInfo.at(it->second).ret - c_instructionInfo.at(it->second).args;
-				m_code.push_back((byte)it->second);
-			}
-		}
+		if (_allowASM && c_instructions.count(us))
+			m_asm.append(c_instructions.at(us));
 		if (_s.defs.count(s))
-			appendFragment(_s.defs.at(s));
+			m_asm.append(_s.defs.at(s).m_asm);
 		else if (_s.args.count(s))
-			appendFragment(_s.args.at(s));
+			m_asm.append(_s.args.at(s).m_asm);
 		else if (_s.outers.count(s))
-			appendFragment(_s.outers.at(s));
+			m_asm.append(_s.outers.at(s).m_asm);
 		else if (us.find_first_of("1234567890") != 0 && us.find_first_not_of("QWERTYUIOPASDFGHJKLZXCVBNM1234567890_") == string::npos)
 		{
 			auto it = _s.vars.find(s);
@@ -187,7 +81,7 @@ CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowAS
 				bool ok;
 				tie(it, ok) = _s.vars.insert(make_pair(s, _s.vars.size() * 32));
 			}
-			appendPush(it->second);
+			m_asm.append((u256)it->second);
 		}
 		else
 			error<BareSymbol>();
@@ -199,44 +93,13 @@ CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowAS
 		bigint i = *_t.get<bigint*>();
 		if (i < 0 || i > bigint(u256(0) - 1))
 			error<IntegerOutOfRange>();
-		appendPush((u256)i);
+		m_asm.append((u256)i);
 		break;
 	}
 	default: break;
 	}
 }
 
-void CodeFragment::appendPushDataLocation(bytes const& _data)
-{
-	m_code.push_back((byte)Instruction::PUSH4);
-	m_data.insert(make_pair(_data, m_code.size()));
-	m_code.resize(m_code.size() + 4);
-	memset(&m_code.back() - 3, 0, 4);
-	m_deposit++;
-}
-
-std::string CodeFragment::asPushedString() const
-{
-	string ret;
-	if (m_code.size())
-	{
-		unsigned bc = m_code[0] - (byte)Instruction::PUSH1 + 1;
-		if (m_code[0] >= (byte)Instruction::PUSH1 && m_code[0] <= (byte)Instruction::PUSH32)
-		{
-			for (unsigned s = 0; s < bc && m_code[1 + s]; ++s)
-				ret.push_back(m_code[1 + s]);
-			return ret;
-		}
-	}
-	error<ExpectedLiteral>();
-	return ret;
-}
-
-void CodeFragment::optimise()
-{
-//	map<string, function<bytes(vector<u256> const&)>> pattern = { { "PUSH,PUSH,ADD", [](vector<u256> const& v) { return CodeFragment(appendPush(v[0] + v[1])); } } };
-}
-
 void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 {
 	if (_t.empty())
@@ -281,7 +144,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 			int c = 0;
 			for (auto const& i: _t)
 				if (c++)
-					appendFragment(CodeFragment(i, _s, true));
+					m_asm.append(CodeFragment(i, _s, true).m_asm);
 		}
 		else if (us == "INCLUDE")
 		{
@@ -299,9 +162,9 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 			else if (i.which() == sp::utree_type::symbol_type)
 			{
 				auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
-				n = _s.getDef(string(sr.begin(), sr.end())).asPushedString();
+				n = _s.getDef(string(sr.begin(), sr.end())).m_asm.backString();
 			}
-			appendFragment(CodeFragment::compile(asString(contents(n)), _s));
+			m_asm.append(CodeFragment::compile(asString(contents(n)), _s).m_asm);
 		}
 		else if (us == "DEF")
 		{
@@ -323,7 +186,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 					else if (i.which() == sp::utree_type::symbol_type)
 					{
 						auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
-						n = _s.getDef(string(sr.begin(), sr.end())).asPushedString();
+						n = _s.getDef(string(sr.begin(), sr.end())).m_asm.backString();
 					}
 				}
 				else if (ii == 2)
@@ -362,7 +225,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 				if (ii == 1)
 				{
 					pos = CodeFragment(i, _s);
-					if (pos.m_deposit != 1)
+					if (pos.m_asm.deposit() != 1)
 						error<InvalidDeposit>();
 				}
 				else if (ii == 2 && !i.tag() && i.which() == sp::utree_type::string_type)
@@ -396,11 +259,11 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 					error<InvalidLiteral>();
 				++ii;
 			}
-			appendPush(data.size());
-			appendInstruction(Instruction::DUP);
-			appendPushDataLocation(data);
-			appendFragment(pos, 1);
-			appendInstruction(Instruction::CODECOPY);
+			m_asm.append((u256)data.size());
+			m_asm.append(Instruction::DUP);
+			m_asm.append(data);
+			m_asm.append(pos.m_asm, 1);
+			m_asm.append(Instruction::CODECOPY);
 		}
 		else
 			nonStandard = false;
@@ -427,7 +290,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 		auto requireSize = [&](unsigned s) { if (code.size() != s) error<IncorrectParameterCount>(); };
 		auto requireMinSize = [&](unsigned s) { if (code.size() < s) error<IncorrectParameterCount>(); };
 		auto requireMaxSize = [&](unsigned s) { if (code.size() > s) error<IncorrectParameterCount>(); };
-		auto requireDeposit = [&](unsigned i, int s) { if (code[i].m_deposit != s) error<InvalidDeposit>(); };
+		auto requireDeposit = [&](unsigned i, int s) { if (code[i].m_asm.deposit() != s) error<InvalidDeposit>(); };
 
 		if (_s.macros.count(s) && _s.macros.at(s).args.size() == code.size())
 		{
@@ -443,7 +306,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 				requireDeposit(i, 1);
 				cs.args[m.args[i]] = code[i];
 			}
-			appendFragment(CodeFragment(m.code, cs));
+			m_asm.append(CodeFragment(m.code, cs).m_asm);
 			for (auto const& i: cs.defs)
 				_s.defs[i.first] = i.second;
 			for (auto const& i: cs.macros)
@@ -459,8 +322,8 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 				requireMinSize(-ea);
 
 			for (unsigned i = code.size(); i; --i)
-				appendFragment(code[i - 1], 1);
-			appendInstruction(it->second);
+				m_asm.append(code[i - 1].m_asm, 1);
+			m_asm.append(it->second);
 		}
 		else if (c_arith.count(us))
 		{
@@ -469,10 +332,10 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 			for (unsigned i = code.size(); i; --i)
 			{
 				requireDeposit(i - 1, 1);
-				appendFragment(code[i - 1], 1);
+				m_asm.append(code[i - 1].m_asm, 1);
 			}
 			for (unsigned i = 1; i < code.size(); ++i)
-				appendInstruction(it->second);
+				m_asm.append(it->second);
 		}
 		else if (c_binary.count(us))
 		{
@@ -480,74 +343,75 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 			requireSize(2);
 			requireDeposit(0, 1);
 			requireDeposit(1, 1);
-			appendFragment(code[1], 1);
-			appendFragment(code[0], 1);
-			appendInstruction(it->second.first);
+			m_asm.append(code[1].m_asm, 1);
+			m_asm.append(code[0].m_asm, 1);
+			m_asm.append(it->second.first);
 			if (it->second.second)
-				appendInstruction(Instruction::NOT);
+				m_asm.append(Instruction::NOT);
 		}
 		else if (c_unary.count(us))
 		{
 			auto it = c_unary.find(us);
 			requireSize(1);
 			requireDeposit(0, 1);
-			appendFragment(code[0], 1);
-			appendInstruction(it->second);
+			m_asm.append(code[0].m_asm, 1);
+			m_asm.append(it->second);
 		}
 		else if (us == "IF")
 		{
 			requireSize(3);
 			requireDeposit(0, 1);
-			appendFragment(code[0]);
-			auto pos = appendJumpI();
-			onePath();
-			appendFragment(code[2]);
-			auto end = appendJump();
-			otherPath();
-			pos.anchor();
-			appendFragment(code[1]);
-			donePaths();
-			end.anchor();
+
+			m_asm.append(code[0].m_asm);
+			auto pos = m_asm.appendJumpI();
+			m_asm.onePath();
+			m_asm << code[2].m_asm;
+			auto end = m_asm.appendJump();
+			m_asm.otherPath();
+			m_asm << pos.tag() << code[1].m_asm << end.tag();
+			m_asm.donePaths();
 		}
 		else if (us == "WHEN" || us == "UNLESS")
 		{
 			requireSize(2);
 			requireDeposit(0, 1);
-			appendFragment(code[0]);
+
+			m_asm.append(code[0].m_asm);
 			if (us == "WHEN")
-				appendInstruction(Instruction::NOT);
-			auto end = appendJumpI();
-			onePath();
-			otherPath();
-			appendFragment(code[1], 0);
-			donePaths();
-			end.anchor();
+				m_asm.append(Instruction::NOT);
+			auto end = m_asm.appendJumpI();
+			m_asm.onePath();
+			m_asm.otherPath();
+			m_asm << code[1].m_asm << end.tag();
+			m_asm.donePaths();
 		}
 		else if (us == "WHILE")
 		{
 			requireSize(2);
 			requireDeposit(0, 1);
-			auto begin = CodeLocation(this);
-			appendFragment(code[0], 1);
-			appendInstruction(Instruction::NOT);
-			auto end = appendJumpI();
-			appendFragment(code[1], 0);
-			appendJump(begin);
-			end.anchor();
+
+			auto begin = m_asm.append();
+			m_asm.append(code[0].m_asm);
+			m_asm.append(Instruction::NOT);
+			auto end = m_asm.appendJumpI();
+			m_asm.append(code[1].m_asm, 0);
+			m_asm.appendJump(begin);
+			m_asm << end.tag();
 		}
 		else if (us == "FOR")
 		{
 			requireSize(4);
 			requireDeposit(1, 1);
-			appendFragment(code[0], 0);
-			auto begin = CodeLocation(this);
-			appendFragment(code[1], 1);
-			appendInstruction(Instruction::NOT);
-			auto end = appendJumpI();
-			appendFragment(code[3], 0);
-			appendFragment(code[2], 0);
-			appendJump(begin);
-			end.anchor();
+
+			m_asm.append(code[0].m_asm, 0);
+			auto begin = m_asm.append();
+			m_asm.append(code[1].m_asm);
+			m_asm.append(Instruction::NOT);
+			auto end = m_asm.appendJumpI();
+			m_asm.append(code[3].m_asm, 0);
+			m_asm.append(code[2].m_asm, 0);
+			m_asm.appendJump(begin);
+			m_asm << end.tag();
 		}
 		else if (us == "LLL")
 		{
@@ -555,22 +419,22 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 			requireMaxSize(3);
 			requireDeposit(1, 1);
 
-			CodeLocation codeloc(this, m_code.size() + 6);
 			bytes const& subcode = code[0].code();
-			appendPush(subcode.size());
-			appendInstruction(Instruction::DUP);
+
+			m_asm.append((u256)subcode.size());
+			m_asm.append(Instruction::DUP);
 			if (code.size() == 3)
 			{
 				requireDeposit(2, 1);
-				appendFragment(code[2], 1);
-				appendInstruction(Instruction::LT);
-				appendInstruction(Instruction::NOT);
-				appendInstruction(Instruction::MUL);
-				appendInstruction(Instruction::DUP);
+				m_asm.append(code[2].m_asm, 1);
+				m_asm.append(Instruction::LT);
+				m_asm.append(Instruction::NOT);
+				m_asm.append(Instruction::MUL);
+				m_asm.append(Instruction::DUP);
 			}
-			appendPushDataLocation(subcode);
-			appendFragment(code[1], 1);
-			appendInstruction(Instruction::CODECOPY);
+			m_asm.append(subcode);
+			m_asm.append(code[1].m_asm, 1);
+			m_asm.append(Instruction::CODECOPY);
 		}
 		else if (us == "&&" || us == "||")
 		{
@@ -578,53 +442,52 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 			for (unsigned i = 0; i < code.size(); ++i)
 				requireDeposit(i, 1);
 
-			vector<CodeLocation> ends;
+			auto end = m_asm.newTag();
 			if (code.size() > 1)
 			{
-				appendPush(us == "||" ? 1 : 0);
+				m_asm.append((u256)(us == "||" ? 1 : 0));
 				for (unsigned i = 1; i < code.size(); ++i)
 				{
 					// Check if true - predicate
-					appendFragment(code[i - 1], 1);
+					m_asm.append(code[i - 1].m_asm, 1);
 					if (us == "&&")
-						appendInstruction(Instruction::NOT);
-					ends.push_back(appendJumpI());
+						m_asm.append(Instruction::NOT);
+					m_asm.appendJumpI(end);
 				}
-				appendInstruction(Instruction::POP);
+				m_asm.append(Instruction::POP);
 			}
 
 			// Check if true - predicate
-			appendFragment(code.back(), 1);
+			m_asm.append(code.back().m_asm, 1);
 
 			// At end now.
-			for (auto& i: ends)
-				i.anchor();
+			m_asm.append(end);
 		}
 		else if (us == "~")
 		{
 			requireSize(1);
 			requireDeposit(0, 1);
-			appendFragment(code[0], 1);
-			appendPush(1);
-			appendPush(0);
-			appendInstruction(Instruction::SUB);
-			appendInstruction(Instruction::SUB);
+
+			m_asm.append(code[0].m_asm, 1);
+			m_asm.append((u256)1);
+			m_asm.append((u256)0);
+			m_asm.append(Instruction::SUB);
+			m_asm.append(Instruction::SUB);
 		}
 		else if (us == "SEQ")
 		{
 			unsigned ii = 0;
 			for (auto const& i: code)
 				if (++ii < code.size())
-					appendFragment(i, 0);
+					m_asm.append(i.m_asm, 0);
 				else
-					appendFragment(i);
+					m_asm.append(i.m_asm);
 		}
 		else if (us == "RAW")
 		{
 			for (auto const& i: code)
-				appendFragment(i);
-			while (m_deposit > 1)
-				appendInstruction(Instruction::POP);
+				m_asm.append(i.m_asm);
+			m_asm.popTo(1);
 		}
 		else if (us.find_first_of("1234567890") != 0 && us.find_first_not_of("QWERTYUIOPASDFGHJKLZXCVBNM1234567890_") == string::npos)
 		{
@@ -634,9 +497,20 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 				bool ok;
 				tie(it, ok) = _s.vars.insert(make_pair(s, _s.vars.size() * 32));
 			}
-			appendPush(it->second);
+			m_asm.append((u256)it->second);
 		}
 		else
 			error<InvalidOperation>();
 	}
 }
+
+CodeFragment CodeFragment::compile(string const& _src, CompilerState& _s)
+{
+	CodeFragment ret;
+	sp::utree o;
+	parseTreeLLL(_src, o);
+	if (!o.empty())
+		ret = CodeFragment(o, _s);
+	_s.treesToKill.push_back(o);
+	return ret;
+}
diff --git a/CodeFragment.h b/CodeFragment.h
index 9f312cda..64760484 100644
--- a/CodeFragment.h
+++ b/CodeFragment.h
@@ -23,7 +23,7 @@
 
 #include <libethsupport/Common.h>
 #include <libethcore/Instruction.h>
-#include "CodeLocation.h"
+#include "Assembly.h"
 #include "Exceptions.h"
 
 namespace boost { namespace spirit { class utree; } }
@@ -36,60 +36,23 @@ class CompilerState;
 
 class CodeFragment
 {
-	friend class CodeLocation;
-
 public:
+	CodeFragment() {}
 	CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowASM = false);
-	CodeFragment(bytes const& _c = bytes()): m_code(_c) {}
 
 	static CodeFragment compile(std::string const& _src, CompilerState& _s);
 
-	/// Consolidates data and returns code.
-	bytes const& code() { optimise(); consolidateData(); return m_code; }
-
-	unsigned appendPush(u256 _l);
-	void appendFragment(CodeFragment const& _f);
-	void appendFragment(CodeFragment const& _f, unsigned _i);
-	void appendInstruction(Instruction _i);
-
-	CodeLocation appendPushLocation(unsigned _l = 0);
-	void appendPushLocation(CodeLocation _l) { assert(_l.m_f == this); appendPushLocation(_l.m_pos); }
-	void appendPushDataLocation(bytes const& _data);
-
-	CodeLocation appendJump() { auto ret = appendPushLocation(0); appendInstruction(Instruction::JUMP); return ret; }
-	CodeLocation appendJumpI() { auto ret = appendPushLocation(0); appendInstruction(Instruction::JUMPI); return ret; }
-	CodeLocation appendJump(CodeLocation _l) { auto ret = appendPushLocation(_l.m_pos); appendInstruction(Instruction::JUMP); return ret; }
-	CodeLocation appendJumpI(CodeLocation _l) { auto ret = appendPushLocation(_l.m_pos); appendInstruction(Instruction::JUMPI); return ret; }
-
-	void appendFile(std::string const& _fn);
+	/// Consolidates data and compiles code.
+	bytes code() const { return m_asm.assemble(); }
 
-	std::string asPushedString() const;
-
-	void onePath() { assert(!m_totalDeposit && !m_baseDeposit); m_baseDeposit = m_deposit; m_totalDeposit = INT_MAX; }
-	void otherPath() { donePath(); m_totalDeposit = m_deposit; m_deposit = m_baseDeposit; }
-	void donePaths() { donePath(); m_totalDeposit = m_baseDeposit = 0; }
-	void ignored() { m_baseDeposit = m_deposit; }
-	void endIgnored() { m_deposit = m_baseDeposit; m_baseDeposit = 0; }
-
-	bool operator==(CodeFragment const& _f) const { return _f.m_code == m_code && _f.m_data == m_data; }
-	bool operator!=(CodeFragment const& _f) const { return !operator==(_f); }
-	unsigned size() const { return m_code.size(); }
-
-	void consolidateData();
-	void optimise();
+	/// Consolidates data and compiles code.
+	std::string assembly() const { return m_asm.out(); }
 
 private:
 	template <class T> void error() const { throw T(); }
 	void constructOperation(sp::utree const& _t, CompilerState& _s);
 
-	void donePath() { if (m_totalDeposit != INT_MAX && m_totalDeposit != m_deposit) error<InvalidDeposit>(); }
-
-	int m_deposit = 0;
-	int m_baseDeposit = 0;
-	int m_totalDeposit = 0;
-	bytes m_code;
-	std::vector<unsigned> m_locs;
-	std::multimap<bytes, unsigned> m_data;
+	Assembly m_asm;
 };
 
 static const CodeFragment NullCodeFragment;
diff --git a/CodeLocation.cpp b/CodeLocation.cpp
deleted file mode 100644
index 2c9ca264..00000000
--- a/CodeLocation.cpp
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file CodeLocation.cpp
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#include "CodeLocation.h"
-#include "CodeFragment.h"
-using namespace std;
-using namespace eth;
-
-CodeLocation::CodeLocation(CodeFragment* _f)
-{
-	m_f = _f;
-	m_pos = _f->m_code.size();
-}
-
-unsigned CodeLocation::get() const
-{
-	assert(m_f->m_code[m_pos - 1] == (byte)Instruction::PUSH4);
-	bytesConstRef r(&m_f->m_code[m_pos], 4);
-	return fromBigEndian<uint32_t>(r);
-}
-
-void CodeLocation::set(unsigned _val)
-{
-	assert(m_f->m_code[m_pos - 1] == (byte)Instruction::PUSH4);
-	assert(!get());
-	bytesRef r(&m_f->m_code[m_pos], 4);
-	toBigEndian(_val, r);
-}
-
-void CodeLocation::anchor()
-{
-	set(m_f->m_code.size());
-}
-
-void CodeLocation::increase(unsigned _val)
-{
-	assert(m_f->m_code[m_pos - 1] == (byte)Instruction::PUSH4);
-	bytesRef r(&m_f->m_code[m_pos], 4);
-	toBigEndian(get() + _val, r);
-}
-
diff --git a/CodeLocation.h b/CodeLocation.h
deleted file mode 100644
index c8cf5ee8..00000000
--- a/CodeLocation.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file CodeLocation.h
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#pragma once
-
-#include <libethsupport/Common.h>
-#include <libethcore/Instruction.h>
-#include "Exceptions.h"
-
-namespace eth
-{
-
-class CodeFragment;
-
-class CodeLocation
-{
-	friend class CodeFragment;
-
-public:
-	CodeLocation(CodeFragment* _f);
-	CodeLocation(CodeFragment* _f, unsigned _p): m_f(_f), m_pos(_p) {}
-
-	unsigned get() const;
-	void increase(unsigned _val);
-	void set(unsigned _val);
-	void set(CodeLocation _loc) { assert(_loc.m_f == m_f); set(_loc.m_pos); }
-	void anchor();
-
-	CodeLocation operator+(unsigned _i) const { return CodeLocation(m_f, m_pos + _i); }
-
-private:
-	CodeFragment* m_f;
-	unsigned m_pos;
-};
-
-}
diff --git a/Compiler.cpp b/Compiler.cpp
index afe84eb4..777bb72d 100644
--- a/Compiler.cpp
+++ b/Compiler.cpp
@@ -27,12 +27,12 @@
 using namespace std;
 using namespace eth;
 
-bytes eth::compileLLL(string const& _s, vector<string>* _errors)
+bytes eth::compileLLL(string const& _src, vector<string>* _errors)
 {
 	try
 	{
 		CompilerState cs;
-		bytes ret = CodeFragment::compile(_s, cs).code();
+		bytes ret = CodeFragment::compile(_src, cs).code();
 		for (auto i: cs.treesToKill)
 			killBigints(i);
 		return ret;
@@ -50,6 +50,29 @@ bytes eth::compileLLL(string const& _s, vector<string>* _errors)
 	return bytes();
 }
 
+std::string eth::compileLLLToAsm(std::string const& _src, std::vector<std::string>* _errors)
+{
+	try
+	{
+		CompilerState cs;
+		string ret = CodeFragment::compile(_src, cs).assembly();
+		for (auto i: cs.treesToKill)
+			killBigints(i);
+		return ret;
+	}
+	catch (Exception const& _e)
+	{
+		if (_errors)
+			_errors->push_back(_e.description());
+	}
+	catch (std::exception)
+	{
+		if (_errors)
+			_errors->push_back("Parse error.");
+	}
+	return string();
+}
+
 string eth::parseLLL(string const& _src)
 {
 	sp::utree o;
diff --git a/Compiler.h b/Compiler.h
index e58e12ba..9dd5fc29 100644
--- a/Compiler.h
+++ b/Compiler.h
@@ -29,7 +29,8 @@ namespace eth
 {
 
 std::string parseLLL(std::string const& _src);
-bytes compileLLL(std::string const& _s, std::vector<std::string>* _errors = nullptr);
+std::string compileLLLToAsm(std::string const& _src, std::vector<std::string>* _errors = nullptr);
+bytes compileLLL(std::string const& _src, std::vector<std::string>* _errors = nullptr);
 
 }
 
-- 
cgit v1.2.3


From 8a0dcc26c45c29b86fc4c9ea5195b44c8fe4b493 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Mon, 26 May 2014 20:09:15 +0200
Subject: Convenience fixups.

---
 Assembly.cpp     | 4 ++++
 Assembly.h       | 1 +
 CodeFragment.cpp | 9 ++++++---
 CodeFragment.h   | 4 ++--
 4 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 1f53cfb5..3614bfc4 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -142,6 +142,10 @@ AssemblyItem const& Assembly::append(AssemblyItem const& _i)
 	return back();
 }
 
+void Assembly::optimise()
+{
+}
+
 bytes Assembly::assemble() const
 {
 	bytes ret;
diff --git a/Assembly.h b/Assembly.h
index 86b37622..26392d14 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -92,6 +92,7 @@ public:
 	std::string out() const { std::stringstream ret; streamOut(ret); return ret.str(); }
 	int deposit() const { return m_deposit; }
 	bytes assemble() const;
+	void optimise();
 	std::ostream& streamOut(std::ostream& _out) const;
 
 private:
diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index 59ff729e..299cda5f 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -102,7 +102,7 @@ CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowAS
 
 void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 {
-	if (_t.empty())
+	if (_t.tag() == 0 && _t.empty())
 		error<EmptyList>();
 	else if (_t.tag() == 0 && _t.front().which() != sp::utree_type::symbol_type)
 		error<DataNotExecutable>();
@@ -361,14 +361,17 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 		{
 			requireSize(3);
 			requireDeposit(0, 1);
+			int minDep = min(code[1].m_asm.deposit(), code[2].m_asm.deposit());
 
 			m_asm.append(code[0].m_asm);
 			auto pos = m_asm.appendJumpI();
 			m_asm.onePath();
-			m_asm << code[2].m_asm;
+			m_asm.append(code[2].m_asm, minDep);
 			auto end = m_asm.appendJump();
 			m_asm.otherPath();
-			m_asm << pos.tag() << code[1].m_asm << end.tag();
+			m_asm << pos.tag();
+			m_asm.append(code[1].m_asm, minDep);
+			m_asm << end.tag();
 			m_asm.donePaths();
 		}
 		else if (us == "WHEN" || us == "UNLESS")
diff --git a/CodeFragment.h b/CodeFragment.h
index 64760484..6935a111 100644
--- a/CodeFragment.h
+++ b/CodeFragment.h
@@ -43,10 +43,10 @@ public:
 	static CodeFragment compile(std::string const& _src, CompilerState& _s);
 
 	/// Consolidates data and compiles code.
-	bytes code() const { return m_asm.assemble(); }
+	bytes code() { m_asm.optimise(); return m_asm.assemble(); }
 
 	/// Consolidates data and compiles code.
-	std::string assembly() const { return m_asm.out(); }
+	std::string assembly() { m_asm.optimise(); return m_asm.out(); }
 
 private:
 	template <class T> void error() const { throw T(); }
-- 
cgit v1.2.3


From 52fbe7dbfd57f4e884992b6596d54aadb070bd41 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Tue, 27 May 2014 14:02:15 +0200
Subject: Start of pinhole optimiser. Minor fix for debugger.

---
 Assembly.cpp | 2 ++
 Assembly.h   | 4 ++++
 2 files changed, 6 insertions(+)

diff --git a/Assembly.cpp b/Assembly.cpp
index 3614bfc4..aebe7185 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -144,6 +144,8 @@ AssemblyItem const& Assembly::append(AssemblyItem const& _i)
 
 void Assembly::optimise()
 {
+	std::vector<pair<  vector<int>,  function< vector<AssemblyItem>(vector<AssemblyItem>) >  >> rules;
+//	rules.insert(make_pair({(int)Instruction::ADD, (int)Instruction::ADD, -(int)Push}, []() {}));
 }
 
 bytes Assembly::assemble() const
diff --git a/Assembly.h b/Assembly.h
index 26392d14..5194d23f 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -51,11 +51,15 @@ public:
 
 	int deposit() const;
 
+	bool operator==(int _mask) const { return -_mask == (int)m_type || (m_type == Operation && _mask == (int)m_data); }
+
 private:
 	AssemblyItemType m_type;
 	u256 m_data;
 };
 
+inline bool operator==(int _i, AssemblyItem _ai) { return _ai.operator==(_i); }
+
 class Assembly
 {
 public:
-- 
cgit v1.2.3


From 7476c6884ee22194b7d363c5e5401773d04bf47d Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Tue, 27 May 2014 17:46:57 +0200
Subject: Quick fix for eth -j; thread naming.

---
 Assembly.cpp | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 Assembly.h   |  13 ++++---
 2 files changed, 124 insertions(+), 7 deletions(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index aebe7185..053de61a 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -21,6 +21,7 @@
 
 #include "Assembly.h"
 
+#include <libethsupport/Log.h>
 #include <libethcore/CommonEth.h>
 
 using namespace std;
@@ -36,6 +37,7 @@ int AssemblyItem::deposit() const
 		return 1;
 	case Tag:
 		return 0;
+	default:;
 	}
 	assert(false);
 }
@@ -64,6 +66,7 @@ unsigned Assembly::bytesRequired() const
 			case PushData:
 				ret += 1 + br;
 			case Tag:;
+			default:;
 			}
 		if (eth::bytesRequired(ret) <= br)
 			return ret;
@@ -100,6 +103,36 @@ void Assembly::append(Assembly const& _a, int _deposit)
 	}
 }
 
+ostream& eth::operator<<(ostream& _out, AssemblyItemsConstRef _i)
+{
+	for (AssemblyItem const& i: _i)
+		switch (i.type())
+		{
+		case Operation:
+			_out << " " << c_instructionInfo.at((Instruction)(byte)i.data()).name;
+			break;
+		case Push:
+			_out << " PUSH" << i.data();
+			break;
+		case PushString:
+			_out << " PUSH'[" << h256(i.data()).abridged() << "]";
+			break;
+		case PushTag:
+			_out << " PUSH[tag" << i.data() << "]";
+			break;
+		case Tag:
+			_out << " tag" << i.data() << ":";
+			break;
+		case PushData:
+			_out << " PUSH*[" << h256(i.data()).abridged() << "]";
+			break;
+		case UndefinedItem:
+			_out << " ???";
+		default:;
+		}
+	return _out;
+}
+
 ostream& Assembly::streamOut(ostream& _out) const
 {
 	_out << ".code:" << endl;
@@ -124,6 +157,7 @@ ostream& Assembly::streamOut(ostream& _out) const
 		case PushData:
 			_out << "  PUSH [" << h256(i.m_data).abridged() << "]" << endl;
 			break;
+		default:;
 		}
 
 	if (m_data.size())
@@ -142,10 +176,89 @@ AssemblyItem const& Assembly::append(AssemblyItem const& _i)
 	return back();
 }
 
+inline bool matches(AssemblyItemsConstRef _a, AssemblyItemsConstRef _b)
+{
+	if (_a.size() != _b.size())
+		return false;
+	for (unsigned i = 0; i < _a.size(); ++i)
+		if (!_a[i].match(_b[i]))
+			return false;
+	return true;
+}
+
 void Assembly::optimise()
 {
-	std::vector<pair<  vector<int>,  function< vector<AssemblyItem>(vector<AssemblyItem>) >  >> rules;
-//	rules.insert(make_pair({(int)Instruction::ADD, (int)Instruction::ADD, -(int)Push}, []() {}));
+	map<Instruction, function<u256(u256, u256)>> c_simple =
+	{
+		{ Instruction::SUB, [](u256 a, u256 b)->u256{return a - b;} },
+		{ Instruction::DIV, [](u256 a, u256 b)->u256{return a / b;} },
+		{ Instruction::SDIV, [](u256 a, u256 b)->u256{u256 r; (s256&)r = (s256&)a / (s256&)b; return r;} },
+		{ Instruction::MOD, [](u256 a, u256 b)->u256{return a % b;} },
+		{ Instruction::SMOD, [](u256 a, u256 b)->u256{u256 r; (s256&)r = (s256&)a % (s256&)b; return r;} },
+		{ Instruction::EXP, [](u256 a, u256 b)->u256{return boost::multiprecision::pow(a, (unsigned)b);} },
+		{ Instruction::LT, [](u256 a, u256 b)->u256{return a < b ? 1 : 0;} },
+		{ Instruction::GT, [](u256 a, u256 b)->u256{return a > b ? 1 : 0;} },
+		{ Instruction::SLT, [](u256 a, u256 b)->u256{return *(s256*)&a < *(s256*)&b ? 1 : 0;} },
+		{ Instruction::SGT, [](u256 a, u256 b)->u256{return *(s256*)&a > *(s256*)&b ? 1 : 0;} },
+		{ Instruction::EQ, [](u256 a, u256 b)->u256{return a == b ? 1 : 0;} },
+	};
+	map<Instruction, function<u256(u256, u256)>> c_associative =
+	{
+		{ Instruction::ADD, [](u256 a, u256 b)->u256{return a + b;} },
+		{ Instruction::MUL, [](u256 a, u256 b)->u256{return a * b;} },
+	};
+	std::vector<pair<AssemblyItems, function<AssemblyItems(AssemblyItemsConstRef)>>> rules =
+	{
+		{ { Push, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
+		{ { Push, PushTag, Instruction::JUMPI }, [](AssemblyItemsConstRef m) -> AssemblyItems { return m[0].data() ? AssemblyItems({ m[1], Instruction::JUMP }) : AssemblyItems(); } },
+	};
+
+	for (auto const& i: c_simple)
+		rules.push_back({ { Push, Push, i.first }, [&](AssemblyItemsConstRef m) -> AssemblyItems { return { i.second(m[1].data(), m[0].data()) }; } });
+	for (auto const& i: c_associative)
+	{
+		rules.push_back({ { Push, Push, i.first }, [&](AssemblyItemsConstRef m) -> AssemblyItems { return { i.second(m[1].data(), m[0].data()) }; } });
+		rules.push_back({ { Push, i.first, Push, i.first }, [&](AssemblyItemsConstRef m) -> AssemblyItems { return { i.second(m[2].data(), m[0].data()), i.first }; } });
+		rules.push_back({ { PushTag, Instruction::JUMP, Tag }, [&](AssemblyItemsConstRef m) -> AssemblyItems
+						{
+							if (m[0].m_data == m[2].m_data)
+								return {};
+							else
+								return m.toVector();
+						}});
+	}
+
+	unsigned total = 0;
+	for (unsigned count = 1; count > 0; total += count)
+	{
+		count = 0;
+		for (unsigned i = 0; i < m_items.size(); ++i)
+		{
+			for (auto const& r: rules)
+			{
+				auto vr = AssemblyItemsConstRef(&m_items).cropped(i, r.first.size());
+				if (matches(&r.first, vr))
+				{
+					auto rw = r.second(vr);
+					if (rw.size() < vr.size())
+					{
+						cnote << vr << "matches" << AssemblyItemsConstRef(&r.first) << "becomes...";
+						for (unsigned j = 0; j < vr.size(); ++j)
+							if (j < rw.size())
+								m_items[i + j] = rw[j];
+							else
+								m_items.erase(m_items.begin() + i + rw.size());
+						cnote << AssemblyItemsConstRef(&rw);
+						count++;
+					}
+				}
+			}
+		}
+	}
+
+	// TODO: find all unused tags, for all those that have an unconditional jump immediately before, remove code between the tag and the next used tag (removing unused tags from the todo along the way).
+
+	cnote << total << " optimisations done.";
 }
 
 bytes Assembly::assemble() const
@@ -205,6 +318,7 @@ bytes Assembly::assemble() const
 		case Tag:
 			tagPos[(unsigned)i.m_data] = ret.size();
 			break;
+		default:;
 		}
 
 	for (auto const& i: tagRef)
diff --git a/Assembly.h b/Assembly.h
index 5194d23f..2efff943 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -30,7 +30,7 @@
 namespace eth
 {
 
-enum AssemblyItemType { Operation, Push, PushString, PushTag, Tag, PushData };
+enum AssemblyItemType { UndefinedItem, Operation, Push, PushString, PushTag, Tag, PushData };
 
 class Assembly;
 
@@ -41,7 +41,7 @@ class AssemblyItem
 public:
 	AssemblyItem(u256 _push): m_type(Push), m_data(_push) {}
 	AssemblyItem(Instruction _i): m_type(Operation), m_data((byte)_i) {}
-	AssemblyItem(AssemblyItemType _type, u256 _data): m_type(_type), m_data(_data) {}
+	AssemblyItem(AssemblyItemType _type, u256 _data = 0): m_type(_type), m_data(_data) {}
 
 	AssemblyItem tag() const { assert(m_type == PushTag || m_type == Tag); return AssemblyItem(Tag, m_data); }
 	AssemblyItem pushTag() const { assert(m_type == PushTag || m_type == Tag); return AssemblyItem(PushTag, m_data); }
@@ -51,14 +51,17 @@ public:
 
 	int deposit() const;
 
-	bool operator==(int _mask) const { return -_mask == (int)m_type || (m_type == Operation && _mask == (int)m_data); }
+	bool match(AssemblyItem const& _i) const { return _i.m_type == UndefinedItem || (m_type == _i.m_type && (m_type != Operation || m_data == _i.m_data)); }
 
 private:
 	AssemblyItemType m_type;
 	u256 m_data;
 };
 
-inline bool operator==(int _i, AssemblyItem _ai) { return _ai.operator==(_i); }
+typedef std::vector<AssemblyItem> AssemblyItems;
+typedef vector_ref<AssemblyItem const> AssemblyItemsConstRef;
+
+std::ostream& operator<<(std::ostream& _out, AssemblyItemsConstRef _i);
 
 class Assembly
 {
@@ -104,7 +107,7 @@ private:
 	unsigned bytesRequired() const;
 
 	unsigned m_usedTags = 0;
-	std::vector<AssemblyItem> m_items;
+	AssemblyItems m_items;
 	std::map<h256, bytes> m_data;
 	std::map<h256, std::string> m_strings;
 
-- 
cgit v1.2.3


From 1fdb7a1536209409010c6b6a69aedfce03c8372d Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Tue, 27 May 2014 18:51:10 +0200
Subject: Pinhole optimise working fairly well...

---
 Assembly.cpp   | 80 +++++++++++++++++++++++++++++++++++++++++++++-------------
 Assembly.h     |  1 +
 CodeFragment.h |  7 +++--
 Compiler.cpp   | 14 +++++++---
 Compiler.h     |  4 +--
 5 files changed, 80 insertions(+), 26 deletions(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 053de61a..1d9cb4bc 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -186,6 +186,9 @@ inline bool matches(AssemblyItemsConstRef _a, AssemblyItemsConstRef _b)
 	return true;
 }
 
+struct OptimiserChannel: public LogChannel { static const char* name() { return "OPT"; } static const int verbosity = 12; };
+#define copt eth::LogOutputStream<OptimiserChannel, true>()
+
 void Assembly::optimise()
 {
 	map<Instruction, function<u256(u256, u256)>> c_simple =
@@ -210,7 +213,7 @@ void Assembly::optimise()
 	std::vector<pair<AssemblyItems, function<AssemblyItems(AssemblyItemsConstRef)>>> rules =
 	{
 		{ { Push, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
-		{ { Push, PushTag, Instruction::JUMPI }, [](AssemblyItemsConstRef m) -> AssemblyItems { return m[0].data() ? AssemblyItems({ m[1], Instruction::JUMP }) : AssemblyItems(); } },
+		{ { Push, PushTag, Instruction::JUMPI }, [](AssemblyItemsConstRef m) -> AssemblyItems { if (m[0].data()) return { m[1], Instruction::JUMP }; else return {}; } },
 	};
 
 	for (auto const& i: c_simple)
@@ -219,19 +222,16 @@ void Assembly::optimise()
 	{
 		rules.push_back({ { Push, Push, i.first }, [&](AssemblyItemsConstRef m) -> AssemblyItems { return { i.second(m[1].data(), m[0].data()) }; } });
 		rules.push_back({ { Push, i.first, Push, i.first }, [&](AssemblyItemsConstRef m) -> AssemblyItems { return { i.second(m[2].data(), m[0].data()), i.first }; } });
-		rules.push_back({ { PushTag, Instruction::JUMP, Tag }, [&](AssemblyItemsConstRef m) -> AssemblyItems
-						{
-							if (m[0].m_data == m[2].m_data)
-								return {};
-							else
-								return m.toVector();
-						}});
+		rules.push_back({ { PushTag, Instruction::JUMP, Tag }, [&](AssemblyItemsConstRef m) -> AssemblyItems { if (m[0].m_data == m[2].m_data) return {}; else return m.toVector(); }});
 	}
 
+	copt << *this;
+
 	unsigned total = 0;
 	for (unsigned count = 1; count > 0; total += count)
 	{
 		count = 0;
+		map<u256, unsigned> tags;
 		for (unsigned i = 0; i < m_items.size(); ++i)
 		{
 			for (auto const& r: rules)
@@ -242,23 +242,64 @@ void Assembly::optimise()
 					auto rw = r.second(vr);
 					if (rw.size() < vr.size())
 					{
-						cnote << vr << "matches" << AssemblyItemsConstRef(&r.first) << "becomes...";
+						copt << vr << "matches" << AssemblyItemsConstRef(&r.first) << "becomes...";
 						for (unsigned j = 0; j < vr.size(); ++j)
 							if (j < rw.size())
 								m_items[i + j] = rw[j];
 							else
 								m_items.erase(m_items.begin() + i + rw.size());
-						cnote << AssemblyItemsConstRef(&rw);
+						copt << AssemblyItemsConstRef(&rw);
 						count++;
+						copt << "Now:\n" << m_items;
 					}
 				}
 			}
+			if (m_items[i].type() == Operation && m_items[i].data() == (byte)Instruction::JUMP)
+			{
+				bool o = false;
+				while (m_items.size() > i + 1 && m_items[i + 1].type() != Tag)
+				{
+					m_items.erase(m_items.begin() + i + 1);
+					o = true;
+				}
+				if (o)
+				{
+					copt << "Jump with no tag. Now:\n" << m_items;
+					++count;
+				}
+			}
 		}
-	}
 
-	// TODO: find all unused tags, for all those that have an unconditional jump immediately before, remove code between the tag and the next used tag (removing unused tags from the todo along the way).
+		for (unsigned i = 0; i < m_items.size(); ++i)
+			if (m_items[i].type() == Tag)
+				tags.insert(make_pair(m_items[i].data(), i));
+
+		for (auto const& i: m_items)
+			if (i.type() == PushTag)
+				tags.erase(i.data());
 
-	cnote << total << " optimisations done.";
+		if (tags.size())
+		{
+			auto t = *tags.begin();
+			unsigned i = t.second;
+			if (i && m_items[i - 1].type() == Operation && m_items[i - 1].data() == (byte)Instruction::JUMP)
+				while (i < m_items.size() && (m_items[i].type() != Tag || tags.count(m_items[i].data())))
+				{
+					if (m_items[i].type() == Tag && tags.count(m_items[i].data()))
+						tags.erase(m_items[i].data());
+					m_items.erase(m_items.begin() + i);
+				}
+			else
+			{
+				m_items.erase(m_items.begin() + i);
+				tags.erase(t.first);
+			}
+			copt << "Unused tag. Now:\n" << m_items;
+			++count;
+		}
+	}
+
+	copt << total << " optimisations done.";
 }
 
 bytes Assembly::assemble() const
@@ -333,13 +374,16 @@ bytes Assembly::assemble() const
 		for (auto const& i: m_data)
 		{
 			auto its = dataRef.equal_range(i.first);
-			for (auto it = its.first; it != its.second; ++it)
+			if (its.first != its.second)
 			{
-				bytesRef r(ret.data() + it->second, bytesPerTag);
-				toBigEndian(ret.size(), r);
+				for (auto it = its.first; it != its.second; ++it)
+				{
+					bytesRef r(ret.data() + it->second, bytesPerTag);
+					toBigEndian(ret.size(), r);
+				}
+				for (auto b: i.second)
+					ret.push_back(b);
 			}
-			for (auto b: i.second)
-				ret.push_back(b);
 		}
 	}
 	return ret;
diff --git a/Assembly.h b/Assembly.h
index 2efff943..a3bf998d 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -62,6 +62,7 @@ typedef std::vector<AssemblyItem> AssemblyItems;
 typedef vector_ref<AssemblyItem const> AssemblyItemsConstRef;
 
 std::ostream& operator<<(std::ostream& _out, AssemblyItemsConstRef _i);
+inline std::ostream& operator<<(std::ostream& _out, AssemblyItems const& _i) { return operator<<(_out, AssemblyItemsConstRef(&_i)); }
 
 class Assembly
 {
diff --git a/CodeFragment.h b/CodeFragment.h
index 6935a111..2c6f2cce 100644
--- a/CodeFragment.h
+++ b/CodeFragment.h
@@ -43,10 +43,13 @@ public:
 	static CodeFragment compile(std::string const& _src, CompilerState& _s);
 
 	/// Consolidates data and compiles code.
-	bytes code() { m_asm.optimise(); return m_asm.assemble(); }
+	bytes code() const { return m_asm.assemble(); }
 
 	/// Consolidates data and compiles code.
-	std::string assembly() { m_asm.optimise(); return m_asm.out(); }
+	std::string assembly() const { return m_asm.out(); }
+
+	/// Optimise the code. Best do this just before calling code() or assembly().
+	void optimise() { m_asm.optimise(); }
 
 private:
 	template <class T> void error() const { throw T(); }
diff --git a/Compiler.cpp b/Compiler.cpp
index 777bb72d..cd326341 100644
--- a/Compiler.cpp
+++ b/Compiler.cpp
@@ -27,12 +27,15 @@
 using namespace std;
 using namespace eth;
 
-bytes eth::compileLLL(string const& _src, vector<string>* _errors)
+bytes eth::compileLLL(string const& _src, bool _opt, vector<string>* _errors)
 {
 	try
 	{
 		CompilerState cs;
-		bytes ret = CodeFragment::compile(_src, cs).code();
+		auto f = CodeFragment::compile(_src, cs);
+		if (_opt)
+			f.optimise();
+		bytes ret = f.code();
 		for (auto i: cs.treesToKill)
 			killBigints(i);
 		return ret;
@@ -50,12 +53,15 @@ bytes eth::compileLLL(string const& _src, vector<string>* _errors)
 	return bytes();
 }
 
-std::string eth::compileLLLToAsm(std::string const& _src, std::vector<std::string>* _errors)
+std::string eth::compileLLLToAsm(std::string const& _src, bool _opt, std::vector<std::string>* _errors)
 {
 	try
 	{
 		CompilerState cs;
-		string ret = CodeFragment::compile(_src, cs).assembly();
+		auto f = CodeFragment::compile(_src, cs);
+		if (_opt)
+			f.optimise();
+		string ret = f.assembly();
 		for (auto i: cs.treesToKill)
 			killBigints(i);
 		return ret;
diff --git a/Compiler.h b/Compiler.h
index 9dd5fc29..395d7909 100644
--- a/Compiler.h
+++ b/Compiler.h
@@ -29,8 +29,8 @@ namespace eth
 {
 
 std::string parseLLL(std::string const& _src);
-std::string compileLLLToAsm(std::string const& _src, std::vector<std::string>* _errors = nullptr);
-bytes compileLLL(std::string const& _src, std::vector<std::string>* _errors = nullptr);
+std::string compileLLLToAsm(std::string const& _src, bool _opt = true, std::vector<std::string>* _errors = nullptr);
+bytes compileLLL(std::string const& _src, bool _opt = true, std::vector<std::string>* _errors = nullptr);
 
 }
 
-- 
cgit v1.2.3


From 009b25d043adc8f165de525eecc19702d105c125 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Tue, 27 May 2014 19:11:37 +0200
Subject: Assembler fix.

---
 Assembly.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Assembly.h b/Assembly.h
index a3bf998d..3907f69f 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -87,7 +87,7 @@ public:
 	template <class T> Assembly& operator<<(T const& _d) { append(_d); return *this; }
 
 	AssemblyItem const& back() { return m_items.back(); }
-	std::string backString() const { return m_items.back().m_type == PushString ? m_strings.at((h256)m_items.back().m_data) : std::string(); }
+	std::string backString() const { return m_items.size() && m_items.back().m_type == PushString ? m_strings.at((h256)m_items.back().m_data) : std::string(); }
 
 	void onePath() { assert(!m_totalDeposit && !m_baseDeposit); m_baseDeposit = m_deposit; m_totalDeposit = INT_MAX; }
 	void otherPath() { donePath(); m_totalDeposit = m_deposit; m_deposit = m_baseDeposit; }
-- 
cgit v1.2.3


From 72265ac38ad65b0adc07e7ea7ece26baea9b356c Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Thu, 29 May 2014 20:30:56 +0200
Subject: Fix for unless/when.

---
 CodeFragment.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index 299cda5f..f30fba95 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -385,7 +385,8 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 			auto end = m_asm.appendJumpI();
 			m_asm.onePath();
 			m_asm.otherPath();
-			m_asm << code[1].m_asm << end.tag();
+			m_asm.append(code[1].m_asm, 0);
+			m_asm << end.tag();
 			m_asm.donePaths();
 		}
 		else if (us == "WHILE")
-- 
cgit v1.2.3


From 362cfb350e8cd2ea58615877e3f1d37b95f0d0bf Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Thu, 29 May 2014 23:11:45 +0200
Subject: Revert "Fix for unless/when."

This reverts commit b12d91e726ae5d1742e6d828c2cb5b694ffdf8a3.
---
 CodeFragment.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index f30fba95..299cda5f 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -385,8 +385,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 			auto end = m_asm.appendJumpI();
 			m_asm.onePath();
 			m_asm.otherPath();
-			m_asm.append(code[1].m_asm, 0);
-			m_asm << end.tag();
+			m_asm << code[1].m_asm << end.tag();
 			m_asm.donePaths();
 		}
 		else if (us == "WHILE")
-- 
cgit v1.2.3


From de85b070b8c65f9ea7e1dd261467d759798629f7 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Thu, 29 May 2014 23:21:51 +0200
Subject: Fix for when/unless.

---
 CodeFragment.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index 299cda5f..f30fba95 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -385,7 +385,8 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 			auto end = m_asm.appendJumpI();
 			m_asm.onePath();
 			m_asm.otherPath();
-			m_asm << code[1].m_asm << end.tag();
+			m_asm.append(code[1].m_asm, 0);
+			m_asm << end.tag();
 			m_asm.donePaths();
 		}
 		else if (us == "WHILE")
-- 
cgit v1.2.3


From b64a96199fb17d624974d8d5efe8e0758ef117bf Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Fri, 30 May 2014 13:37:39 +0200
Subject: Fix for nonce incrementing. Messaging for some execution failures.
 State uses temporary for transaction trie. Additional optimisation.

---
 Assembly.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Assembly.cpp b/Assembly.cpp
index 1d9cb4bc..c0dc6fd5 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -213,7 +213,10 @@ void Assembly::optimise()
 	std::vector<pair<AssemblyItems, function<AssemblyItems(AssemblyItemsConstRef)>>> rules =
 	{
 		{ { Push, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
+		{ { PushTag, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
+		{ { PushString, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
 		{ { Push, PushTag, Instruction::JUMPI }, [](AssemblyItemsConstRef m) -> AssemblyItems { if (m[0].data()) return { m[1], Instruction::JUMP }; else return {}; } },
+		{ { Instruction::NOT, Instruction::NOT }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
 	};
 
 	for (auto const& i: c_simple)
-- 
cgit v1.2.3


From 78c0baa026d69a6b03d0f3d9288c4da4e03f4b96 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Fri, 30 May 2014 14:47:13 +0200
Subject: Actually do endow ether. Standard extension.

---
 Compiler.cpp      |  2 ++
 CompilerState.cpp | 23 +++++++++++++++++++++++
 CompilerState.h   |  1 +
 3 files changed, 26 insertions(+)

diff --git a/Compiler.cpp b/Compiler.cpp
index cd326341..8400ad95 100644
--- a/Compiler.cpp
+++ b/Compiler.cpp
@@ -32,6 +32,7 @@ bytes eth::compileLLL(string const& _src, bool _opt, vector<string>* _errors)
 	try
 	{
 		CompilerState cs;
+		cs.populateStandard();
 		auto f = CodeFragment::compile(_src, cs);
 		if (_opt)
 			f.optimise();
@@ -58,6 +59,7 @@ std::string eth::compileLLLToAsm(std::string const& _src, bool _opt, std::vector
 	try
 	{
 		CompilerState cs;
+		cs.populateStandard();
 		auto f = CodeFragment::compile(_src, cs);
 		if (_opt)
 			f.optimise();
diff --git a/CompilerState.cpp b/CompilerState.cpp
index d2894475..571b9de3 100644
--- a/CompilerState.cpp
+++ b/CompilerState.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "CompilerState.h"
+#include "CodeFragment.h"
 
 using namespace std;
 using namespace eth;
@@ -35,3 +36,25 @@ CodeFragment const& CompilerState::getDef(std::string const& _s)
 	else
 		return NullCodeFragment;
 }
+
+void CompilerState::populateStandard()
+{
+	static const string s = "{"
+	"(def 'gav 0x8a40bfaa73256b60764c1bf40675a99083efb075)"
+	"(def 'send (to value) (call (- (gas) 21) to value 0 0 0 0))"
+#if 0
+	"(def 'send (gaslimit to value) (call gaslimit to value 0 0 0 0))"
+	"(def 'alloc (len) (asm msize 0 1 len msize add sub mstore8))"
+	"(def 'msg (gaslimit to value data datasize outsize) { [32]:outsize [0]:(alloc @32) (call gaslimit to value data datasize @0 @32) @0 })"
+	"(def 'msg (gaslimit to value data datasize) { (call gaslimit to value data datasize 0 32) @0 })"
+	"(def 'msg (gaslimit to value data) { [0]:data (msg gaslimit to value 0 32) })"
+	"(def 'create (to value code) { [0]:(msize) (create to value @0 (lll code @0)) })"
+	"(def 'sha3 (val) { [0]:val (sha3 0 32) })"
+	"(def 'return (val) { [0]:val (return 0 32) })"
+	"(def 'makeperm (name pos) { (def name (sload pos)) (def name (v) (sstore pos v)) } )"
+	"(def 'permcount 0)"
+	"(def 'perm (name) { (makeperm name permcount) (def 'permcount (+ permcount 1)) } )"
+#endif
+	"}";
+	CodeFragment::compile(s, *this);
+}
diff --git a/CompilerState.h b/CompilerState.h
index d53c2bcd..7f3cef82 100644
--- a/CompilerState.h
+++ b/CompilerState.h
@@ -37,6 +37,7 @@ struct Macro
 struct CompilerState
 {
 	CodeFragment const& getDef(std::string const& _s);
+	void populateStandard();
 
 	std::map<std::string, unsigned> vars;
 	std::map<std::string, CodeFragment> defs;
-- 
cgit v1.2.3


From b379ce906530797f0f58569653b648ab64f2968d Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Fri, 30 May 2014 14:55:07 +0200
Subject: Variadic macros work.

---
 CodeFragment.cpp  | 17 ++++++++++-------
 CompilerState.cpp |  2 +-
 CompilerState.h   |  2 +-
 3 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index f30fba95..448d3ef2 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -172,6 +172,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 			unsigned ii = 0;
 			if (_t.size() != 3 && _t.size() != 4)
 				error<IncorrectParameterCount>();
+			vector<string> args;
 			for (auto const& i: _t)
 			{
 				if (ii == 1)
@@ -198,16 +199,18 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 							if (j.tag() || j.which() != sp::utree_type::symbol_type)
 								error<InvalidMacroArgs>();
 							auto sr = j.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
-							_s.macros[n].args.push_back(string(sr.begin(), sr.end()));
+							args.push_back(string(sr.begin(), sr.end()));
 						}
 				else if (ii == 3)
 				{
-					_s.macros[n].code = i;
-					_s.macros[n].env = _s.outers;
+					auto k = make_pair(n, args.size());
+					_s.macros[k].code = i;
+					_s.macros[k].env = _s.outers;
+					_s.macros[k].args = args;
 					for (auto const& i: _s.args)
-						_s.macros[n].env[i.first] = i.second;
+						_s.macros[k].env[i.first] = i.second;
 					for (auto const& i: _s.defs)
-						_s.macros[n].env[i.first] = i.second;
+						_s.macros[k].env[i.first] = i.second;
 				}
 				++ii;
 			}
@@ -292,9 +295,9 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 		auto requireMaxSize = [&](unsigned s) { if (code.size() > s) error<IncorrectParameterCount>(); };
 		auto requireDeposit = [&](unsigned i, int s) { if (code[i].m_asm.deposit() != s) error<InvalidDeposit>(); };
 
-		if (_s.macros.count(s) && _s.macros.at(s).args.size() == code.size())
+		if (_s.macros.count(make_pair(s, code.size())))
 		{
-			Macro const& m = _s.macros.at(s);
+			Macro const& m = _s.macros.at(make_pair(s, code.size()));
 			CompilerState cs = _s;
 			for (auto const& i: m.env)
 				cs.outers[i.first] = i.second;
diff --git a/CompilerState.cpp b/CompilerState.cpp
index 571b9de3..e5d0b2a0 100644
--- a/CompilerState.cpp
+++ b/CompilerState.cpp
@@ -42,8 +42,8 @@ void CompilerState::populateStandard()
 	static const string s = "{"
 	"(def 'gav 0x8a40bfaa73256b60764c1bf40675a99083efb075)"
 	"(def 'send (to value) (call (- (gas) 21) to value 0 0 0 0))"
-#if 0
 	"(def 'send (gaslimit to value) (call gaslimit to value 0 0 0 0))"
+#if 1
 	"(def 'alloc (len) (asm msize 0 1 len msize add sub mstore8))"
 	"(def 'msg (gaslimit to value data datasize outsize) { [32]:outsize [0]:(alloc @32) (call gaslimit to value data datasize @0 @32) @0 })"
 	"(def 'msg (gaslimit to value data datasize) { (call gaslimit to value data datasize 0 32) @0 })"
diff --git a/CompilerState.h b/CompilerState.h
index 7f3cef82..b7581e0b 100644
--- a/CompilerState.h
+++ b/CompilerState.h
@@ -43,7 +43,7 @@ struct CompilerState
 	std::map<std::string, CodeFragment> defs;
 	std::map<std::string, CodeFragment> args;
 	std::map<std::string, CodeFragment> outers;
-	std::map<std::string, Macro> macros;
+	std::map<std::pair<std::string, unsigned>, Macro> macros;
 	std::vector<boost::spirit::utree> treesToKill;
 };
 
-- 
cgit v1.2.3


From 8c25c35b375b5284505e0004ad741497c222e293 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Sat, 31 May 2014 00:49:07 +0200
Subject: Javascript console and env.load(), env.note, ...

---
 Parser.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Parser.cpp b/Parser.cpp
index 10d2188a..de0a5428 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -75,7 +75,7 @@ void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
 
 	qi::rule<it, qi::ascii::space_type, sp::utree()> element;
 	qi::rule<it, string()> str = '"' > qi::lexeme[+(~qi::char_(std::string("\"") + '\0'))] > '"';
-	qi::rule<it, string()> strsh = '\'' > qi::lexeme[+(~qi::char_(std::string(" ;())") + '\0'))];
+	qi::rule<it, string()> strsh = '\'' > qi::lexeme[+(~qi::char_(std::string(" ;@()[]{}:") + '\0'))];
 	qi::rule<it, symbol_type()> symbol = qi::lexeme[+(~qi::char_(std::string(" @[]{}:();\"\x01-\x1f\x7f") + '\0'))];
 	qi::rule<it, string()> intstr = qi::lexeme[ qi::no_case["0x"][qi::_val = "0x"] >> *qi::char_("0-9a-fA-F")[qi::_val += qi::_1]] | qi::lexeme[+qi::char_("0-9")[qi::_val += qi::_1]];
 	qi::rule<it, bigint()> integer = intstr;
-- 
cgit v1.2.3


From 9ebaeb53fa398a2b983bd9320cd73d3c2f0b2c62 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Sat, 31 May 2014 02:00:49 +0200
Subject: Minor bug fix. Fixes for a few warnings.

---
 Assembly.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index c0dc6fd5..4b7d9834 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -39,7 +39,7 @@ int AssemblyItem::deposit() const
 		return 0;
 	default:;
 	}
-	assert(false);
+	return 0;
 }
 
 unsigned Assembly::bytesRequired() const
-- 
cgit v1.2.3


From 7afd678509cf01187d8a706a0bbdb45df115f755 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Sat, 31 May 2014 13:01:06 +0200
Subject: Fix for compiler.

---
 CompilerState.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CompilerState.cpp b/CompilerState.cpp
index e5d0b2a0..2d23d14e 100644
--- a/CompilerState.cpp
+++ b/CompilerState.cpp
@@ -48,7 +48,7 @@ void CompilerState::populateStandard()
 	"(def 'msg (gaslimit to value data datasize outsize) { [32]:outsize [0]:(alloc @32) (call gaslimit to value data datasize @0 @32) @0 })"
 	"(def 'msg (gaslimit to value data datasize) { (call gaslimit to value data datasize 0 32) @0 })"
 	"(def 'msg (gaslimit to value data) { [0]:data (msg gaslimit to value 0 32) })"
-	"(def 'create (to value code) { [0]:(msize) (create to value @0 (lll code @0)) })"
+	"(def 'create (value code) { [0]:(msize) (create value @0 (lll code @0)) })"
 	"(def 'sha3 (val) { [0]:val (sha3 0 32) })"
 	"(def 'return (val) { [0]:val (return 0 32) })"
 	"(def 'makeperm (name pos) { (def name (sload pos)) (def name (v) (sstore pos v)) } )"
-- 
cgit v1.2.3


From 99e9cb0e2e891a790553adf9309362a709e8689a Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Sat, 31 May 2014 13:06:32 +0200
Subject: Additional variants of create and send.

---
 CompilerState.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/CompilerState.cpp b/CompilerState.cpp
index 2d23d14e..5cf2a965 100644
--- a/CompilerState.cpp
+++ b/CompilerState.cpp
@@ -43,18 +43,19 @@ void CompilerState::populateStandard()
 	"(def 'gav 0x8a40bfaa73256b60764c1bf40675a99083efb075)"
 	"(def 'send (to value) (call (- (gas) 21) to value 0 0 0 0))"
 	"(def 'send (gaslimit to value) (call gaslimit to value 0 0 0 0))"
-#if 1
 	"(def 'alloc (len) (asm msize 0 1 len msize add sub mstore8))"
 	"(def 'msg (gaslimit to value data datasize outsize) { [32]:outsize [0]:(alloc @32) (call gaslimit to value data datasize @0 @32) @0 })"
 	"(def 'msg (gaslimit to value data datasize) { (call gaslimit to value data datasize 0 32) @0 })"
 	"(def 'msg (gaslimit to value data) { [0]:data (msg gaslimit to value 0 32) })"
+	"(def 'msg (to value data) { [0]:data (msg 0 to value 0 32) })"
+	"(def 'msg (to data) { [0]:data (msg 0 to 0 0 32) })"
 	"(def 'create (value code) { [0]:(msize) (create value @0 (lll code @0)) })"
+	"(def 'create (code) { [0]:(msize) (create 0 @0 (lll code @0)) })"
 	"(def 'sha3 (val) { [0]:val (sha3 0 32) })"
 	"(def 'return (val) { [0]:val (return 0 32) })"
 	"(def 'makeperm (name pos) { (def name (sload pos)) (def name (v) (sstore pos v)) } )"
 	"(def 'permcount 0)"
 	"(def 'perm (name) { (makeperm name permcount) (def 'permcount (+ permcount 1)) } )"
-#endif
 	"}";
 	CodeFragment::compile(s, *this);
 }
-- 
cgit v1.2.3


From f64b371382e0a7f2adbe4fd3b45f61fd1ad7d759 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Sat, 31 May 2014 13:41:08 +0200
Subject: Fixes and language additions.

---
 CompilerState.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/CompilerState.cpp b/CompilerState.cpp
index 5cf2a965..74e5062f 100644
--- a/CompilerState.cpp
+++ b/CompilerState.cpp
@@ -41,6 +41,11 @@ void CompilerState::populateStandard()
 {
 	static const string s = "{"
 	"(def 'gav 0x8a40bfaa73256b60764c1bf40675a99083efb075)"
+	"(def 'namereg 0x2d0aceee7e5ab874e22ccf8d1a649f59106d74e8)"
+	"(def 'config 0xccdeac59d35627b7de09332e819d5159e7bb7250)"
+	"(def 'gavcoin 0x5620133321fcac7f15a5c570016f6cb6dc263f9d)"
+	"(def 'sendgavcoin (to value) { [0]:to [32]:value (call (- (gas) 21) gavcoin 0 0 64 0 0) })"
+	"(def 'regname (name) { [0]:name (call (- (gas) 21) namereg 0 0 32 0 0) })"
 	"(def 'send (to value) (call (- (gas) 21) to value 0 0 0 0))"
 	"(def 'send (gaslimit to value) (call gaslimit to value 0 0 0 0))"
 	"(def 'alloc (len) (asm msize 0 1 len msize add sub mstore8))"
@@ -53,6 +58,7 @@ void CompilerState::populateStandard()
 	"(def 'create (code) { [0]:(msize) (create 0 @0 (lll code @0)) })"
 	"(def 'sha3 (val) { [0]:val (sha3 0 32) })"
 	"(def 'return (val) { [0]:val (return 0 32) })"
+	"(def 'returnlll (code) (return 0 (lll code 0)) )"
 	"(def 'makeperm (name pos) { (def name (sload pos)) (def name (v) (sstore pos v)) } )"
 	"(def 'permcount 0)"
 	"(def 'perm (name) { (makeperm name permcount) (def 'permcount (+ permcount 1)) } )"
-- 
cgit v1.2.3


From bbc7bd19e529cd1a64708b45b8f8193b60d5fb59 Mon Sep 17 00:00:00 2001
From: Tim Hughes <tim@twistedfury.com>
Date: Wed, 4 Jun 2014 11:34:14 +0100
Subject: Fixed all the windows compile errors and project reorg with the
 exception of the more complex problem in Parser.cpp

---
 CodeFragment.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CodeFragment.h b/CodeFragment.h
index 2c6f2cce..8e3ff1d7 100644
--- a/CodeFragment.h
+++ b/CodeFragment.h
@@ -32,7 +32,7 @@ namespace sp = boost::spirit;
 namespace eth
 {
 
-class CompilerState;
+struct CompilerState;
 
 class CodeFragment
 {
-- 
cgit v1.2.3


From 5ea7efd593aa4576df6ac0c2b3c334e0f4ec6201 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Tue, 10 Jun 2014 16:49:54 +0100
Subject: Fix signed instructions.

---
 Assembly.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 4b7d9834..0de16982 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -195,14 +195,14 @@ void Assembly::optimise()
 	{
 		{ Instruction::SUB, [](u256 a, u256 b)->u256{return a - b;} },
 		{ Instruction::DIV, [](u256 a, u256 b)->u256{return a / b;} },
-		{ Instruction::SDIV, [](u256 a, u256 b)->u256{u256 r; (s256&)r = (s256&)a / (s256&)b; return r;} },
+        { Instruction::SDIV, [](u256 a, u256 b)->u256{return s2u(u2s(a) / u2s(b));} },
 		{ Instruction::MOD, [](u256 a, u256 b)->u256{return a % b;} },
-		{ Instruction::SMOD, [](u256 a, u256 b)->u256{u256 r; (s256&)r = (s256&)a % (s256&)b; return r;} },
+        { Instruction::SMOD, [](u256 a, u256 b)->u256{return s2u(u2s(a) % u2s(b));} },
 		{ Instruction::EXP, [](u256 a, u256 b)->u256{return boost::multiprecision::pow(a, (unsigned)b);} },
 		{ Instruction::LT, [](u256 a, u256 b)->u256{return a < b ? 1 : 0;} },
 		{ Instruction::GT, [](u256 a, u256 b)->u256{return a > b ? 1 : 0;} },
-		{ Instruction::SLT, [](u256 a, u256 b)->u256{return *(s256*)&a < *(s256*)&b ? 1 : 0;} },
-		{ Instruction::SGT, [](u256 a, u256 b)->u256{return *(s256*)&a > *(s256*)&b ? 1 : 0;} },
+        { Instruction::SLT, [](u256 a, u256 b)->u256{return u2s(a) < u2s(b) ? 1 : 0;} },
+        { Instruction::SGT, [](u256 a, u256 b)->u256{return u2s(a) > u2s(b) ? 1 : 0;} },
 		{ Instruction::EQ, [](u256 a, u256 b)->u256{return a == b ? 1 : 0;} },
 	};
 	map<Instruction, function<u256(u256, u256)>> c_associative =
-- 
cgit v1.2.3


From a2219639febeeac1807c670071aded337d7a4d7c Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Wed, 11 Jun 2014 19:25:21 +0100
Subject: LLL supports get/set/ref. Logging changes.

---
 CodeFragment.cpp  | 81 +++++++++++++++++++++++++++++++++++++------------------
 CompilerState.cpp |  4 +++
 CompilerState.h   |  5 +++-
 3 files changed, 63 insertions(+), 27 deletions(-)

diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index 448d3ef2..804504f0 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -79,9 +79,10 @@ CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowAS
 			if (it == _s.vars.end())
 			{
 				bool ok;
-				tie(it, ok) = _s.vars.insert(make_pair(s, _s.vars.size() * 32));
+				tie(it, ok) = _s.vars.insert(make_pair(s, make_pair(_s.stackSize, 32)));
+				_s.stackSize += 32;
 			}
-			m_asm.append((u256)it->second);
+			m_asm.append((u256)it->second.first);
 		}
 		else
 			error<BareSymbol>();
@@ -137,6 +138,36 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 		default:;
 		}
 
+		auto firstAsString = [&]()
+		{
+			auto i = *++_t.begin();
+			if (i.tag())
+				error<InvalidName>();
+			if (i.which() == sp::utree_type::string_type)
+			{
+				auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
+				return string(sr.begin(), sr.end());
+			}
+			else if (i.which() == sp::utree_type::symbol_type)
+			{
+				auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
+				return _s.getDef(string(sr.begin(), sr.end())).m_asm.backString();
+			}
+			return string();
+		};
+
+		auto varAddress = [&](string const& n)
+		{
+			auto it = _s.vars.find(n);
+			if (it == _s.vars.end())
+			{
+				bool ok;
+				tie(it, ok) = _s.vars.insert(make_pair(n, make_pair(_s.stackSize, 32)));
+				_s.stackSize += 32;
+			}
+			return it->second.first;
+		};
+
 		// Operations who args are not standard stack-pushers.
 		bool nonStandard = true;
 		if (us == "ASM")
@@ -150,22 +181,28 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 		{
 			if (_t.size() != 2)
 				error<IncorrectParameterCount>();
-			string n;
-			auto i = *++_t.begin();
-			if (i.tag())
-				error<InvalidName>();
-			if (i.which() == sp::utree_type::string_type)
-			{
-				auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
-				n = string(sr.begin(), sr.end());
-			}
-			else if (i.which() == sp::utree_type::symbol_type)
-			{
-				auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
-				n = _s.getDef(string(sr.begin(), sr.end())).m_asm.backString();
-			}
-			m_asm.append(CodeFragment::compile(asString(contents(n)), _s).m_asm);
+			m_asm.append(CodeFragment::compile(asString(contents(firstAsString())), _s).m_asm);
+		}
+		else if (us == "SET")
+		{
+			if (_t.size() != 3)
+				error<IncorrectParameterCount>();
+			int c = 0;
+			for (auto const& i: _t)
+				if (c++ == 2)
+					m_asm.append(CodeFragment(i, _s, false).m_asm);
+			m_asm.append((u256)varAddress(firstAsString()));
+			m_asm.append(Instruction::MSTORE);
 		}
+		else if (us == "GET")
+		{
+			if (_t.size() != 2)
+				error<IncorrectParameterCount>();
+			m_asm.append((u256)varAddress(firstAsString()));
+			m_asm.append(Instruction::MLOAD);
+		}
+		else if (us == "REF")
+			m_asm.append((u256)varAddress(firstAsString()));
 		else if (us == "DEF")
 		{
 			string n;
@@ -497,15 +534,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 			m_asm.popTo(1);
 		}
 		else if (us.find_first_of("1234567890") != 0 && us.find_first_not_of("QWERTYUIOPASDFGHJKLZXCVBNM1234567890_") == string::npos)
-		{
-			auto it = _s.vars.find(s);
-			if (it == _s.vars.end())
-			{
-				bool ok;
-				tie(it, ok) = _s.vars.insert(make_pair(s, _s.vars.size() * 32));
-			}
-			m_asm.append((u256)it->second);
-		}
+			m_asm.append((u256)varAddress(s));
 		else
 			error<InvalidOperation>();
 	}
diff --git a/CompilerState.cpp b/CompilerState.cpp
index 74e5062f..490e9267 100644
--- a/CompilerState.cpp
+++ b/CompilerState.cpp
@@ -25,6 +25,10 @@
 using namespace std;
 using namespace eth;
 
+CompilerState::CompilerState()
+{
+}
+
 CodeFragment const& CompilerState::getDef(std::string const& _s)
 {
 	if (defs.count(_s))
diff --git a/CompilerState.h b/CompilerState.h
index b7581e0b..f8f7ce81 100644
--- a/CompilerState.h
+++ b/CompilerState.h
@@ -36,10 +36,13 @@ struct Macro
 
 struct CompilerState
 {
+	CompilerState();
+
 	CodeFragment const& getDef(std::string const& _s);
 	void populateStandard();
 
-	std::map<std::string, unsigned> vars;
+	unsigned stackSize = 64;
+	std::map<std::string, std::pair<unsigned, unsigned>> vars;       ///< maps name to stack offset & size.
 	std::map<std::string, CodeFragment> defs;
 	std::map<std::string, CodeFragment> args;
 	std::map<std::string, CodeFragment> outers;
-- 
cgit v1.2.3


From 52d7d699021182207853cc657f3633f4f960fcc3 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Thu, 12 Jun 2014 18:35:39 +0100
Subject: Standard service JS script. Bug fix for load & LLL macros. Move to
 new services.

---
 CodeFragment.cpp  | 2 +-
 CompilerState.cpp | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index 804504f0..9284c1f3 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -343,7 +343,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 			cs.defs.clear();
 			for (unsigned i = 0; i < m.args.size(); ++i)
 			{
-				requireDeposit(i, 1);
+				//requireDeposit(i, 1);
 				cs.args[m.args[i]] = code[i];
 			}
 			m_asm.append(CodeFragment(m.code, cs).m_asm);
diff --git a/CompilerState.cpp b/CompilerState.cpp
index 490e9267..7e990413 100644
--- a/CompilerState.cpp
+++ b/CompilerState.cpp
@@ -44,7 +44,7 @@ CodeFragment const& CompilerState::getDef(std::string const& _s)
 void CompilerState::populateStandard()
 {
 	static const string s = "{"
-	"(def 'gav 0x8a40bfaa73256b60764c1bf40675a99083efb075)"
+	"(def 'gav 0x51ba59315b3a95761d0863b05ccc7a7f54703d99)"
 	"(def 'namereg 0x2d0aceee7e5ab874e22ccf8d1a649f59106d74e8)"
 	"(def 'config 0xccdeac59d35627b7de09332e819d5159e7bb7250)"
 	"(def 'gavcoin 0x5620133321fcac7f15a5c570016f6cb6dc263f9d)"
-- 
cgit v1.2.3


From 2c0c091616cb5a57626c714e8857e31cc39b5ab7 Mon Sep 17 00:00:00 2001
From: Tim Hughes <tim@twistedfury.com>
Date: Wed, 18 Jun 2014 12:24:56 +0100
Subject: Fixed MSVC compile errors (but missing functionality in LLL parser)

---
 Parser.cpp | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/Parser.cpp b/Parser.cpp
index de0a5428..98583f33 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -87,9 +87,16 @@ void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
 	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> sload = qi::lit("@@") > element;
 	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> mstore = '[' > element > ']' > -qi::lit(":") > element;
 	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> sstore = qi::lit("[[") > element > qi::lit("]]") > -qi::lit(":") > element;
-	qi::rule<it, qi::ascii::space_type, sp::utree()> extra = sload[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 2)] | mload[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 1)] | sstore[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 4)] | mstore[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 3)] | seq[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 5)];
 	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> list = '(' > *element > ')';
+
+	// todo: fix compound compile errors in this line for Visual Studio 2013
+#ifndef _MSC_VER
+	qi::rule<it, qi::ascii::space_type, sp::utree()> extra = sload[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 2)] | mload[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 1)] | sstore[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 4)] | mstore[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 3)] | seq[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 5)];
 	element = atom | list | extra;
+#else
+	element = atom | list/* | extra*/;
+#endif
+	
 
 	string s;
 	s.reserve(_s.size());
-- 
cgit v1.2.3


From eaf79f924c3757268fe6829dbeef6fdfd7960d45 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Sun, 22 Jun 2014 11:41:29 +0100
Subject: Better language determination.

---
 Parser.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Parser.cpp b/Parser.cpp
index 98583f33..13faf583 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -118,6 +118,6 @@ void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
 		if (!incomment)
 			s.push_back(i);
 	}
-	qi::phrase_parse(s.cbegin(), s.cend(), element, space, o_out);
+	qi::phrase_parse(s.cbegin(), s.cend(), element, space, qi::skip_flag::dont_postskip, o_out);
 }
 
-- 
cgit v1.2.3


From 18c3da3eb29fa646f34b56876012abcee65e03ca Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Sun, 22 Jun 2014 20:36:16 +0100
Subject: Better language detection.

---
 Parser.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Parser.cpp b/Parser.cpp
index 13faf583..0ae3c6fe 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -118,6 +118,9 @@ void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
 		if (!incomment)
 			s.push_back(i);
 	}
-	qi::phrase_parse(s.cbegin(), s.cend(), element, space, qi::skip_flag::dont_postskip, o_out);
+	auto ret = s.cbegin();
+	qi::phrase_parse(ret, s.cend(), element, space, qi::skip_flag::dont_postskip, o_out);
+	if (ret != s.cend())
+		throw std::exception();
 }
 
-- 
cgit v1.2.3


From 5e2b4bbd58f1d244d1aab985e07835071692d7a5 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Fri, 27 Jun 2014 23:47:24 +0200
Subject: Project refactor. Introduce the Serpent library.

---
 Assembly.cpp     |  2 +-
 Assembly.h       |  5 +++--
 CMakeLists.txt   | 11 ++---------
 CodeFragment.cpp |  4 ++--
 CodeFragment.h   |  4 ++--
 Compiler.h       |  2 +-
 Parser.h         |  2 +-
 7 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 0de16982..0fa12537 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -21,7 +21,7 @@
 
 #include "Assembly.h"
 
-#include <libethsupport/Log.h>
+#include <libethential/Log.h>
 #include <libethcore/CommonEth.h>
 
 using namespace std;
diff --git a/Assembly.h b/Assembly.h
index 3907f69f..29f899c0 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -23,8 +23,9 @@
 
 #include <iostream>
 #include <sstream>
-#include <libethsupport/Common.h>
-#include <libethcore/Instruction.h>
+#include <libethential/Common.h>
+#include <libevmface/Instruction.h>
+#include <libethcore/SHA3.h>
 #include "Exceptions.h"
 
 namespace eth
diff --git a/CMakeLists.txt b/CMakeLists.txt
index dc5fc222..4117e6ed 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,17 +18,10 @@ endif()
 file(GLOB HEADERS "*.h") 
 
 include_directories(..)
-include_directories(${MINIUPNPC_ID})
-include_directories(${LEVELDB_ID})
-
-target_link_libraries(${EXECUTABLE} ethcore)
-target_link_libraries(${EXECUTABLE} ethsupport)
-target_link_libraries(${EXECUTABLE} secp256k1)
-target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS})
-target_link_libraries(${EXECUTABLE} ${LEVELDB_LS})
+target_link_libraries(${EXECUTABLE} ethential)
+target_link_libraries(${EXECUTABLE} evmface)
 target_link_libraries(${EXECUTABLE} gmp)
 
-
 if(${TARGET_PLATFORM} STREQUAL "w64")
 	include_directories(/usr/x86_64-w64-mingw32/include/cryptopp)
 	target_link_libraries(${EXECUTABLE} cryptopp)
diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index 9284c1f3..2ad23471 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -24,8 +24,8 @@
 
 #include <boost/algorithm/string.hpp>
 #include <boost/spirit/include/support_utree.hpp>
-#include <libethsupport/Log.h>
-#include <libethcore/Instruction.h>
+#include <libethential/Log.h>
+#include <libevmface/Instruction.h>
 #include <libethcore/CommonEth.h>
 #include "CompilerState.h"
 using namespace std;
diff --git a/CodeFragment.h b/CodeFragment.h
index 8e3ff1d7..b9d44c03 100644
--- a/CodeFragment.h
+++ b/CodeFragment.h
@@ -21,8 +21,8 @@
 
 #pragma once
 
-#include <libethsupport/Common.h>
-#include <libethcore/Instruction.h>
+#include <libethential/Common.h>
+#include <libevmface/Instruction.h>
 #include "Assembly.h"
 #include "Exceptions.h"
 
diff --git a/Compiler.h b/Compiler.h
index 395d7909..da84a2fe 100644
--- a/Compiler.h
+++ b/Compiler.h
@@ -23,7 +23,7 @@
 
 #include <string>
 #include <vector>
-#include <libethsupport/Common.h>
+#include <libethential/Common.h>
 
 namespace eth
 {
diff --git a/Parser.h b/Parser.h
index 059ffe6a..5286c3e8 100644
--- a/Parser.h
+++ b/Parser.h
@@ -23,7 +23,7 @@
 
 #include <string>
 #include <vector>
-#include <libethsupport/Common.h>
+#include <libethential/Common.h>
 
 namespace boost { namespace spirit { class utree; } }
 namespace sp = boost::spirit;
-- 
cgit v1.2.3


From 674ff8e3cc1e95a351d14683db7b67a7822d5aa3 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Sat, 28 Jun 2014 19:23:32 +0200
Subject: Full python serpent support. Shared libs on all platforms.

---
 Assembly.h       |  4 ++--
 CMakeLists.txt   | 26 ++++++--------------------
 CodeFragment.cpp |  1 -
 3 files changed, 8 insertions(+), 23 deletions(-)

diff --git a/Assembly.h b/Assembly.h
index 29f899c0..3e8a8326 100644
--- a/Assembly.h
+++ b/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<std::string>()(asString(_data)); m_data[h] = _data; return AssemblyItem(PushData, h); }
+	AssemblyItem newPushString(std::string const& _data) { h256 h = (u256)std::hash<std::string>()(_data); m_strings[h] = _data; return AssemblyItem(PushString, h); }
 
 	AssemblyItem append() { return append(newTag()); }
 	void append(Assembly const& _a);
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4117e6ed..2356b7d9 100644
--- a/CMakeLists.txt
+++ b/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/CodeFragment.cpp b/CodeFragment.cpp
index 2ad23471..f0aeb860 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -26,7 +26,6 @@
 #include <boost/spirit/include/support_utree.hpp>
 #include <libethential/Log.h>
 #include <libevmface/Instruction.h>
-#include <libethcore/CommonEth.h>
 #include "CompilerState.h"
 using namespace std;
 using namespace eth;
-- 
cgit v1.2.3


From e65c3ff17de66cfd7d80ef78abba09c6ecf35ded Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Mon, 30 Jun 2014 11:49:52 +0200
Subject: Docs & consolidation of headers.

---
 All.h | 7 +++++++
 1 file changed, 7 insertions(+)
 create mode 100644 All.h

diff --git a/All.h b/All.h
new file mode 100644
index 00000000..ec6989e6
--- /dev/null
+++ b/All.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "Assembly.h"
+#include "CodeFragment.h"
+#include "Compiler.h"
+#include "CompilerState.h"
+#include "Parser.h"
-- 
cgit v1.2.3


From 3174a5e0c6072004159326f000c0e1dfe6703b00 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Tue, 1 Jul 2014 00:16:01 +0200
Subject: Fixed problem with alloc.

---
 Assembly.cpp      |  5 +++++
 Assembly.h        |  2 ++
 CodeFragment.cpp  | 39 +++++++++++++++++++++++++++++++++++++--
 CodeFragment.h    |  7 +++++--
 Compiler.cpp      |  4 ++--
 CompilerState.cpp |  3 +--
 CompilerState.h   |  1 +
 7 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 0fa12537..7016b286 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -176,6 +176,11 @@ AssemblyItem const& Assembly::append(AssemblyItem const& _i)
 	return back();
 }
 
+void Assembly::injectStart(AssemblyItem const& _i)
+{
+	m_items.insert(m_items.begin(), _i);
+}
+
 inline bool matches(AssemblyItemsConstRef _a, AssemblyItemsConstRef _b)
 {
 	if (_a.size() != _b.size())
diff --git a/Assembly.h b/Assembly.h
index 3e8a8326..9cd10a82 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -98,6 +98,8 @@ public:
 
 	void popTo(int _deposit) { while (m_deposit > _deposit) append(Instruction::POP); }
 
+	void injectStart(AssemblyItem const& _i);
+
 	std::string out() const { std::stringstream ret; streamOut(ret); return ret.str(); }
 	int deposit() const { return m_deposit; }
 	bytes assemble() const;
diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index f0aeb860..70973aab 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -19,7 +19,6 @@
  * @date 2014
  */
 
-#include "Parser.h"
 #include "CodeFragment.h"
 
 #include <boost/algorithm/string.hpp>
@@ -27,12 +26,30 @@
 #include <libethential/Log.h>
 #include <libevmface/Instruction.h>
 #include "CompilerState.h"
+#include "Parser.h"
 using namespace std;
 using namespace eth;
 namespace qi = boost::spirit::qi;
 namespace px = boost::phoenix;
 namespace sp = boost::spirit;
 
+void CodeFragment::finalise(CompilerState const& _cs)
+{
+	if (_cs.usedAlloc && _cs.vars.size() && !m_finalised)
+	{
+		m_finalised = true;
+		m_asm.injectStart(Instruction::MSTORE8);
+		m_asm.injectStart((u256)((_cs.vars.size() + 2) * 32) - 1);
+		m_asm.injectStart((u256)1);
+	}
+}
+
+bytes CodeFragment::code(CompilerState const& _cs)
+{
+	finalise(_cs);
+	return m_asm.assemble();
+}
+
 CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowASM)
 {
 /*	cdebug << "CodeFragment. Locals:";
@@ -317,6 +334,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 		vector<CodeFragment> code;
 		CompilerState ns = _s;
 		ns.vars.clear();
+		ns.usedAlloc = false;
 		int c = _t.tag() ? 1 : 0;
 		for (auto const& i: _t)
 			if (c++)
@@ -456,13 +474,30 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 			m_asm.appendJump(begin);
 			m_asm << end.tag();
 		}
+		else if (us == "ALLOC")
+		{
+			requireSize(1);
+			requireDeposit(0, 1);
+
+			m_asm.append(Instruction::MEMSIZE);
+			m_asm.append(u256(0));
+			m_asm.append(u256(1));
+			m_asm.append(code[0].m_asm, 1);
+			m_asm.append(Instruction::MEMSIZE);
+			m_asm.append(Instruction::ADD);
+			m_asm.append(Instruction::SUB);
+			m_asm.append(Instruction::MSTORE8);
+
+			_s.usedAlloc = true;
+		}
 		else if (us == "LLL")
 		{
 			requireMinSize(2);
 			requireMaxSize(3);
 			requireDeposit(1, 1);
 
-			bytes const& subcode = code[0].code();
+			code[0].optimise();
+			bytes subcode = code[0].code(ns);
 
 			m_asm.append((u256)subcode.size());
 			m_asm.append(Instruction::DUP);
diff --git a/CodeFragment.h b/CodeFragment.h
index b9d44c03..58e40912 100644
--- a/CodeFragment.h
+++ b/CodeFragment.h
@@ -43,18 +43,21 @@ public:
 	static CodeFragment compile(std::string const& _src, CompilerState& _s);
 
 	/// Consolidates data and compiles code.
-	bytes code() const { return m_asm.assemble(); }
+	bytes code(CompilerState const& _cs);
 
 	/// Consolidates data and compiles code.
-	std::string assembly() const { return m_asm.out(); }
+	std::string assembly(CompilerState const& _cs) { finalise(_cs); return m_asm.out(); }
 
 	/// Optimise the code. Best do this just before calling code() or assembly().
 	void optimise() { m_asm.optimise(); }
 
 private:
+	void finalise(CompilerState const& _cs);
+
 	template <class T> void error() const { throw T(); }
 	void constructOperation(sp::utree const& _t, CompilerState& _s);
 
+	bool m_finalised = false;
 	Assembly m_asm;
 };
 
diff --git a/Compiler.cpp b/Compiler.cpp
index 8400ad95..0faf478d 100644
--- a/Compiler.cpp
+++ b/Compiler.cpp
@@ -36,7 +36,7 @@ bytes eth::compileLLL(string const& _src, bool _opt, vector<string>* _errors)
 		auto f = CodeFragment::compile(_src, cs);
 		if (_opt)
 			f.optimise();
-		bytes ret = f.code();
+		bytes ret = f.code(cs);
 		for (auto i: cs.treesToKill)
 			killBigints(i);
 		return ret;
@@ -63,7 +63,7 @@ std::string eth::compileLLLToAsm(std::string const& _src, bool _opt, std::vector
 		auto f = CodeFragment::compile(_src, cs);
 		if (_opt)
 			f.optimise();
-		string ret = f.assembly();
+		string ret = f.assembly(cs);
 		for (auto i: cs.treesToKill)
 			killBigints(i);
 		return ret;
diff --git a/CompilerState.cpp b/CompilerState.cpp
index 7e990413..7a668190 100644
--- a/CompilerState.cpp
+++ b/CompilerState.cpp
@@ -52,8 +52,7 @@ void CompilerState::populateStandard()
 	"(def 'regname (name) { [0]:name (call (- (gas) 21) namereg 0 0 32 0 0) })"
 	"(def 'send (to value) (call (- (gas) 21) to value 0 0 0 0))"
 	"(def 'send (gaslimit to value) (call gaslimit to value 0 0 0 0))"
-	"(def 'alloc (len) (asm msize 0 1 len msize add sub mstore8))"
-	"(def 'msg (gaslimit to value data datasize outsize) { [32]:outsize [0]:(alloc @32) (call gaslimit to value data datasize @0 @32) @0 })"
+	"(def 'msg (gaslimit to value data datasize outsize) { (set x outsize) (set y (alloc @32)) (call gaslimit to value data datasize @0 @32) @0 })"
 	"(def 'msg (gaslimit to value data datasize) { (call gaslimit to value data datasize 0 32) @0 })"
 	"(def 'msg (gaslimit to value data) { [0]:data (msg gaslimit to value 0 32) })"
 	"(def 'msg (to value data) { [0]:data (msg 0 to value 0 32) })"
diff --git a/CompilerState.h b/CompilerState.h
index f8f7ce81..5dcde614 100644
--- a/CompilerState.h
+++ b/CompilerState.h
@@ -48,6 +48,7 @@ struct CompilerState
 	std::map<std::string, CodeFragment> outers;
 	std::map<std::pair<std::string, unsigned>, Macro> macros;
 	std::vector<boost::spirit::utree> treesToKill;
+	bool usedAlloc = false;
 };
 
 }
-- 
cgit v1.2.3


From a8133b6f489cd7357e64c918d096d1180962670e Mon Sep 17 00:00:00 2001
From: Vitalik Buterin <v@buterin.com>
Date: Tue, 1 Jul 2014 13:29:58 -0400
Subject: Removed libethcore dependencies

---
 Assembly.h   | 1 -
 Exceptions.h | 2 --
 2 files changed, 3 deletions(-)

diff --git a/Assembly.h b/Assembly.h
index 9cd10a82..4a6d02ce 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -25,7 +25,6 @@
 #include <sstream>
 #include <libethential/Common.h>
 #include <libevmface/Instruction.h>
-#include <libethcore/SHA3.h>
 #include "Exceptions.h"
 
 namespace eth
diff --git a/Exceptions.h b/Exceptions.h
index 79b7cd52..a1aee173 100644
--- a/Exceptions.h
+++ b/Exceptions.h
@@ -21,8 +21,6 @@
 
 #pragma once
 
-#include <libethcore/Exceptions.h>
-
 namespace eth
 {
 
-- 
cgit v1.2.3


From 17010d445c28d5d67ebb124563f3b9f6991f034f Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Wed, 2 Jul 2014 10:19:04 +0200
Subject: Remove unneeded dependencies.

---
 Assembly.cpp | 1 -
 Assembly.h   | 1 -
 Parser.cpp   | 5 ++++-
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 7016b286..f4d700f9 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -22,7 +22,6 @@
 #include "Assembly.h"
 
 #include <libethential/Log.h>
-#include <libethcore/CommonEth.h>
 
 using namespace std;
 using namespace eth;
diff --git a/Assembly.h b/Assembly.h
index 9cd10a82..4a6d02ce 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -25,7 +25,6 @@
 #include <sstream>
 #include <libethential/Common.h>
 #include <libevmface/Instruction.h>
-#include <libethcore/SHA3.h>
 #include "Exceptions.h"
 
 namespace eth
diff --git a/Parser.cpp b/Parser.cpp
index 0ae3c6fe..d7658f67 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -24,7 +24,6 @@
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix.hpp>
 #include <boost/spirit/include/support_utree.hpp>
-#include <libethcore/CommonEth.h>
 
 using namespace std;
 using namespace eth;
@@ -73,6 +72,10 @@ void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
 	typedef sp::basic_string<std::string, sp::utree_type::symbol_type> symbol_type;
 	typedef string::const_iterator it;
 
+	static const u256 ether = u256(1000000000) * 1000000000;
+	static const u256 finney = u256(1000000000) * 1000000;
+	static const u256 szabo = u256(1000000000) * 1000;
+
 	qi::rule<it, qi::ascii::space_type, sp::utree()> element;
 	qi::rule<it, string()> str = '"' > qi::lexeme[+(~qi::char_(std::string("\"") + '\0'))] > '"';
 	qi::rule<it, string()> strsh = '\'' > qi::lexeme[+(~qi::char_(std::string(" ;@()[]{}:") + '\0'))];
-- 
cgit v1.2.3


From 67315763116cf78b8c2047ce8bd2808576d8c066 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Wed, 2 Jul 2014 14:39:21 +0200
Subject: Fix some macros.

---
 CompilerState.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/CompilerState.cpp b/CompilerState.cpp
index 7a668190..e1d71011 100644
--- a/CompilerState.cpp
+++ b/CompilerState.cpp
@@ -55,8 +55,8 @@ void CompilerState::populateStandard()
 	"(def 'msg (gaslimit to value data datasize outsize) { (set x outsize) (set y (alloc @32)) (call gaslimit to value data datasize @0 @32) @0 })"
 	"(def 'msg (gaslimit to value data datasize) { (call gaslimit to value data datasize 0 32) @0 })"
 	"(def 'msg (gaslimit to value data) { [0]:data (msg gaslimit to value 0 32) })"
-	"(def 'msg (to value data) { [0]:data (msg 0 to value 0 32) })"
-	"(def 'msg (to data) { [0]:data (msg 0 to 0 0 32) })"
+	"(def 'msg (to value data) { [0]:data (msg (- gas 21) to value 0 32) })"
+	"(def 'msg (to data) { [0]:data (msg (- gas 21) to 0 0 32) })"
 	"(def 'create (value code) { [0]:(msize) (create value @0 (lll code @0)) })"
 	"(def 'create (code) { [0]:(msize) (create 0 @0 (lll code @0)) })"
 	"(def 'sha3 (val) { [0]:val (sha3 0 32) })"
-- 
cgit v1.2.3


From f4c99cdbb9f6123b33e29cb810c8781b5a2ba125 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Thu, 3 Jul 2014 15:00:22 +0200
Subject: Windows build coersions.

---
 CMakeLists.txt |  7 +++++--
 Compiler.cpp   |  6 +++++-
 Parser.cpp     | 13 ++++++++-----
 3 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2356b7d9..99d6d980 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,7 +7,11 @@ aux_source_directory(. SRC_LIST)
 set(EXECUTABLE lll)
 
 # set(CMAKE_INSTALL_PREFIX ../lib)
-add_library(${EXECUTABLE} SHARED ${SRC_LIST})
+if(ETH_STATIC)
+	add_library(${EXECUTABLE} STATIC ${SRC_LIST})
+else()
+	add_library(${EXECUTABLE} SHARED ${SRC_LIST})
+endif()
 
 file(GLOB HEADERS "*.h") 
 
@@ -15,7 +19,6 @@ include_directories(..)
 
 target_link_libraries(${EXECUTABLE} evmface)
 target_link_libraries(${EXECUTABLE} ethential)
-target_link_libraries(${EXECUTABLE} gmp)
 
 
 if(${TARGET_PLATFORM} STREQUAL "w64")
diff --git a/Compiler.cpp b/Compiler.cpp
index 0faf478d..1621acf9 100644
--- a/Compiler.cpp
+++ b/Compiler.cpp
@@ -84,7 +84,11 @@ std::string eth::compileLLLToAsm(std::string const& _src, bool _opt, std::vector
 string eth::parseLLL(string const& _src)
 {
 	sp::utree o;
-	parseTreeLLL(_src, o);
+	try
+	{
+		parseTreeLLL(_src, o);
+	}
+	catch (...) {}
 	ostringstream ret;
 	debugOutAST(ret, o);
 	killBigints(o);
diff --git a/Parser.cpp b/Parser.cpp
index d7658f67..4adcdd0e 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -21,6 +21,8 @@
 
 #include "Parser.h"
 
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#define BOOST_SPIRIT_USE_PHOENIX_V3
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix.hpp>
 #include <boost/spirit/include/support_utree.hpp>
@@ -93,12 +95,13 @@ void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
 	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> list = '(' > *element > ')';
 
 	// todo: fix compound compile errors in this line for Visual Studio 2013
-#ifndef _MSC_VER
-	qi::rule<it, qi::ascii::space_type, sp::utree()> extra = sload[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 2)] | mload[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 1)] | sstore[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 4)] | mstore[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 3)] | seq[qi::_val = qi::_1, bind(&sp::utree::tag, qi::_val, 5)];
+//#ifndef _MSC_VER
+	auto x = [](int a) { return [=](sp::utree& n, typename qi::rule<it, qi::ascii::space_type, sp::utree()>::context_type& c) { (boost::fusion::at_c<0>(c.attributes) = n).tag(a); }; };
+	qi::rule<it, qi::ascii::space_type, sp::utree()> extra = mload[x(1)] | sload[x(2)] | mstore[x(3)] | sstore[x(4)] | seq[x(5)];
 	element = atom | list | extra;
-#else
-	element = atom | list/* | extra*/;
-#endif
+/*#else
+	element = atom | list;
+#endif*/
 	
 
 	string s;
-- 
cgit v1.2.3


From a7f469020033b8879a99e6c9dc7cc68deed14c9f Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Fri, 4 Jul 2014 03:45:21 +0200
Subject: Latest API updates.

---
 Parser.cpp | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/Parser.cpp b/Parser.cpp
index 4adcdd0e..53580898 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -94,15 +94,9 @@ void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
 	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> sstore = qi::lit("[[") > element > qi::lit("]]") > -qi::lit(":") > element;
 	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> list = '(' > *element > ')';
 
-	// todo: fix compound compile errors in this line for Visual Studio 2013
-//#ifndef _MSC_VER
 	auto x = [](int a) { return [=](sp::utree& n, typename qi::rule<it, qi::ascii::space_type, sp::utree()>::context_type& c) { (boost::fusion::at_c<0>(c.attributes) = n).tag(a); }; };
-	qi::rule<it, qi::ascii::space_type, sp::utree()> extra = mload[x(1)] | sload[x(2)] | mstore[x(3)] | sstore[x(4)] | seq[x(5)];
+	qi::rule<it, qi::ascii::space_type, sp::utree()> extra = sload[x(2)] | mload[x(1)] | sstore[x(4)] | mstore[x(3)] | seq[x(5)];
 	element = atom | list | extra;
-/*#else
-	element = atom | list;
-#endif*/
-	
 
 	string s;
 	s.reserve(_s.size());
-- 
cgit v1.2.3


From b5cc0ae6cdf0bef2a92845fc6f5b74ce47d6428c Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Sun, 6 Jul 2014 04:23:13 +0200
Subject: Compiler fixes. Updates for coins.

---
 Assembly.cpp      |  2 ++
 CodeFragment.cpp  |  3 +++
 CompilerState.cpp | 16 +++++++++-------
 CompilerState.h   |  2 +-
 Parser.cpp        | 13 ++++++++-----
 5 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index f4d700f9..6f567853 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -74,12 +74,14 @@ unsigned Assembly::bytesRequired() const
 
 void Assembly::append(Assembly const& _a)
 {
+	auto newDeposit = m_deposit + _a.deposit();
 	for (AssemblyItem i: _a.m_items)
 	{
 		if (i.type() == Tag || i.type() == PushTag)
 			i.m_data += m_usedTags;
 		append(i);
 	}
+	m_deposit = newDeposit;
 	m_usedTags += _a.m_usedTags;
 	for (auto const& i: _a.m_data)
 		m_data.insert(i);
diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index 70973aab..47c83e63 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -151,6 +151,9 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 		case 5:
 			us = "SEQ";
 			break;
+		case 6:
+			us = "CALLDATALOAD";
+			break;
 		default:;
 		}
 
diff --git a/CompilerState.cpp b/CompilerState.cpp
index e1d71011..380d5a66 100644
--- a/CompilerState.cpp
+++ b/CompilerState.cpp
@@ -45,18 +45,20 @@ void CompilerState::populateStandard()
 {
 	static const string s = "{"
 	"(def 'gav 0x51ba59315b3a95761d0863b05ccc7a7f54703d99)"
-	"(def 'namereg 0x2d0aceee7e5ab874e22ccf8d1a649f59106d74e8)"
-	"(def 'config 0xccdeac59d35627b7de09332e819d5159e7bb7250)"
+	"(def 'config 0x661005d2720d855f1d9976f88bb10c1a3398c77f)"
+	"(def 'namereg 0x50441127ea5b9dfd835a9aba4e1dc9c1257b58ca)"
 	"(def 'gavcoin 0x5620133321fcac7f15a5c570016f6cb6dc263f9d)"
-	"(def 'sendgavcoin (to value) { [0]:to [32]:value (call (- (gas) 21) gavcoin 0 0 64 0 0) })"
-	"(def 'regname (name) { [0]:name (call (- (gas) 21) namereg 0 0 32 0 0) })"
-	"(def 'send (to value) (call (- (gas) 21) to value 0 0 0 0))"
+	"(def 'allgas (- (gas) 21))"
+	"(def 'sendgavcoin (to value) { [0]'send [32]:to [64]:value (call allgas gavcoin 0 0 96 0 0) })"
+	"(def 'regname (name) { [0]'register [32]name (call allgas namereg 0 0 64 0 0) })"
+	"(def 'regcoins (name) { [0]'register [32]name (call allgas namereg 0 0 64 0 0) })"
+	"(def 'send (to value) (call allgas to value 0 0 0 0))"
 	"(def 'send (gaslimit to value) (call gaslimit to value 0 0 0 0))"
 	"(def 'msg (gaslimit to value data datasize outsize) { (set x outsize) (set y (alloc @32)) (call gaslimit to value data datasize @0 @32) @0 })"
 	"(def 'msg (gaslimit to value data datasize) { (call gaslimit to value data datasize 0 32) @0 })"
 	"(def 'msg (gaslimit to value data) { [0]:data (msg gaslimit to value 0 32) })"
-	"(def 'msg (to value data) { [0]:data (msg (- gas 21) to value 0 32) })"
-	"(def 'msg (to data) { [0]:data (msg (- gas 21) to 0 0 32) })"
+	"(def 'msg (to value data) { [0]:data (msg allgas to value 0 32) })"
+	"(def 'msg (to data) { [0]:data (msg allgas to 0 0 32) })"
 	"(def 'create (value code) { [0]:(msize) (create value @0 (lll code @0)) })"
 	"(def 'create (code) { [0]:(msize) (create 0 @0 (lll code @0)) })"
 	"(def 'sha3 (val) { [0]:val (sha3 0 32) })"
diff --git a/CompilerState.h b/CompilerState.h
index 5dcde614..a0b3bf46 100644
--- a/CompilerState.h
+++ b/CompilerState.h
@@ -41,7 +41,7 @@ struct CompilerState
 	CodeFragment const& getDef(std::string const& _s);
 	void populateStandard();
 
-	unsigned stackSize = 64;
+	unsigned stackSize = 128;
 	std::map<std::string, std::pair<unsigned, unsigned>> vars;       ///< maps name to stack offset & size.
 	std::map<std::string, CodeFragment> defs;
 	std::map<std::string, CodeFragment> args;
diff --git a/Parser.cpp b/Parser.cpp
index 53580898..314e6cf7 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -56,6 +56,7 @@ void eth::debugOutAST(ostream& _out, sp::utree const& _this)
 		case 3: _out << "[ "; debugOutAST(_out, _this.front()); _out << " ] "; debugOutAST(_out, _this.back()); break;
 		case 4: _out << "[[ "; debugOutAST(_out, _this.front()); _out << " ]] "; debugOutAST(_out, _this.back()); break;
 		case 5: _out << "{ "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << "}"; break;
+		case 6: _out << "$ "; debugOutAST(_out, _this.front()); break;
 		default:;
 		}
 
@@ -80,8 +81,8 @@ void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
 
 	qi::rule<it, qi::ascii::space_type, sp::utree()> element;
 	qi::rule<it, string()> str = '"' > qi::lexeme[+(~qi::char_(std::string("\"") + '\0'))] > '"';
-	qi::rule<it, string()> strsh = '\'' > qi::lexeme[+(~qi::char_(std::string(" ;@()[]{}:") + '\0'))];
-	qi::rule<it, symbol_type()> symbol = qi::lexeme[+(~qi::char_(std::string(" @[]{}:();\"\x01-\x1f\x7f") + '\0'))];
+	qi::rule<it, string()> strsh = '\'' > qi::lexeme[+(~qi::char_(std::string(" ;$@()[]{}:\n\t") + '\0'))];
+	qi::rule<it, symbol_type()> symbol = qi::lexeme[+(~qi::char_(std::string(" $@[]{}:();\"\x01-\x1f\x7f") + '\0'))];
 	qi::rule<it, string()> intstr = qi::lexeme[ qi::no_case["0x"][qi::_val = "0x"] >> *qi::char_("0-9a-fA-F")[qi::_val += qi::_1]] | qi::lexeme[+qi::char_("0-9")[qi::_val += qi::_1]];
 	qi::rule<it, bigint()> integer = intstr;
 	qi::rule<it, bigint()> multiplier = qi::lit("wei")[qi::_val = 1] | qi::lit("szabo")[qi::_val = szabo] | qi::lit("finney")[qi::_val = finney] | qi::lit("ether")[qi::_val = ether];
@@ -92,10 +93,11 @@ void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
 	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> sload = qi::lit("@@") > element;
 	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> mstore = '[' > element > ']' > -qi::lit(":") > element;
 	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> sstore = qi::lit("[[") > element > qi::lit("]]") > -qi::lit(":") > element;
+	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> calldataload = qi::lit("$") > element;
 	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> list = '(' > *element > ')';
 
 	auto x = [](int a) { return [=](sp::utree& n, typename qi::rule<it, qi::ascii::space_type, sp::utree()>::context_type& c) { (boost::fusion::at_c<0>(c.attributes) = n).tag(a); }; };
-	qi::rule<it, qi::ascii::space_type, sp::utree()> extra = sload[x(2)] | mload[x(1)] | sstore[x(4)] | mstore[x(3)] | seq[x(5)];
+	qi::rule<it, qi::ascii::space_type, sp::utree()> extra = sload[x(2)] | mload[x(1)] | sstore[x(4)] | mstore[x(3)] | seq[x(5)] | calldataload[x(6)];
 	element = atom | list | extra;
 
 	string s;
@@ -120,7 +122,8 @@ void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
 	}
 	auto ret = s.cbegin();
 	qi::phrase_parse(ret, s.cend(), element, space, qi::skip_flag::dont_postskip, o_out);
-	if (ret != s.cend())
-		throw std::exception();
+	for (auto i = ret; i != s.cend(); ++i)
+		if (!isspace(*i))
+			throw std::exception();
 }
 
-- 
cgit v1.2.3


From 352e75179999d6de562b810ccffd874c0fb4bc66 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Sun, 6 Jul 2014 13:13:37 +0200
Subject: Build fixes.

---
 CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 99d6d980..b220d8e9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,7 +21,7 @@ target_link_libraries(${EXECUTABLE} evmface)
 target_link_libraries(${EXECUTABLE} ethential)
 
 
-if(${TARGET_PLATFORM} STREQUAL "w64")
+if("${TARGET_PLATFORM}" STREQUAL "w64")
 	target_link_libraries(${EXECUTABLE} boost_system-mt-s)
 	target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s)
 	target_link_libraries(${EXECUTABLE} iphlpapi)
-- 
cgit v1.2.3


From e128f34b6ba7b3dd2337fde54a2cf1e16489de1e Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Wed, 9 Jul 2014 16:05:07 +0100
Subject: MEMSIZE -> MSIZE

---
 CodeFragment.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index 47c83e63..d19d7509 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -482,11 +482,11 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 			requireSize(1);
 			requireDeposit(0, 1);
 
-			m_asm.append(Instruction::MEMSIZE);
+			m_asm.append(Instruction::MSIZE);
 			m_asm.append(u256(0));
 			m_asm.append(u256(1));
 			m_asm.append(code[0].m_asm, 1);
-			m_asm.append(Instruction::MEMSIZE);
+			m_asm.append(Instruction::MSIZE);
 			m_asm.append(Instruction::ADD);
 			m_asm.append(Instruction::SUB);
 			m_asm.append(Instruction::MSTORE8);
-- 
cgit v1.2.3


From f9612d61be27af23446fe1fb0cae9e2743c1e58d Mon Sep 17 00:00:00 2001
From: Tim Hughes <tim@twistedfury.com>
Date: Wed, 9 Jul 2014 19:43:39 +0100
Subject: Fixed MSVC build errors and updated projects.

---
 Parser.cpp | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/Parser.cpp b/Parser.cpp
index 314e6cf7..1907fd17 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -69,9 +69,24 @@ void eth::debugOutAST(ostream& _out, sp::utree const& _this)
 	}
 }
 
+namespace eth {
+namespace parseTreeLLL_ {
+
+template<unsigned N>
+struct tagNode
+{
+	void operator()(sp::utree& n, qi::rule<string::const_iterator, qi::ascii::space_type, sp::utree()>::context_type& c) const
+	{
+		(boost::fusion::at_c<0>(c.attributes) = n).tag(N);
+	}
+};
+
+}}
+
 void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
 {
 	using qi::ascii::space;
+	using eth::parseTreeLLL_::tagNode;
 	typedef sp::basic_string<std::string, sp::utree_type::symbol_type> symbol_type;
 	typedef string::const_iterator it;
 
@@ -96,8 +111,7 @@ void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
 	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> calldataload = qi::lit("$") > element;
 	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> list = '(' > *element > ')';
 
-	auto x = [](int a) { return [=](sp::utree& n, typename qi::rule<it, qi::ascii::space_type, sp::utree()>::context_type& c) { (boost::fusion::at_c<0>(c.attributes) = n).tag(a); }; };
-	qi::rule<it, qi::ascii::space_type, sp::utree()> extra = sload[x(2)] | mload[x(1)] | sstore[x(4)] | mstore[x(3)] | seq[x(5)] | calldataload[x(6)];
+	qi::rule<it, qi::ascii::space_type, sp::utree()> extra = sload[tagNode<2>()] | mload[tagNode<1>()] | sstore[tagNode<4>()] | mstore[tagNode<3>()] | seq[tagNode<5>()] | calldataload[tagNode<6>()];
 	element = atom | list | extra;
 
 	string s;
-- 
cgit v1.2.3


From 8dfad3e7c0ef1f0dd7527e0ed52663b52fc1e870 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Mon, 21 Jul 2014 15:14:44 +0200
Subject: Move JS setup code up into lib macro. Remove a few redundant messages
 from build.

---
 CMakeLists.txt | 2 --
 1 file changed, 2 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b220d8e9..98bebdfe 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,8 +45,6 @@ else ()
 	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} )
 
-- 
cgit v1.2.3


From b56713375074a1db82ad44726f43dcfc12f37141 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Wed, 23 Jul 2014 22:51:14 +0200
Subject: Minor updates.

---
 Assembly.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 6f567853..3abdf66f 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -116,7 +116,7 @@ ostream& eth::operator<<(ostream& _out, AssemblyItemsConstRef _i)
 			_out << " PUSH" << i.data();
 			break;
 		case PushString:
-			_out << " PUSH'[" << h256(i.data()).abridged() << "]";
+			_out << " PUSH'[" << hex << (unsigned)i.data() << "]";
 			break;
 		case PushTag:
 			_out << " PUSH[tag" << i.data() << "]";
@@ -125,7 +125,7 @@ ostream& eth::operator<<(ostream& _out, AssemblyItemsConstRef _i)
 			_out << " tag" << i.data() << ":";
 			break;
 		case PushData:
-			_out << " PUSH*[" << h256(i.data()).abridged() << "]";
+			_out << " PUSH*[" << hex << (unsigned)i.data() << "]";
 			break;
 		case UndefinedItem:
 			_out << " ???";
@@ -156,7 +156,7 @@ ostream& Assembly::streamOut(ostream& _out) const
 			_out << "tag" << i.m_data << ": " << endl;
 			break;
 		case PushData:
-			_out << "  PUSH [" << h256(i.m_data).abridged() << "]" << endl;
+			_out << "  PUSH [" << hex << (unsigned)i.m_data << "]" << endl;
 			break;
 		default:;
 		}
@@ -165,7 +165,7 @@ ostream& Assembly::streamOut(ostream& _out) const
 	{
 		_out << ".data:" << endl;
 		for (auto const& i: m_data)
-			_out << "  " << i.first.abridged() << ": " << toHex(i.second) << endl;
+			_out << "  " << hex << (unsigned)(u256)i.first << ": " << toHex(i.second) << endl;
 	}
 	return _out;
 }
-- 
cgit v1.2.3


From 510abc0997c248a1a767ceade6749f426ae3a968 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Sun, 27 Jul 2014 11:20:43 +0200
Subject: Fixes and whatnot.

---
 CompilerState.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/CompilerState.cpp b/CompilerState.cpp
index 380d5a66..01995674 100644
--- a/CompilerState.cpp
+++ b/CompilerState.cpp
@@ -62,6 +62,8 @@ void CompilerState::populateStandard()
 	"(def 'create (value code) { [0]:(msize) (create value @0 (lll code @0)) })"
 	"(def 'create (code) { [0]:(msize) (create 0 @0 (lll code @0)) })"
 	"(def 'sha3 (val) { [0]:val (sha3 0 32) })"
+	"(def 'sha3pair (a b) { [0]:a [32]:b (sha3 0 64) })"
+	"(def 'sha3trip (a b c) { [0]:a [32]:b [64]:c (sha3 0 96) })"
 	"(def 'return (val) { [0]:val (return 0 32) })"
 	"(def 'returnlll (code) (return 0 (lll code 0)) )"
 	"(def 'makeperm (name pos) { (def name (sload pos)) (def name (v) (sstore pos v)) } )"
-- 
cgit v1.2.3


From ed0209fefc50ab59b43b7f781410699c49445aab Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Sun, 27 Jul 2014 13:09:36 +0200
Subject: Updates to assembler - see the sub-codes.

---
 Assembly.cpp     | 74 +++++++++++++++++++++++++++++++++++++++++++++-----------
 Assembly.h       | 12 ++++++---
 CodeFragment.cpp | 13 ++--------
 CodeFragment.h   |  8 +-----
 Compiler.cpp     |  9 ++-----
 5 files changed, 73 insertions(+), 43 deletions(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 3abdf66f..78552f3c 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -32,7 +32,7 @@ int AssemblyItem::deposit() const
 	{
 	case Operation:
 		return c_instructionInfo.at((Instruction)(byte)m_data).ret - c_instructionInfo.at((Instruction)(byte)m_data).args;
-	case Push: case PushString: case PushTag: case PushData:
+	case Push: case PushString: case PushTag: case PushData: case PushSub: case PushSubSize:
 		return 1;
 	case Tag:
 		return 0;
@@ -61,8 +61,12 @@ unsigned Assembly::bytesRequired() const
 			case Push:
 				ret += 1 + max<unsigned>(1, eth::bytesRequired(i.m_data));
 				break;
+			case PushSubSize:
+				ret += 4;		// worst case: a 16MB program
+				break;
 			case PushTag:
 			case PushData:
+			case PushSub:
 				ret += 1 + br;
 			case Tag:;
 			default:;
@@ -87,6 +91,8 @@ void Assembly::append(Assembly const& _a)
 		m_data.insert(i);
 	for (auto const& i: _a.m_strings)
 		m_strings.insert(i);
+	for (auto const& i: _a.m_subs)
+		m_subs.insert(i);
 
 	assert(!_a.m_baseDeposit);
 	assert(!_a.m_totalDeposit);
@@ -127,6 +133,12 @@ ostream& eth::operator<<(ostream& _out, AssemblyItemsConstRef _i)
 		case PushData:
 			_out << " PUSH*[" << hex << (unsigned)i.data() << "]";
 			break;
+		case PushSub:
+			_out << " PUSHs[" << hex << h256(i.data()).abridged() << "]";
+			break;
+		case PushSubSize:
+			_out << " PUSHss[" << hex << h256(i.data()).abridged() << "]";
+			break;
 		case UndefinedItem:
 			_out << " ???";
 		default:;
@@ -134,38 +146,50 @@ ostream& eth::operator<<(ostream& _out, AssemblyItemsConstRef _i)
 	return _out;
 }
 
-ostream& Assembly::streamOut(ostream& _out) const
+ostream& Assembly::streamOut(ostream& _out, string const& _prefix) const
 {
-	_out << ".code:" << endl;
+	_out << _prefix << ".code:" << endl;
 	for (AssemblyItem const& i: m_items)
 		switch (i.m_type)
 		{
 		case Operation:
-			_out << "  " << c_instructionInfo.at((Instruction)(byte)i.m_data).name << endl;
+			_out << _prefix << "  " << c_instructionInfo.at((Instruction)(byte)i.m_data).name << endl;
 			break;
 		case Push:
-			_out << "  PUSH " << i.m_data << endl;
+			_out << _prefix << "  PUSH " << i.m_data << endl;
 			break;
 		case PushString:
-			_out << "  PUSH \"" << m_strings.at((h256)i.m_data) << "\"" << endl;
+			_out << _prefix << "  PUSH \"" << m_strings.at((h256)i.m_data) << "\"" << endl;
 			break;
 		case PushTag:
-			_out << "  PUSH [tag" << i.m_data << "]" << endl;
+			_out << _prefix << "  PUSH [tag" << i.m_data << "]" << endl;
+			break;
+		case PushSub:
+			_out << _prefix << "  PUSH [$" << h256(i.m_data).abridged() << "]" << endl;
+			break;
+		case PushSubSize:
+			_out << _prefix << "  PUSH #[$" << h256(i.m_data).abridged() << "]" << endl;
 			break;
 		case Tag:
-			_out << "tag" << i.m_data << ": " << endl;
+			_out << _prefix << "tag" << i.m_data << ": " << endl;
 			break;
 		case PushData:
-			_out << "  PUSH [" << hex << (unsigned)i.m_data << "]" << endl;
+			_out << _prefix << "  PUSH [" << hex << (unsigned)i.m_data << "]" << endl;
 			break;
 		default:;
 		}
 
-	if (m_data.size())
+	if (m_data.size() || m_subs.size())
 	{
-		_out << ".data:" << endl;
+		_out << _prefix << ".data:" << endl;
 		for (auto const& i: m_data)
-			_out << "  " << hex << (unsigned)(u256)i.first << ": " << toHex(i.second) << endl;
+			if (!m_subs.count(i.first))
+				_out << _prefix << "  " << hex << (unsigned)(u256)i.first << ": " << toHex(i.second) << endl;
+		for (auto const& i: m_subs)
+		{
+			_out << _prefix << "  " << hex << (unsigned)(u256)i.first << ": " << endl;
+			i.second.streamOut(_out, _prefix + "  ");
+		}
 	}
 	return _out;
 }
@@ -195,8 +219,10 @@ inline bool matches(AssemblyItemsConstRef _a, AssemblyItemsConstRef _b)
 struct OptimiserChannel: public LogChannel { static const char* name() { return "OPT"; } static const int verbosity = 12; };
 #define copt eth::LogOutputStream<OptimiserChannel, true>()
 
-void Assembly::optimise()
+Assembly& Assembly::optimise(bool _enable)
 {
+	if (!_enable)
+		return *this;
 	map<Instruction, function<u256(u256, u256)>> c_simple =
 	{
 		{ Instruction::SUB, [](u256 a, u256 b)->u256{return a - b;} },
@@ -221,6 +247,8 @@ void Assembly::optimise()
 		{ { Push, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
 		{ { PushTag, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
 		{ { PushString, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
+		{ { PushSub, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
+		{ { PushSubSize, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
 		{ { Push, PushTag, Instruction::JUMPI }, [](AssemblyItemsConstRef m) -> AssemblyItems { if (m[0].data()) return { m[1], Instruction::JUMP }; else return {}; } },
 		{ { Instruction::NOT, Instruction::NOT }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
 	};
@@ -309,6 +337,11 @@ void Assembly::optimise()
 	}
 
 	copt << total << " optimisations done.";
+
+	for (auto& i: m_subs)
+	  i.second.optimise(true);
+
+	return *this;
 }
 
 bytes Assembly::assemble() const
@@ -323,6 +356,9 @@ bytes Assembly::assemble() const
 	unsigned bytesPerTag = eth::bytesRequired(totalBytes);
 	byte tagPush = (byte)Instruction::PUSH1 - 1 + bytesPerTag;
 
+	for (auto const& i: m_subs)
+		m_data[i.first] = i.second.assemble();
+
 	for (AssemblyItem const& i: m_items)
 		switch (i.m_type)
 		{
@@ -358,13 +394,23 @@ bytes Assembly::assemble() const
 			ret.resize(ret.size() + bytesPerTag);
 			break;
 		}
-		case PushData:
+		case PushData: case PushSub:
 		{
 			ret.push_back(tagPush);
 			dataRef.insert(make_pair((h256)i.m_data, ret.size()));
 			ret.resize(ret.size() + bytesPerTag);
 			break;
 		}
+		case PushSubSize:
+		{
+			auto s = m_data[i.m_data].size();
+			byte b = max<unsigned>(1, eth::bytesRequired(s));
+			ret.push_back((byte)Instruction::PUSH1 - 1 + b);
+			ret.resize(ret.size() + b);
+			bytesRef byr(&ret.back() + 1 - b, b);
+			toBigEndian(s, byr);
+			break;
+		}
 		case Tag:
 			tagPos[(unsigned)i.m_data] = ret.size();
 			break;
diff --git a/Assembly.h b/Assembly.h
index 4a6d02ce..581e1643 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -30,7 +30,7 @@
 namespace eth
 {
 
-enum AssemblyItemType { UndefinedItem, Operation, Push, PushString, PushTag, Tag, PushData };
+enum AssemblyItemType { UndefinedItem, Operation, Push, PushString, PushTag, PushSub, PushSubSize, Tag, PushData };
 
 class Assembly;
 
@@ -70,7 +70,9 @@ public:
 	AssemblyItem newTag() { return AssemblyItem(Tag, m_usedTags++); }
 	AssemblyItem newPushTag() { return AssemblyItem(PushTag, m_usedTags++); }
 	AssemblyItem newData(bytes const& _data) { h256 h = (u256)std::hash<std::string>()(asString(_data)); m_data[h] = _data; return AssemblyItem(PushData, h); }
+	AssemblyItem newSub(Assembly const& _sub) { h256 h = h256::random(s_fixedHashEngine); m_subs[h] = _sub; return AssemblyItem(PushSub, h); }
 	AssemblyItem newPushString(std::string const& _data) { h256 h = (u256)std::hash<std::string>()(_data); m_strings[h] = _data; return AssemblyItem(PushString, h); }
+	AssemblyItem newPushSubSize(h256 const& _subId) { return AssemblyItem(PushSubSize, _subId); }
 
 	AssemblyItem append() { return append(newTag()); }
 	void append(Assembly const& _a);
@@ -78,6 +80,7 @@ public:
 	AssemblyItem const& append(AssemblyItem const& _i);
 	AssemblyItem const& append(std::string const& _data) { return append(newPushString(_data)); }
 	AssemblyItem const& append(bytes const& _data) { return append(newData(_data)); }
+	AssemblyItem appendSubSize(Assembly const& _asm) { auto ret = newSub(_asm); append(newPushSubSize(ret.data())); return ret; }
 
 	AssemblyItem appendJump() { auto ret = append(newPushTag()); append(Instruction::JUMP); return ret; }
 	AssemblyItem appendJumpI() { auto ret = append(newPushTag()); append(Instruction::JUMPI); return ret; }
@@ -102,8 +105,8 @@ public:
 	std::string out() const { std::stringstream ret; streamOut(ret); return ret.str(); }
 	int deposit() const { return m_deposit; }
 	bytes assemble() const;
-	void optimise();
-	std::ostream& streamOut(std::ostream& _out) const;
+	Assembly& optimise(bool _enable);
+	std::ostream& streamOut(std::ostream& _out, std::string const& _prefix = "") const;
 
 private:
 	void donePath() { if (m_totalDeposit != INT_MAX && m_totalDeposit != m_deposit) throw InvalidDeposit(); }
@@ -111,7 +114,8 @@ private:
 
 	unsigned m_usedTags = 0;
 	AssemblyItems m_items;
-	std::map<h256, bytes> m_data;
+	mutable std::map<h256, bytes> m_data;
+	std::map<h256, Assembly> m_subs;
 	std::map<h256, std::string> m_strings;
 
 	int m_deposit = 0;
diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index d19d7509..bc7fa615 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -44,12 +44,6 @@ void CodeFragment::finalise(CompilerState const& _cs)
 	}
 }
 
-bytes CodeFragment::code(CompilerState const& _cs)
-{
-	finalise(_cs);
-	return m_asm.assemble();
-}
-
 CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowASM)
 {
 /*	cdebug << "CodeFragment. Locals:";
@@ -499,10 +493,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 			requireMaxSize(3);
 			requireDeposit(1, 1);
 
-			code[0].optimise();
-			bytes subcode = code[0].code(ns);
-
-			m_asm.append((u256)subcode.size());
+			auto subPush = m_asm.appendSubSize(code[0].assembly(ns));
 			m_asm.append(Instruction::DUP);
 			if (code.size() == 3)
 			{
@@ -513,7 +504,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 				m_asm.append(Instruction::MUL);
 				m_asm.append(Instruction::DUP);
 			}
-			m_asm.append(subcode);
+			m_asm.append(subPush);
 			m_asm.append(code[1].m_asm, 1);
 			m_asm.append(Instruction::CODECOPY);
 		}
diff --git a/CodeFragment.h b/CodeFragment.h
index 58e40912..98a6f15c 100644
--- a/CodeFragment.h
+++ b/CodeFragment.h
@@ -43,13 +43,7 @@ public:
 	static CodeFragment compile(std::string const& _src, CompilerState& _s);
 
 	/// Consolidates data and compiles code.
-	bytes code(CompilerState const& _cs);
-
-	/// Consolidates data and compiles code.
-	std::string assembly(CompilerState const& _cs) { finalise(_cs); return m_asm.out(); }
-
-	/// Optimise the code. Best do this just before calling code() or assembly().
-	void optimise() { m_asm.optimise(); }
+	Assembly& assembly(CompilerState const& _cs) { finalise(_cs); return m_asm; }
 
 private:
 	void finalise(CompilerState const& _cs);
diff --git a/Compiler.cpp b/Compiler.cpp
index 1621acf9..ebe2638b 100644
--- a/Compiler.cpp
+++ b/Compiler.cpp
@@ -34,9 +34,7 @@ bytes eth::compileLLL(string const& _src, bool _opt, vector<string>* _errors)
 		CompilerState cs;
 		cs.populateStandard();
 		auto f = CodeFragment::compile(_src, cs);
-		if (_opt)
-			f.optimise();
-		bytes ret = f.code(cs);
+		bytes ret = f.assembly(cs).optimise(_opt).assemble();
 		for (auto i: cs.treesToKill)
 			killBigints(i);
 		return ret;
@@ -60,10 +58,7 @@ std::string eth::compileLLLToAsm(std::string const& _src, bool _opt, std::vector
 	{
 		CompilerState cs;
 		cs.populateStandard();
-		auto f = CodeFragment::compile(_src, cs);
-		if (_opt)
-			f.optimise();
-		string ret = f.assembly(cs);
+		string ret = CodeFragment::compile(_src, cs).assembly(cs).optimise(_opt).out();
 		for (auto i: cs.treesToKill)
 			killBigints(i);
 		return ret;
-- 
cgit v1.2.3


From 6f68842208e1025d3769cdea4829407e65b07744 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Sun, 27 Jul 2014 14:06:38 +0200
Subject: Avoid _asm from MSVC.

---
 Assembly.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Assembly.h b/Assembly.h
index 581e1643..888b373c 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -80,7 +80,7 @@ public:
 	AssemblyItem const& append(AssemblyItem const& _i);
 	AssemblyItem const& append(std::string const& _data) { return append(newPushString(_data)); }
 	AssemblyItem const& append(bytes const& _data) { return append(newData(_data)); }
-	AssemblyItem appendSubSize(Assembly const& _asm) { auto ret = newSub(_asm); append(newPushSubSize(ret.data())); return ret; }
+	AssemblyItem appendSubSize(Assembly const& _asmbly) { auto ret = newSub(_asmbly); append(newPushSubSize(ret.data())); return ret; }
 
 	AssemblyItem appendJump() { auto ret = append(newPushTag()); append(Instruction::JUMP); return ret; }
 	AssemblyItem appendJumpI() { auto ret = append(newPushTag()); append(Instruction::JUMPI); return ret; }
-- 
cgit v1.2.3


From 621fbc00f47d962562fb647f4c64de5ddd55af9a Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Mon, 28 Jul 2014 01:58:34 +0200
Subject: Rename assembly again.

---
 Assembly.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Assembly.h b/Assembly.h
index 888b373c..f0f93297 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -80,7 +80,7 @@ public:
 	AssemblyItem const& append(AssemblyItem const& _i);
 	AssemblyItem const& append(std::string const& _data) { return append(newPushString(_data)); }
 	AssemblyItem const& append(bytes const& _data) { return append(newData(_data)); }
-	AssemblyItem appendSubSize(Assembly const& _asmbly) { auto ret = newSub(_asmbly); append(newPushSubSize(ret.data())); return ret; }
+	AssemblyItem appendSubSize(Assembly const& _a) { auto ret = newSub(_a); append(newPushSubSize(ret.data())); return ret; }
 
 	AssemblyItem appendJump() { auto ret = append(newPushTag()); append(Instruction::JUMP); return ret; }
 	AssemblyItem appendJumpI() { auto ret = append(newPushTag()); append(Instruction::JUMPI); return ret; }
-- 
cgit v1.2.3


From b3e207090337126cd48c5c827b6e0fd5c20c6097 Mon Sep 17 00:00:00 2001
From: Giacomo Tazzari <giacomo.tazzari@gmail.com>
Date: Sun, 10 Aug 2014 00:42:34 +0200
Subject: Using boost::spirit::standard namespace instead of
 boost::spirit::ascii in parseTreeLLL() to prevent crashing when parsing code
 containing non-ascii characters

---
 Parser.cpp | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/Parser.cpp b/Parser.cpp
index 1907fd17..edcd38f3 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -85,7 +85,8 @@ struct tagNode
 
 void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
 {
-	using qi::ascii::space;
+	using qi::standard::space;
+	using qi::standard::space_type;
 	using eth::parseTreeLLL_::tagNode;
 	typedef sp::basic_string<std::string, sp::utree_type::symbol_type> symbol_type;
 	typedef string::const_iterator it;
@@ -94,24 +95,24 @@ void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
 	static const u256 finney = u256(1000000000) * 1000000;
 	static const u256 szabo = u256(1000000000) * 1000;
 
-	qi::rule<it, qi::ascii::space_type, sp::utree()> element;
+	qi::rule<it, space_type, sp::utree()> element;
 	qi::rule<it, string()> str = '"' > qi::lexeme[+(~qi::char_(std::string("\"") + '\0'))] > '"';
 	qi::rule<it, string()> strsh = '\'' > qi::lexeme[+(~qi::char_(std::string(" ;$@()[]{}:\n\t") + '\0'))];
 	qi::rule<it, symbol_type()> symbol = qi::lexeme[+(~qi::char_(std::string(" $@[]{}:();\"\x01-\x1f\x7f") + '\0'))];
 	qi::rule<it, string()> intstr = qi::lexeme[ qi::no_case["0x"][qi::_val = "0x"] >> *qi::char_("0-9a-fA-F")[qi::_val += qi::_1]] | qi::lexeme[+qi::char_("0-9")[qi::_val += qi::_1]];
 	qi::rule<it, bigint()> integer = intstr;
 	qi::rule<it, bigint()> multiplier = qi::lit("wei")[qi::_val = 1] | qi::lit("szabo")[qi::_val = szabo] | qi::lit("finney")[qi::_val = finney] | qi::lit("ether")[qi::_val = ether];
-	qi::rule<it, qi::ascii::space_type, bigint()> quantity = integer[qi::_val = qi::_1] >> -multiplier[qi::_val *= qi::_1];
-	qi::rule<it, qi::ascii::space_type, sp::utree()> atom = quantity[qi::_val = px::construct<sp::any_ptr>(px::new_<bigint>(qi::_1))] | (str | strsh)[qi::_val = qi::_1] | symbol[qi::_val = qi::_1];
-	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> seq = '{' > *element > '}';
-	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> mload = '@' > element;
-	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> sload = qi::lit("@@") > element;
-	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> mstore = '[' > element > ']' > -qi::lit(":") > element;
-	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> sstore = qi::lit("[[") > element > qi::lit("]]") > -qi::lit(":") > element;
-	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> calldataload = qi::lit("$") > element;
-	qi::rule<it, qi::ascii::space_type, sp::utree::list_type()> list = '(' > *element > ')';
-
-	qi::rule<it, qi::ascii::space_type, sp::utree()> extra = sload[tagNode<2>()] | mload[tagNode<1>()] | sstore[tagNode<4>()] | mstore[tagNode<3>()] | seq[tagNode<5>()] | calldataload[tagNode<6>()];
+	qi::rule<it, space_type, bigint()> quantity = integer[qi::_val = qi::_1] >> -multiplier[qi::_val *= qi::_1];
+	qi::rule<it, space_type, sp::utree()> atom = quantity[qi::_val = px::construct<sp::any_ptr>(px::new_<bigint>(qi::_1))] | (str | strsh)[qi::_val = qi::_1] | symbol[qi::_val = qi::_1];
+	qi::rule<it, space_type, sp::utree::list_type()> seq = '{' > *element > '}';
+	qi::rule<it, space_type, sp::utree::list_type()> mload = '@' > element;
+	qi::rule<it, space_type, sp::utree::list_type()> sload = qi::lit("@@") > element;
+	qi::rule<it, space_type, sp::utree::list_type()> mstore = '[' > element > ']' > -qi::lit(":") > element;
+	qi::rule<it, space_type, sp::utree::list_type()> sstore = qi::lit("[[") > element > qi::lit("]]") > -qi::lit(":") > element;
+	qi::rule<it, space_type, sp::utree::list_type()> calldataload = qi::lit("$") > element;
+	qi::rule<it, space_type, sp::utree::list_type()> list = '(' > *element > ')';
+
+	qi::rule<it, space_type, sp::utree()> extra = sload[tagNode<2>()] | mload[tagNode<1>()] | sstore[tagNode<4>()] | mstore[tagNode<3>()] | seq[tagNode<5>()] | calldataload[tagNode<6>()];
 	element = atom | list | extra;
 
 	string s;
-- 
cgit v1.2.3


From 17cb91aa35e3048723ac449b48d26038e6956de7 Mon Sep 17 00:00:00 2001
From: Giacomo Tazzari <giacomo.tazzari@gmail.com>
Date: Mon, 11 Aug 2014 11:06:32 +0200
Subject: Fixed implementation of EXP opcode (wrong results when exponent >=
 2^32)

---
 Assembly.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 78552f3c..550f5c89 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -230,7 +230,7 @@ Assembly& Assembly::optimise(bool _enable)
         { Instruction::SDIV, [](u256 a, u256 b)->u256{return s2u(u2s(a) / u2s(b));} },
 		{ Instruction::MOD, [](u256 a, u256 b)->u256{return a % b;} },
         { Instruction::SMOD, [](u256 a, u256 b)->u256{return s2u(u2s(a) % u2s(b));} },
-		{ Instruction::EXP, [](u256 a, u256 b)->u256{return boost::multiprecision::pow(a, (unsigned)b);} },
+		{ Instruction::EXP, [](u256 a, u256 b)->u256{return (u256)boost::multiprecision::powm((bigint)a, (bigint)b, bigint(2) << 256);} },
 		{ Instruction::LT, [](u256 a, u256 b)->u256{return a < b ? 1 : 0;} },
 		{ Instruction::GT, [](u256 a, u256 b)->u256{return a > b ? 1 : 0;} },
         { Instruction::SLT, [](u256 a, u256 b)->u256{return u2s(a) < u2s(b) ? 1 : 0;} },
-- 
cgit v1.2.3


From 905df780a32370725ea5e28f97724a496d816d0a Mon Sep 17 00:00:00 2001
From: Giacomo Tazzari <giacomo.tazzari@gmail.com>
Date: Mon, 11 Aug 2014 11:20:11 +0200
Subject: Code indentation fix

---
 Assembly.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 550f5c89..491d3812 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -227,14 +227,14 @@ Assembly& Assembly::optimise(bool _enable)
 	{
 		{ Instruction::SUB, [](u256 a, u256 b)->u256{return a - b;} },
 		{ Instruction::DIV, [](u256 a, u256 b)->u256{return a / b;} },
-        { Instruction::SDIV, [](u256 a, u256 b)->u256{return s2u(u2s(a) / u2s(b));} },
+		{ Instruction::SDIV, [](u256 a, u256 b)->u256{return s2u(u2s(a) / u2s(b));} },
 		{ Instruction::MOD, [](u256 a, u256 b)->u256{return a % b;} },
-        { Instruction::SMOD, [](u256 a, u256 b)->u256{return s2u(u2s(a) % u2s(b));} },
+		{ Instruction::SMOD, [](u256 a, u256 b)->u256{return s2u(u2s(a) % u2s(b));} },
 		{ Instruction::EXP, [](u256 a, u256 b)->u256{return (u256)boost::multiprecision::powm((bigint)a, (bigint)b, bigint(2) << 256);} },
 		{ Instruction::LT, [](u256 a, u256 b)->u256{return a < b ? 1 : 0;} },
 		{ Instruction::GT, [](u256 a, u256 b)->u256{return a > b ? 1 : 0;} },
-        { Instruction::SLT, [](u256 a, u256 b)->u256{return u2s(a) < u2s(b) ? 1 : 0;} },
-        { Instruction::SGT, [](u256 a, u256 b)->u256{return u2s(a) > u2s(b) ? 1 : 0;} },
+		{ Instruction::SLT, [](u256 a, u256 b)->u256{return u2s(a) < u2s(b) ? 1 : 0;} },
+		{ Instruction::SGT, [](u256 a, u256 b)->u256{return u2s(a) > u2s(b) ? 1 : 0;} },
 		{ Instruction::EQ, [](u256 a, u256 b)->u256{return a == b ? 1 : 0;} },
 	};
 	map<Instruction, function<u256(u256, u256)>> c_associative =
-- 
cgit v1.2.3


From e4e46b07ebcf05bebbb3b1711b843f65268d99bc Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Thu, 14 Aug 2014 13:26:28 +0200
Subject: Fix for padding in new SHA3.

---
 CompilerState.cpp | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/CompilerState.cpp b/CompilerState.cpp
index 01995674..22277501 100644
--- a/CompilerState.cpp
+++ b/CompilerState.cpp
@@ -46,12 +46,7 @@ void CompilerState::populateStandard()
 	static const string s = "{"
 	"(def 'gav 0x51ba59315b3a95761d0863b05ccc7a7f54703d99)"
 	"(def 'config 0x661005d2720d855f1d9976f88bb10c1a3398c77f)"
-	"(def 'namereg 0x50441127ea5b9dfd835a9aba4e1dc9c1257b58ca)"
-	"(def 'gavcoin 0x5620133321fcac7f15a5c570016f6cb6dc263f9d)"
 	"(def 'allgas (- (gas) 21))"
-	"(def 'sendgavcoin (to value) { [0]'send [32]:to [64]:value (call allgas gavcoin 0 0 96 0 0) })"
-	"(def 'regname (name) { [0]'register [32]name (call allgas namereg 0 0 64 0 0) })"
-	"(def 'regcoins (name) { [0]'register [32]name (call allgas namereg 0 0 64 0 0) })"
 	"(def 'send (to value) (call allgas to value 0 0 0 0))"
 	"(def 'send (gaslimit to value) (call gaslimit to value 0 0 0 0))"
 	"(def 'msg (gaslimit to value data datasize outsize) { (set x outsize) (set y (alloc @32)) (call gaslimit to value data datasize @0 @32) @0 })"
@@ -69,6 +64,13 @@ void CompilerState::populateStandard()
 	"(def 'makeperm (name pos) { (def name (sload pos)) (def name (v) (sstore pos v)) } )"
 	"(def 'permcount 0)"
 	"(def 'perm (name) { (makeperm name permcount) (def 'permcount (+ permcount 1)) } )"
+	"(def 'namereg (msg config 0))"
+	"(def 'coinreg (msg config 1))"
+	"(def 'gavcoin (msg config 2))"
+	"(def 'sendgavcoin (to value) { [32]'send [64]:to [96]:value (call allgas gavcoin 0 32 96 0 0) })"
+	"(def 'regname (name) { [32]'register [64]name (call allgas namereg 0 32 64 0 0) })"
+	"(def 'regcoin (name) { [32]name (call allgas coinreg 0 32 32 0 0) })"
+	"(def 'regcoin (name denom) { [32]name [64]denom (call allgas coinreg 0 32 64 0 0) })"
 	"}";
 	CodeFragment::compile(s, *this);
 }
-- 
cgit v1.2.3


From 5cdacb1bc1728ef0411f6d6cdb4172bc26dc5fa7 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Thu, 21 Aug 2014 15:53:59 +0200
Subject: Unambiguous licence.

---
 CodeFragment.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index bc7fa615..09f49bc7 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -313,7 +313,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 				++ii;
 			}
 			m_asm.append((u256)data.size());
-			m_asm.append(Instruction::DUP);
+			m_asm.append(Instruction::DUP1);
 			m_asm.append(data);
 			m_asm.append(pos.m_asm, 1);
 			m_asm.append(Instruction::CODECOPY);
@@ -494,7 +494,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 			requireDeposit(1, 1);
 
 			auto subPush = m_asm.appendSubSize(code[0].assembly(ns));
-			m_asm.append(Instruction::DUP);
+			m_asm.append(Instruction::DUP1);
 			if (code.size() == 3)
 			{
 				requireDeposit(2, 1);
@@ -502,7 +502,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 				m_asm.append(Instruction::LT);
 				m_asm.append(Instruction::NOT);
 				m_asm.append(Instruction::MUL);
-				m_asm.append(Instruction::DUP);
+				m_asm.append(Instruction::DUP1);
 			}
 			m_asm.append(subPush);
 			m_asm.append(code[1].m_asm, 1);
-- 
cgit v1.2.3


From 74f198c0438a2674103c8e1ce24a0feedef278dc Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Thu, 21 Aug 2014 16:14:12 +0200
Subject: SWAP & DUP

---
 CodeFragment.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index 09f49bc7..a9128e29 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -77,7 +77,7 @@ CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowAS
 		string us = boost::algorithm::to_upper_copy(s);
 		if (_allowASM && c_instructions.count(us))
 			m_asm.append(c_instructions.at(us));
-		if (_s.defs.count(s))
+		else if (_s.defs.count(s))
 			m_asm.append(_s.defs.at(s).m_asm);
 		else if (_s.args.count(s))
 			m_asm.append(_s.args.at(s).m_asm);
-- 
cgit v1.2.3


From 00caaf53d28976ed276d9d2fe7a54c07ba92b002 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Tue, 26 Aug 2014 22:27:45 +0200
Subject: Better interface for instrInfo.

---
 Assembly.cpp     | 6 +++---
 CodeFragment.cpp | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 491d3812..f397ec37 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -31,7 +31,7 @@ int AssemblyItem::deposit() const
 	switch (m_type)
 	{
 	case Operation:
-		return c_instructionInfo.at((Instruction)(byte)m_data).ret - c_instructionInfo.at((Instruction)(byte)m_data).args;
+		return instructionInfo((Instruction)(byte)m_data).ret - instructionInfo((Instruction)(byte)m_data).args;
 	case Push: case PushString: case PushTag: case PushData: case PushSub: case PushSubSize:
 		return 1;
 	case Tag:
@@ -116,7 +116,7 @@ ostream& eth::operator<<(ostream& _out, AssemblyItemsConstRef _i)
 		switch (i.type())
 		{
 		case Operation:
-			_out << " " << c_instructionInfo.at((Instruction)(byte)i.data()).name;
+			_out << " " << instructionInfo((Instruction)(byte)i.data()).name;
 			break;
 		case Push:
 			_out << " PUSH" << i.data();
@@ -153,7 +153,7 @@ ostream& Assembly::streamOut(ostream& _out, string const& _prefix) const
 		switch (i.m_type)
 		{
 		case Operation:
-			_out << _prefix << "  " << c_instructionInfo.at((Instruction)(byte)i.m_data).name << endl;
+			_out << _prefix << "  " << instructionInfo((Instruction)(byte)i.m_data).name << endl;
 			break;
 		case Push:
 			_out << _prefix << "  PUSH " << i.m_data << endl;
diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index a9128e29..07d17fbe 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -369,7 +369,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 		else if (c_instructions.count(us))
 		{
 			auto it = c_instructions.find(us);
-			int ea = c_instructionInfo.at(it->second).args;
+			int ea = instructionInfo(it->second).args;
 			if (ea >= 0)
 				requireSize(ea);
 			else
-- 
cgit v1.2.3


From 6ff57fe0759d13a97346cf5590f57ad729cbbae7 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Fri, 5 Sep 2014 17:09:58 +0200
Subject: Project-wide reorganisation of namespaces.

---
 Assembly.cpp      | 17 +++++++++--------
 Assembly.h        |  3 +++
 CodeFragment.cpp  |  3 ++-
 CodeFragment.h    |  3 +++
 Compiler.cpp      |  9 +++++----
 Compiler.h        |  4 +++-
 CompilerState.cpp |  3 ++-
 CompilerState.h   |  3 +++
 Exceptions.h      |  7 ++++++-
 Parser.cpp        | 15 ++++++++-------
 Parser.h          |  4 +++-
 11 files changed, 47 insertions(+), 24 deletions(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index f397ec37..475eaeab 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -24,7 +24,8 @@
 #include <libethential/Log.h>
 
 using namespace std;
-using namespace eth;
+using namespace dev;
+using namespace dev::eth;
 
 int AssemblyItem::deposit() const
 {
@@ -59,7 +60,7 @@ unsigned Assembly::bytesRequired() const
 				ret += 33;
 				break;
 			case Push:
-				ret += 1 + max<unsigned>(1, eth::bytesRequired(i.m_data));
+				ret += 1 + max<unsigned>(1, dev::bytesRequired(i.m_data));
 				break;
 			case PushSubSize:
 				ret += 4;		// worst case: a 16MB program
@@ -71,7 +72,7 @@ unsigned Assembly::bytesRequired() const
 			case Tag:;
 			default:;
 			}
-		if (eth::bytesRequired(ret) <= br)
+		if (dev::bytesRequired(ret) <= br)
 			return ret;
 	}
 }
@@ -110,7 +111,7 @@ void Assembly::append(Assembly const& _a, int _deposit)
 	}
 }
 
-ostream& eth::operator<<(ostream& _out, AssemblyItemsConstRef _i)
+ostream& dev::eth::operator<<(ostream& _out, AssemblyItemsConstRef _i)
 {
 	for (AssemblyItem const& i: _i)
 		switch (i.type())
@@ -217,7 +218,7 @@ inline bool matches(AssemblyItemsConstRef _a, AssemblyItemsConstRef _b)
 }
 
 struct OptimiserChannel: public LogChannel { static const char* name() { return "OPT"; } static const int verbosity = 12; };
-#define copt eth::LogOutputStream<OptimiserChannel, true>()
+#define copt dev::LogOutputStream<OptimiserChannel, true>()
 
 Assembly& Assembly::optimise(bool _enable)
 {
@@ -353,7 +354,7 @@ bytes Assembly::assemble() const
 	vector<unsigned> tagPos(m_usedTags);
 	map<unsigned, unsigned> tagRef;
 	multimap<h256, unsigned> dataRef;
-	unsigned bytesPerTag = eth::bytesRequired(totalBytes);
+	unsigned bytesPerTag = dev::bytesRequired(totalBytes);
 	byte tagPush = (byte)Instruction::PUSH1 - 1 + bytesPerTag;
 
 	for (auto const& i: m_subs)
@@ -380,7 +381,7 @@ bytes Assembly::assemble() const
 		}
 		case Push:
 		{
-			byte b = max<unsigned>(1, eth::bytesRequired(i.m_data));
+			byte b = max<unsigned>(1, dev::bytesRequired(i.m_data));
 			ret.push_back((byte)Instruction::PUSH1 - 1 + b);
 			ret.resize(ret.size() + b);
 			bytesRef byr(&ret.back() + 1 - b, b);
@@ -404,7 +405,7 @@ bytes Assembly::assemble() const
 		case PushSubSize:
 		{
 			auto s = m_data[i.m_data].size();
-			byte b = max<unsigned>(1, eth::bytesRequired(s));
+			byte b = max<unsigned>(1, dev::bytesRequired(s));
 			ret.push_back((byte)Instruction::PUSH1 - 1 + b);
 			ret.resize(ret.size() + b);
 			bytesRef byr(&ret.back() + 1 - b, b);
diff --git a/Assembly.h b/Assembly.h
index f0f93297..cfeb6d1f 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -27,6 +27,8 @@
 #include <libevmface/Instruction.h>
 #include "Exceptions.h"
 
+namespace dev
+{
 namespace eth
 {
 
@@ -130,3 +132,4 @@ inline std::ostream& operator<<(std::ostream& _out, Assembly const& _a)
 }
 
 }
+}
diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index 07d17fbe..ecad3d36 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -28,7 +28,8 @@
 #include "CompilerState.h"
 #include "Parser.h"
 using namespace std;
-using namespace eth;
+using namespace dev;
+using namespace dev::eth;
 namespace qi = boost::spirit::qi;
 namespace px = boost::phoenix;
 namespace sp = boost::spirit;
diff --git a/CodeFragment.h b/CodeFragment.h
index 98a6f15c..a81d8ea2 100644
--- a/CodeFragment.h
+++ b/CodeFragment.h
@@ -29,6 +29,8 @@
 namespace boost { namespace spirit { class utree; } }
 namespace sp = boost::spirit;
 
+namespace dev
+{
 namespace eth
 {
 
@@ -58,3 +60,4 @@ private:
 static const CodeFragment NullCodeFragment;
 
 }
+}
diff --git a/Compiler.cpp b/Compiler.cpp
index ebe2638b..389c10be 100644
--- a/Compiler.cpp
+++ b/Compiler.cpp
@@ -25,9 +25,10 @@
 #include "CodeFragment.h"
 
 using namespace std;
-using namespace eth;
+using namespace dev;
+using namespace dev::eth;
 
-bytes eth::compileLLL(string const& _src, bool _opt, vector<string>* _errors)
+bytes dev::eth::compileLLL(string const& _src, bool _opt, vector<string>* _errors)
 {
 	try
 	{
@@ -52,7 +53,7 @@ bytes eth::compileLLL(string const& _src, bool _opt, vector<string>* _errors)
 	return bytes();
 }
 
-std::string eth::compileLLLToAsm(std::string const& _src, bool _opt, std::vector<std::string>* _errors)
+std::string dev::eth::compileLLLToAsm(std::string const& _src, bool _opt, std::vector<std::string>* _errors)
 {
 	try
 	{
@@ -76,7 +77,7 @@ std::string eth::compileLLLToAsm(std::string const& _src, bool _opt, std::vector
 	return string();
 }
 
-string eth::parseLLL(string const& _src)
+string dev::eth::parseLLL(string const& _src)
 {
 	sp::utree o;
 	try
diff --git a/Compiler.h b/Compiler.h
index da84a2fe..5daec0a5 100644
--- a/Compiler.h
+++ b/Compiler.h
@@ -25,6 +25,8 @@
 #include <vector>
 #include <libethential/Common.h>
 
+namespace dev
+{
 namespace eth
 {
 
@@ -33,4 +35,4 @@ std::string compileLLLToAsm(std::string const& _src, bool _opt = true, std::vect
 bytes compileLLL(std::string const& _src, bool _opt = true, std::vector<std::string>* _errors = nullptr);
 
 }
-
+}
diff --git a/CompilerState.cpp b/CompilerState.cpp
index 22277501..c3dc2dda 100644
--- a/CompilerState.cpp
+++ b/CompilerState.cpp
@@ -23,7 +23,8 @@
 #include "CodeFragment.h"
 
 using namespace std;
-using namespace eth;
+using namespace dev;
+using namespace dev::eth;
 
 CompilerState::CompilerState()
 {
diff --git a/CompilerState.h b/CompilerState.h
index a0b3bf46..bfe56f92 100644
--- a/CompilerState.h
+++ b/CompilerState.h
@@ -24,6 +24,8 @@
 #include <boost/spirit/include/support_utree.hpp>
 #include "CodeFragment.h"
 
+namespace dev
+{
 namespace eth
 {
 
@@ -52,3 +54,4 @@ struct CompilerState
 };
 
 }
+}
diff --git a/Exceptions.h b/Exceptions.h
index a1aee173..1dcbbcc6 100644
--- a/Exceptions.h
+++ b/Exceptions.h
@@ -21,11 +21,15 @@
 
 #pragma once
 
+#include <libethential/Exceptions.h>
+
+namespace dev
+{
 namespace eth
 {
 
 /// Compile a Low-level Lisp-like Language program into EVM-code.
-class CompilerException: public Exception {};
+class CompilerException: public dev::Exception {};
 class InvalidOperation: public CompilerException {};
 class IntegerOutOfRange: public CompilerException {};
 class StringTooLong: public CompilerException {};
@@ -40,3 +44,4 @@ class BareSymbol: public CompilerException {};
 class ExpectedLiteral: public CompilerException {};
 
 }
+}
diff --git a/Parser.cpp b/Parser.cpp
index edcd38f3..52a05174 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -28,12 +28,13 @@
 #include <boost/spirit/include/support_utree.hpp>
 
 using namespace std;
-using namespace eth;
+using namespace dev;
+using namespace dev::eth;
 namespace qi = boost::spirit::qi;
 namespace px = boost::phoenix;
 namespace sp = boost::spirit;
 
-void eth::killBigints(sp::utree const& _this)
+void dev::eth::killBigints(sp::utree const& _this)
 {
 	switch (_this.which())
 	{
@@ -43,7 +44,7 @@ void eth::killBigints(sp::utree const& _this)
 	}
 }
 
-void eth::debugOutAST(ostream& _out, sp::utree const& _this)
+void dev::eth::debugOutAST(ostream& _out, sp::utree const& _this)
 {
 	switch (_this.which())
 	{
@@ -69,7 +70,7 @@ void eth::debugOutAST(ostream& _out, sp::utree const& _this)
 	}
 }
 
-namespace eth {
+namespace dev { namespace eth {
 namespace parseTreeLLL_ {
 
 template<unsigned N>
@@ -81,13 +82,13 @@ struct tagNode
 	}
 };
 
-}}
+}}}
 
-void eth::parseTreeLLL(string const& _s, sp::utree& o_out)
+void dev::eth::parseTreeLLL(string const& _s, sp::utree& o_out)
 {
 	using qi::standard::space;
 	using qi::standard::space_type;
-	using eth::parseTreeLLL_::tagNode;
+	using dev::eth::parseTreeLLL_::tagNode;
 	typedef sp::basic_string<std::string, sp::utree_type::symbol_type> symbol_type;
 	typedef string::const_iterator it;
 
diff --git a/Parser.h b/Parser.h
index 5286c3e8..f90c6b5d 100644
--- a/Parser.h
+++ b/Parser.h
@@ -28,6 +28,8 @@
 namespace boost { namespace spirit { class utree; } }
 namespace sp = boost::spirit;
 
+namespace dev
+{
 namespace eth
 {
 
@@ -36,4 +38,4 @@ void parseTreeLLL(std::string const& _s, sp::utree& o_out);
 void debugOutAST(std::ostream& _out, sp::utree const& _this);
 
 }
-
+}
-- 
cgit v1.2.3


From 55d0e1c34ef3c14b2c262fe7edd4fdc2f18bcfb5 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Fri, 5 Sep 2014 18:24:29 +0200
Subject: Split ethcore off into devcrypto ready for Whisper's crypto and repot
 namespace. Rename ethential to devcore.

---
 Assembly.cpp     | 2 +-
 Assembly.h       | 2 +-
 CMakeLists.txt   | 2 +-
 CodeFragment.cpp | 2 +-
 CodeFragment.h   | 2 +-
 Compiler.h       | 2 +-
 Exceptions.h     | 2 +-
 Parser.h         | 2 +-
 8 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 475eaeab..2250a71f 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -21,7 +21,7 @@
 
 #include "Assembly.h"
 
-#include <libethential/Log.h>
+#include <libdevcore/Log.h>
 
 using namespace std;
 using namespace dev;
diff --git a/Assembly.h b/Assembly.h
index cfeb6d1f..b8152fe0 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -23,7 +23,7 @@
 
 #include <iostream>
 #include <sstream>
-#include <libethential/Common.h>
+#include <libdevcore/Common.h>
 #include <libevmface/Instruction.h>
 #include "Exceptions.h"
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 98bebdfe..7746613e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,7 +18,7 @@ file(GLOB HEADERS "*.h")
 include_directories(..)
 
 target_link_libraries(${EXECUTABLE} evmface)
-target_link_libraries(${EXECUTABLE} ethential)
+target_link_libraries(${EXECUTABLE} devcore)
 
 
 if("${TARGET_PLATFORM}" STREQUAL "w64")
diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index ecad3d36..533d00a9 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -23,7 +23,7 @@
 
 #include <boost/algorithm/string.hpp>
 #include <boost/spirit/include/support_utree.hpp>
-#include <libethential/Log.h>
+#include <libdevcore/Log.h>
 #include <libevmface/Instruction.h>
 #include "CompilerState.h"
 #include "Parser.h"
diff --git a/CodeFragment.h b/CodeFragment.h
index a81d8ea2..60ab7c6d 100644
--- a/CodeFragment.h
+++ b/CodeFragment.h
@@ -21,7 +21,7 @@
 
 #pragma once
 
-#include <libethential/Common.h>
+#include <libdevcore/Common.h>
 #include <libevmface/Instruction.h>
 #include "Assembly.h"
 #include "Exceptions.h"
diff --git a/Compiler.h b/Compiler.h
index 5daec0a5..0fadd278 100644
--- a/Compiler.h
+++ b/Compiler.h
@@ -23,7 +23,7 @@
 
 #include <string>
 #include <vector>
-#include <libethential/Common.h>
+#include <libdevcore/Common.h>
 
 namespace dev
 {
diff --git a/Exceptions.h b/Exceptions.h
index 1dcbbcc6..c45215f1 100644
--- a/Exceptions.h
+++ b/Exceptions.h
@@ -21,7 +21,7 @@
 
 #pragma once
 
-#include <libethential/Exceptions.h>
+#include <libdevcore/Exceptions.h>
 
 namespace dev
 {
diff --git a/Parser.h b/Parser.h
index f90c6b5d..b21989f0 100644
--- a/Parser.h
+++ b/Parser.h
@@ -23,7 +23,7 @@
 
 #include <string>
 #include <vector>
-#include <libethential/Common.h>
+#include <libdevcore/Common.h>
 
 namespace boost { namespace spirit { class utree; } }
 namespace sp = boost::spirit;
-- 
cgit v1.2.3


From f61c3232449d36cc44bcff70240f5292bf8f9f16 Mon Sep 17 00:00:00 2001
From: Christoph Jentzsch <jentzsch.software@gmail.com>
Date: Thu, 2 Oct 2014 14:20:33 +0200
Subject: Restructured exceptions. Boost::exception is now used primarily.

---
 Assembly.cpp   | 2 +-
 Assembly.h     | 2 +-
 CodeFragment.h | 2 +-
 Compiler.cpp   | 7 +++++--
 Parser.cpp     | 2 +-
 5 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 2250a71f..9b6dee94 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -102,7 +102,7 @@ void Assembly::append(Assembly const& _a)
 void Assembly::append(Assembly const& _a, int _deposit)
 {
 	if (_deposit > _a.m_deposit)
-		throw InvalidDeposit();
+		BOOST_THROW_EXCEPTION(InvalidDeposit());
 	else
 	{
 		append(_a);
diff --git a/Assembly.h b/Assembly.h
index b8152fe0..b7feaf4f 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -111,7 +111,7 @@ public:
 	std::ostream& streamOut(std::ostream& _out, std::string const& _prefix = "") const;
 
 private:
-	void donePath() { if (m_totalDeposit != INT_MAX && m_totalDeposit != m_deposit) throw InvalidDeposit(); }
+	void donePath() { if (m_totalDeposit != INT_MAX && m_totalDeposit != m_deposit) BOOST_THROW_EXCEPTION(InvalidDeposit()); }
 	unsigned bytesRequired() const;
 
 	unsigned m_usedTags = 0;
diff --git a/CodeFragment.h b/CodeFragment.h
index 60ab7c6d..d6ca86bb 100644
--- a/CodeFragment.h
+++ b/CodeFragment.h
@@ -50,7 +50,7 @@ public:
 private:
 	void finalise(CompilerState const& _cs);
 
-	template <class T> void error() const { throw T(); }
+	template <class T> void error() const { BOOST_THROW_EXCEPTION(T() ); }
 	void constructOperation(sp::utree const& _t, CompilerState& _s);
 
 	bool m_finalised = false;
diff --git a/Compiler.cpp b/Compiler.cpp
index 389c10be..37fb3c34 100644
--- a/Compiler.cpp
+++ b/Compiler.cpp
@@ -43,7 +43,10 @@ bytes dev::eth::compileLLL(string const& _src, bool _opt, vector<string>* _error
 	catch (Exception const& _e)
 	{
 		if (_errors)
-			_errors->push_back(_e.description());
+		{
+			_errors->push_back("Parse error.");
+			_errors->push_back(diagnostic_information(_e));
+		}
 	}
 	catch (std::exception)
 	{
@@ -67,7 +70,7 @@ std::string dev::eth::compileLLLToAsm(std::string const& _src, bool _opt, std::v
 	catch (Exception const& _e)
 	{
 		if (_errors)
-			_errors->push_back(_e.description());
+			_errors->push_back(diagnostic_information(_e));
 	}
 	catch (std::exception)
 	{
diff --git a/Parser.cpp b/Parser.cpp
index 52a05174..e94e88e1 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -140,6 +140,6 @@ void dev::eth::parseTreeLLL(string const& _s, sp::utree& o_out)
 	qi::phrase_parse(ret, s.cend(), element, space, qi::skip_flag::dont_postskip, o_out);
 	for (auto i = ret; i != s.cend(); ++i)
 		if (!isspace(*i))
-			throw std::exception();
+			BOOST_THROW_EXCEPTION(std::exception());
 }
 
-- 
cgit v1.2.3


From 92d9a107d711040cc34921aa6bd5f5abcf515b8c Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Tue, 7 Oct 2014 18:43:01 +0200
Subject: PoC-7: JUMPDEST implemented.

---
 Assembly.cpp | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 9b6dee94..11ee9122 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -149,6 +149,17 @@ ostream& dev::eth::operator<<(ostream& _out, AssemblyItemsConstRef _i)
 
 ostream& Assembly::streamOut(ostream& _out, string const& _prefix) const
 {
+	_out << _prefix << ".pre:" << endl;
+	for (AssemblyItem const& i: m_items)
+		switch (i.m_type)
+		{
+		case PushTag:
+			_out << _prefix << "  PUSH [tag" << i.m_data << "]" << endl;
+			_out << _prefix << "  JUMPDEST" << endl;
+			break;
+		default:;
+		}
+
 	_out << _prefix << ".code:" << endl;
 	for (AssemblyItem const& i: m_items)
 		switch (i.m_type)
@@ -353,9 +364,11 @@ bytes Assembly::assemble() const
 	ret.reserve(totalBytes);
 	vector<unsigned> tagPos(m_usedTags);
 	map<unsigned, unsigned> tagRef;
+	map<unsigned, unsigned> pretagRef;
 	multimap<h256, unsigned> dataRef;
 	unsigned bytesPerTag = dev::bytesRequired(totalBytes);
 	byte tagPush = (byte)Instruction::PUSH1 - 1 + bytesPerTag;
+	bytes preret;
 
 	for (auto const& i: m_subs)
 		m_data[i.first] = i.second.assemble();
@@ -393,6 +406,11 @@ bytes Assembly::assemble() const
 			ret.push_back(tagPush);
 			tagRef[ret.size()] = (unsigned)i.m_data;
 			ret.resize(ret.size() + bytesPerTag);
+
+			preret.push_back(tagPush);
+			pretagRef[preret.size()] = (unsigned)i.m_data;
+			preret.resize(preret.size() + bytesPerTag);
+			preret.push_back((byte)Instruction::JUMPDEST);
 			break;
 		}
 		case PushData: case PushSub:
@@ -424,6 +442,12 @@ bytes Assembly::assemble() const
 		toBigEndian(tagPos[i.second], r);
 	}
 
+	for (auto const& i: pretagRef)
+	{
+		bytesRef r(preret.data() + i.first, bytesPerTag);
+		toBigEndian(tagPos[i.second], r);
+	}
+
 	if (m_data.size())
 	{
 		ret.push_back(0);
@@ -442,5 +466,5 @@ bytes Assembly::assemble() const
 			}
 		}
 	}
-	return ret;
+	return preret + ret;
 }
-- 
cgit v1.2.3


From 8c1c9ac6646a93837c5fcd9c446097ae797c25da Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Tue, 7 Oct 2014 23:07:56 +0200
Subject: More attempts to fix for the ultra-pedantic clang compiler.

---
 CodeFragment.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index 533d00a9..56b5d440 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -24,6 +24,7 @@
 #include <boost/algorithm/string.hpp>
 #include <boost/spirit/include/support_utree.hpp>
 #include <libdevcore/Log.h>
+#include <libdevcore/CommonIO.h>
 #include <libevmface/Instruction.h>
 #include "CompilerState.h"
 #include "Parser.h"
-- 
cgit v1.2.3


From b4865f961bfa946c38545403e515d8825ebb0399 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Wed, 8 Oct 2014 14:43:32 +0200
Subject: PoC-7 JUMPDEST done the intended way. Windows pedantic build fix.

---
 Assembly.cpp | 31 ++++---------------------------
 1 file changed, 4 insertions(+), 27 deletions(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 11ee9122..695c9ffa 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -129,7 +129,7 @@ ostream& dev::eth::operator<<(ostream& _out, AssemblyItemsConstRef _i)
 			_out << " PUSH[tag" << i.data() << "]";
 			break;
 		case Tag:
-			_out << " tag" << i.data() << ":";
+			_out << " tag" << i.data() << ": JUMPDEST";
 			break;
 		case PushData:
 			_out << " PUSH*[" << hex << (unsigned)i.data() << "]";
@@ -149,17 +149,6 @@ ostream& dev::eth::operator<<(ostream& _out, AssemblyItemsConstRef _i)
 
 ostream& Assembly::streamOut(ostream& _out, string const& _prefix) const
 {
-	_out << _prefix << ".pre:" << endl;
-	for (AssemblyItem const& i: m_items)
-		switch (i.m_type)
-		{
-		case PushTag:
-			_out << _prefix << "  PUSH [tag" << i.m_data << "]" << endl;
-			_out << _prefix << "  JUMPDEST" << endl;
-			break;
-		default:;
-		}
-
 	_out << _prefix << ".code:" << endl;
 	for (AssemblyItem const& i: m_items)
 		switch (i.m_type)
@@ -183,7 +172,7 @@ ostream& Assembly::streamOut(ostream& _out, string const& _prefix) const
 			_out << _prefix << "  PUSH #[$" << h256(i.m_data).abridged() << "]" << endl;
 			break;
 		case Tag:
-			_out << _prefix << "tag" << i.m_data << ": " << endl;
+			_out << _prefix << "tag" << i.m_data << ": " << endl << _prefix << "  JUMPDEST" << endl;
 			break;
 		case PushData:
 			_out << _prefix << "  PUSH [" << hex << (unsigned)i.m_data << "]" << endl;
@@ -364,11 +353,9 @@ bytes Assembly::assemble() const
 	ret.reserve(totalBytes);
 	vector<unsigned> tagPos(m_usedTags);
 	map<unsigned, unsigned> tagRef;
-	map<unsigned, unsigned> pretagRef;
 	multimap<h256, unsigned> dataRef;
 	unsigned bytesPerTag = dev::bytesRequired(totalBytes);
 	byte tagPush = (byte)Instruction::PUSH1 - 1 + bytesPerTag;
-	bytes preret;
 
 	for (auto const& i: m_subs)
 		m_data[i.first] = i.second.assemble();
@@ -406,11 +393,6 @@ bytes Assembly::assemble() const
 			ret.push_back(tagPush);
 			tagRef[ret.size()] = (unsigned)i.m_data;
 			ret.resize(ret.size() + bytesPerTag);
-
-			preret.push_back(tagPush);
-			pretagRef[preret.size()] = (unsigned)i.m_data;
-			preret.resize(preret.size() + bytesPerTag);
-			preret.push_back((byte)Instruction::JUMPDEST);
 			break;
 		}
 		case PushData: case PushSub:
@@ -432,6 +414,7 @@ bytes Assembly::assemble() const
 		}
 		case Tag:
 			tagPos[(unsigned)i.m_data] = ret.size();
+			ret.push_back((byte)Instruction::JUMPDEST);
 			break;
 		default:;
 		}
@@ -442,12 +425,6 @@ bytes Assembly::assemble() const
 		toBigEndian(tagPos[i.second], r);
 	}
 
-	for (auto const& i: pretagRef)
-	{
-		bytesRef r(preret.data() + i.first, bytesPerTag);
-		toBigEndian(tagPos[i.second], r);
-	}
-
 	if (m_data.size())
 	{
 		ret.push_back(0);
@@ -466,5 +443,5 @@ bytes Assembly::assemble() const
 			}
 		}
 	}
-	return preret + ret;
+	return ret;
 }
-- 
cgit v1.2.3


From db9b99602e72cccdcb346fb80612a9275ec0a8f8 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Wed, 8 Oct 2014 16:40:46 +0200
Subject: According commit for JUMPDEST.

---
 Assembly.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 695c9ffa..c26a9a98 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -413,8 +413,8 @@ bytes Assembly::assemble() const
 			break;
 		}
 		case Tag:
-			tagPos[(unsigned)i.m_data] = ret.size();
 			ret.push_back((byte)Instruction::JUMPDEST);
+			tagPos[(unsigned)i.m_data] = ret.size();
 			break;
 		default:;
 		}
-- 
cgit v1.2.3


From 9c691e917fcfd291fcaa3c6aaff8c8242fc50873 Mon Sep 17 00:00:00 2001
From: subtly <subtly@users.noreply.github.com>
Date: Thu, 16 Oct 2014 15:10:54 +0200
Subject: add headers to cmake

---
 CMakeLists.txt | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7746613e..cb50cc36 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,15 +6,13 @@ aux_source_directory(. SRC_LIST)
 
 set(EXECUTABLE lll)
 
-# set(CMAKE_INSTALL_PREFIX ../lib)
+file(GLOB HEADERS "*.h")
 if(ETH_STATIC)
-	add_library(${EXECUTABLE} STATIC ${SRC_LIST})
+	add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS})
 else()
-	add_library(${EXECUTABLE} SHARED ${SRC_LIST})
+	add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS})
 endif()
 
-file(GLOB HEADERS "*.h") 
-
 include_directories(..)
 
 target_link_libraries(${EXECUTABLE} evmface)
-- 
cgit v1.2.3


From bded2ff3726c5626ea59b2bcbdf5fcded25457c7 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Mon, 27 Oct 2014 20:26:34 +0100
Subject: Draft of new LOG/bloom/headers/block format.

---
 Assembly.cpp | 4 ++--
 Assembly.h   | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index c26a9a98..5b10138d 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -147,7 +147,7 @@ ostream& dev::eth::operator<<(ostream& _out, AssemblyItemsConstRef _i)
 	return _out;
 }
 
-ostream& Assembly::streamOut(ostream& _out, string const& _prefix) const
+ostream& Assembly::streamRLP(ostream& _out, string const& _prefix) const
 {
 	_out << _prefix << ".code:" << endl;
 	for (AssemblyItem const& i: m_items)
@@ -189,7 +189,7 @@ ostream& Assembly::streamOut(ostream& _out, string const& _prefix) const
 		for (auto const& i: m_subs)
 		{
 			_out << _prefix << "  " << hex << (unsigned)(u256)i.first << ": " << endl;
-			i.second.streamOut(_out, _prefix + "  ");
+			i.second.streamRLP(_out, _prefix + "  ");
 		}
 	}
 	return _out;
diff --git a/Assembly.h b/Assembly.h
index b7feaf4f..8ab3062d 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -104,11 +104,11 @@ public:
 
 	void injectStart(AssemblyItem const& _i);
 
-	std::string out() const { std::stringstream ret; streamOut(ret); return ret.str(); }
+	std::string out() const { std::stringstream ret; streamRLP(ret); return ret.str(); }
 	int deposit() const { return m_deposit; }
 	bytes assemble() const;
 	Assembly& optimise(bool _enable);
-	std::ostream& streamOut(std::ostream& _out, std::string const& _prefix = "") const;
+	std::ostream& streamRLP(std::ostream& _out, std::string const& _prefix = "") const;
 
 private:
 	void donePath() { if (m_totalDeposit != INT_MAX && m_totalDeposit != m_deposit) BOOST_THROW_EXCEPTION(InvalidDeposit()); }
@@ -127,7 +127,7 @@ private:
 
 inline std::ostream& operator<<(std::ostream& _out, Assembly const& _a)
 {
-	_a.streamOut(_out);
+	_a.streamRLP(_out);
 	return _out;
 }
 
-- 
cgit v1.2.3


From f6e24989ec929eb7d22486544a0053c4e5bb2e6c Mon Sep 17 00:00:00 2001
From: Christian <c@ethdev.com>
Date: Wed, 29 Oct 2014 00:13:26 +0100
Subject: Bugfix: Tag takes one byte (for JUMPDEST)

---
 Assembly.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 5b10138d..7ad84682 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -54,6 +54,7 @@ unsigned Assembly::bytesRequired() const
 			switch (i.m_type)
 			{
 			case Operation:
+			case Tag: // 1 byte for the JUMPDEST
 				ret++;
 				break;
 			case PushString:
@@ -69,7 +70,6 @@ unsigned Assembly::bytesRequired() const
 			case PushData:
 			case PushSub:
 				ret += 1 + br;
-			case Tag:;
 			default:;
 			}
 		if (dev::bytesRequired(ret) <= br)
-- 
cgit v1.2.3


From d038c0751dba11ce8c6d9c3ec2375190ab145b6d Mon Sep 17 00:00:00 2001
From: Christian <c@ethdev.com>
Date: Thu, 30 Oct 2014 01:20:32 +0100
Subject: Contract compiler and also add ExpressionStatement to AST.

ExpressionStatement functions as glue between Statements and Expressions.

This way it is possible to detect when the border between statements and
expressions is crossed while walking the AST. Note that ExpressionStatement is
not the only border, almost every statement can contains expressions.
---
 Assembly.cpp | 2 +-
 Assembly.h   | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 5b10138d..7ad84682 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -54,6 +54,7 @@ unsigned Assembly::bytesRequired() const
 			switch (i.m_type)
 			{
 			case Operation:
+			case Tag: // 1 byte for the JUMPDEST
 				ret++;
 				break;
 			case PushString:
@@ -69,7 +70,6 @@ unsigned Assembly::bytesRequired() const
 			case PushData:
 			case PushSub:
 				ret += 1 + br;
-			case Tag:;
 			default:;
 			}
 		if (dev::bytesRequired(ret) <= br)
diff --git a/Assembly.h b/Assembly.h
index 8ab3062d..38baee0c 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -105,7 +105,11 @@ public:
 	void injectStart(AssemblyItem const& _i);
 
 	std::string out() const { std::stringstream ret; streamRLP(ret); return ret.str(); }
+
 	int deposit() const { return m_deposit; }
+	void adjustDeposit(int _adjustment) { m_deposit += _adjustment; assert(m_deposit >= 0); }
+	void setDeposit(int _deposit) { m_deposit = _deposit; assert(m_deposit >= 0); }
+
 	bytes assemble() const;
 	Assembly& optimise(bool _enable);
 	std::ostream& streamRLP(std::ostream& _out, std::string const& _prefix = "") const;
-- 
cgit v1.2.3


From 64786387c17fec33e3e9de40387925c10a9dccfb Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Fri, 31 Oct 2014 14:32:32 +0100
Subject: PoC-7: Instruction set reform

---
 Assembly.cpp     |  2 +-
 CodeFragment.cpp | 14 +++++++-------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 7ad84682..25895e1b 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -251,7 +251,7 @@ Assembly& Assembly::optimise(bool _enable)
 		{ { PushSub, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
 		{ { PushSubSize, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
 		{ { Push, PushTag, Instruction::JUMPI }, [](AssemblyItemsConstRef m) -> AssemblyItems { if (m[0].data()) return { m[1], Instruction::JUMP }; else return {}; } },
-		{ { Instruction::NOT, Instruction::NOT }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
+		{ { Instruction::ISZERO, Instruction::ISZERO }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
 	};
 
 	for (auto const& i: c_simple)
diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index 56b5d440..47df8f3b 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -328,7 +328,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 
 		std::map<std::string, Instruction> const c_arith = { { "+", Instruction::ADD }, { "-", Instruction::SUB }, { "*", Instruction::MUL }, { "/", Instruction::DIV }, { "%", Instruction::MOD }, { "&", Instruction::AND }, { "|", Instruction::OR }, { "^", Instruction::XOR } };
 		std::map<std::string, pair<Instruction, bool>> const c_binary = { { "<", { Instruction::LT, false } }, { "<=", { Instruction::GT, true } }, { ">", { Instruction::GT, false } }, { ">=", { Instruction::LT, true } }, { "S<", { Instruction::SLT, false } }, { "S<=", { Instruction::SGT, true } }, { "S>", { Instruction::SGT, false } }, { "S>=", { Instruction::SLT, true } }, { "=", { Instruction::EQ, false } }, { "!=", { Instruction::EQ, true } } };
-		std::map<std::string, Instruction> const c_unary = { { "!", Instruction::NOT } };
+		std::map<std::string, Instruction> const c_unary = { { "!", Instruction::ISZERO } };
 
 		vector<CodeFragment> code;
 		CompilerState ns = _s;
@@ -403,7 +403,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 			m_asm.append(code[0].m_asm, 1);
 			m_asm.append(it->second.first);
 			if (it->second.second)
-				m_asm.append(Instruction::NOT);
+				m_asm.append(Instruction::ISZERO);
 		}
 		else if (c_unary.count(us))
 		{
@@ -437,7 +437,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 
 			m_asm.append(code[0].m_asm);
 			if (us == "WHEN")
-				m_asm.append(Instruction::NOT);
+				m_asm.append(Instruction::ISZERO);
 			auto end = m_asm.appendJumpI();
 			m_asm.onePath();
 			m_asm.otherPath();
@@ -452,7 +452,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 
 			auto begin = m_asm.append();
 			m_asm.append(code[0].m_asm);
-			m_asm.append(Instruction::NOT);
+			m_asm.append(Instruction::ISZERO);
 			auto end = m_asm.appendJumpI();
 			m_asm.append(code[1].m_asm, 0);
 			m_asm.appendJump(begin);
@@ -466,7 +466,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 			m_asm.append(code[0].m_asm, 0);
 			auto begin = m_asm.append();
 			m_asm.append(code[1].m_asm);
-			m_asm.append(Instruction::NOT);
+			m_asm.append(Instruction::ISZERO);
 			auto end = m_asm.appendJumpI();
 			m_asm.append(code[3].m_asm, 0);
 			m_asm.append(code[2].m_asm, 0);
@@ -502,7 +502,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 				requireDeposit(2, 1);
 				m_asm.append(code[2].m_asm, 1);
 				m_asm.append(Instruction::LT);
-				m_asm.append(Instruction::NOT);
+				m_asm.append(Instruction::ISZERO);
 				m_asm.append(Instruction::MUL);
 				m_asm.append(Instruction::DUP1);
 			}
@@ -525,7 +525,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 					// Check if true - predicate
 					m_asm.append(code[i - 1].m_asm, 1);
 					if (us == "&&")
-						m_asm.append(Instruction::NOT);
+						m_asm.append(Instruction::ISZERO);
 					m_asm.appendJumpI(end);
 				}
 				m_asm.append(Instruction::POP);
-- 
cgit v1.2.3


From 577503539e5fe6c06edc3271b0b00d51f82e29c9 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Fri, 31 Oct 2014 20:29:38 +0100
Subject: Fix for assembler.

---
 Assembly.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Assembly.cpp b/Assembly.cpp
index 25895e1b..d4f6c0a7 100644
--- a/Assembly.cpp
+++ b/Assembly.cpp
@@ -413,8 +413,8 @@ bytes Assembly::assemble() const
 			break;
 		}
 		case Tag:
-			ret.push_back((byte)Instruction::JUMPDEST);
 			tagPos[(unsigned)i.m_data] = ret.size();
+			ret.push_back((byte)Instruction::JUMPDEST);
 			break;
 		default:;
 		}
-- 
cgit v1.2.3


From fd980ea543a9d666dd20289ac61cfbe40a039d5e Mon Sep 17 00:00:00 2001
From: Christian <c@ethdev.com>
Date: Wed, 5 Nov 2014 15:21:20 +0100
Subject: assert and exception corrections in solidity-external files.

---
 Assembly.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/Assembly.h b/Assembly.h
index 38baee0c..e39f1899 100644
--- a/Assembly.h
+++ b/Assembly.h
@@ -45,8 +45,8 @@ public:
 	AssemblyItem(Instruction _i): m_type(Operation), m_data((byte)_i) {}
 	AssemblyItem(AssemblyItemType _type, u256 _data = 0): m_type(_type), m_data(_data) {}
 
-	AssemblyItem tag() const { assert(m_type == PushTag || m_type == Tag); return AssemblyItem(Tag, m_data); }
-	AssemblyItem pushTag() const { assert(m_type == PushTag || m_type == Tag); return AssemblyItem(PushTag, m_data); }
+	AssemblyItem tag() const { if (asserts(m_type == PushTag || m_type == Tag)) BOOST_THROW_EXCEPTION(Exception()); return AssemblyItem(Tag, m_data); }
+	AssemblyItem pushTag() const { if (asserts(m_type == PushTag || m_type == Tag)) BOOST_THROW_EXCEPTION(Exception()); return AssemblyItem(PushTag, m_data); }
 
 	AssemblyItemType type() const { return m_type; }
 	u256 data() const { return m_data; }
@@ -94,7 +94,7 @@ public:
 	AssemblyItem const& back() { return m_items.back(); }
 	std::string backString() const { return m_items.size() && m_items.back().m_type == PushString ? m_strings.at((h256)m_items.back().m_data) : std::string(); }
 
-	void onePath() { assert(!m_totalDeposit && !m_baseDeposit); m_baseDeposit = m_deposit; m_totalDeposit = INT_MAX; }
+	void onePath() { if (asserts(!m_totalDeposit && !m_baseDeposit)) BOOST_THROW_EXCEPTION(InvalidDeposit()); m_baseDeposit = m_deposit; m_totalDeposit = INT_MAX; }
 	void otherPath() { donePath(); m_totalDeposit = m_deposit; m_deposit = m_baseDeposit; }
 	void donePaths() { donePath(); m_totalDeposit = m_baseDeposit = 0; }
 	void ignored() { m_baseDeposit = m_deposit; }
@@ -107,8 +107,8 @@ public:
 	std::string out() const { std::stringstream ret; streamRLP(ret); return ret.str(); }
 
 	int deposit() const { return m_deposit; }
-	void adjustDeposit(int _adjustment) { m_deposit += _adjustment; assert(m_deposit >= 0); }
-	void setDeposit(int _deposit) { m_deposit = _deposit; assert(m_deposit >= 0); }
+	void adjustDeposit(int _adjustment) { m_deposit += _adjustment; if (asserts(m_deposit >= 0)) BOOST_THROW_EXCEPTION(InvalidDeposit()); }
+	void setDeposit(int _deposit) { m_deposit = _deposit; if (asserts(m_deposit >= 0)) BOOST_THROW_EXCEPTION(InvalidDeposit()); }
 
 	bytes assemble() const;
 	Assembly& optimise(bool _enable);
-- 
cgit v1.2.3


From 476853f3feb2159fa24a85826c19e7e5190d3770 Mon Sep 17 00:00:00 2001
From: Christian <c@ethdev.com>
Date: Thu, 6 Nov 2014 14:50:18 +0100
Subject: Moved instructions and assembly to new libevmcore.

---
 All.h            |   1 -
 Assembly.cpp     | 447 -------------------------------------------------------
 Assembly.h       | 139 -----------------
 CMakeLists.txt   |   2 +-
 CodeFragment.cpp |   2 +-
 CodeFragment.h   |   4 +-
 Exceptions.h     |   3 -
 7 files changed, 4 insertions(+), 594 deletions(-)
 delete mode 100644 Assembly.cpp
 delete mode 100644 Assembly.h

diff --git a/All.h b/All.h
index ec6989e6..7c4192f6 100644
--- a/All.h
+++ b/All.h
@@ -1,6 +1,5 @@
 #pragma once
 
-#include "Assembly.h"
 #include "CodeFragment.h"
 #include "Compiler.h"
 #include "CompilerState.h"
diff --git a/Assembly.cpp b/Assembly.cpp
deleted file mode 100644
index d4f6c0a7..00000000
--- a/Assembly.cpp
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file Assembly.cpp
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#include "Assembly.h"
-
-#include <libdevcore/Log.h>
-
-using namespace std;
-using namespace dev;
-using namespace dev::eth;
-
-int AssemblyItem::deposit() const
-{
-	switch (m_type)
-	{
-	case Operation:
-		return instructionInfo((Instruction)(byte)m_data).ret - instructionInfo((Instruction)(byte)m_data).args;
-	case Push: case PushString: case PushTag: case PushData: case PushSub: case PushSubSize:
-		return 1;
-	case Tag:
-		return 0;
-	default:;
-	}
-	return 0;
-}
-
-unsigned Assembly::bytesRequired() const
-{
-	for (unsigned br = 1;; ++br)
-	{
-		unsigned ret = 1;
-		for (auto const& i: m_data)
-			ret += i.second.size();
-
-		for (AssemblyItem const& i: m_items)
-			switch (i.m_type)
-			{
-			case Operation:
-			case Tag: // 1 byte for the JUMPDEST
-				ret++;
-				break;
-			case PushString:
-				ret += 33;
-				break;
-			case Push:
-				ret += 1 + max<unsigned>(1, dev::bytesRequired(i.m_data));
-				break;
-			case PushSubSize:
-				ret += 4;		// worst case: a 16MB program
-				break;
-			case PushTag:
-			case PushData:
-			case PushSub:
-				ret += 1 + br;
-			default:;
-			}
-		if (dev::bytesRequired(ret) <= br)
-			return ret;
-	}
-}
-
-void Assembly::append(Assembly const& _a)
-{
-	auto newDeposit = m_deposit + _a.deposit();
-	for (AssemblyItem i: _a.m_items)
-	{
-		if (i.type() == Tag || i.type() == PushTag)
-			i.m_data += m_usedTags;
-		append(i);
-	}
-	m_deposit = newDeposit;
-	m_usedTags += _a.m_usedTags;
-	for (auto const& i: _a.m_data)
-		m_data.insert(i);
-	for (auto const& i: _a.m_strings)
-		m_strings.insert(i);
-	for (auto const& i: _a.m_subs)
-		m_subs.insert(i);
-
-	assert(!_a.m_baseDeposit);
-	assert(!_a.m_totalDeposit);
-}
-
-void Assembly::append(Assembly const& _a, int _deposit)
-{
-	if (_deposit > _a.m_deposit)
-		BOOST_THROW_EXCEPTION(InvalidDeposit());
-	else
-	{
-		append(_a);
-		while (_deposit++ < _a.m_deposit)
-			append(Instruction::POP);
-	}
-}
-
-ostream& dev::eth::operator<<(ostream& _out, AssemblyItemsConstRef _i)
-{
-	for (AssemblyItem const& i: _i)
-		switch (i.type())
-		{
-		case Operation:
-			_out << " " << instructionInfo((Instruction)(byte)i.data()).name;
-			break;
-		case Push:
-			_out << " PUSH" << i.data();
-			break;
-		case PushString:
-			_out << " PUSH'[" << hex << (unsigned)i.data() << "]";
-			break;
-		case PushTag:
-			_out << " PUSH[tag" << i.data() << "]";
-			break;
-		case Tag:
-			_out << " tag" << i.data() << ": JUMPDEST";
-			break;
-		case PushData:
-			_out << " PUSH*[" << hex << (unsigned)i.data() << "]";
-			break;
-		case PushSub:
-			_out << " PUSHs[" << hex << h256(i.data()).abridged() << "]";
-			break;
-		case PushSubSize:
-			_out << " PUSHss[" << hex << h256(i.data()).abridged() << "]";
-			break;
-		case UndefinedItem:
-			_out << " ???";
-		default:;
-		}
-	return _out;
-}
-
-ostream& Assembly::streamRLP(ostream& _out, string const& _prefix) const
-{
-	_out << _prefix << ".code:" << endl;
-	for (AssemblyItem const& i: m_items)
-		switch (i.m_type)
-		{
-		case Operation:
-			_out << _prefix << "  " << instructionInfo((Instruction)(byte)i.m_data).name << endl;
-			break;
-		case Push:
-			_out << _prefix << "  PUSH " << i.m_data << endl;
-			break;
-		case PushString:
-			_out << _prefix << "  PUSH \"" << m_strings.at((h256)i.m_data) << "\"" << endl;
-			break;
-		case PushTag:
-			_out << _prefix << "  PUSH [tag" << i.m_data << "]" << endl;
-			break;
-		case PushSub:
-			_out << _prefix << "  PUSH [$" << h256(i.m_data).abridged() << "]" << endl;
-			break;
-		case PushSubSize:
-			_out << _prefix << "  PUSH #[$" << h256(i.m_data).abridged() << "]" << endl;
-			break;
-		case Tag:
-			_out << _prefix << "tag" << i.m_data << ": " << endl << _prefix << "  JUMPDEST" << endl;
-			break;
-		case PushData:
-			_out << _prefix << "  PUSH [" << hex << (unsigned)i.m_data << "]" << endl;
-			break;
-		default:;
-		}
-
-	if (m_data.size() || m_subs.size())
-	{
-		_out << _prefix << ".data:" << endl;
-		for (auto const& i: m_data)
-			if (!m_subs.count(i.first))
-				_out << _prefix << "  " << hex << (unsigned)(u256)i.first << ": " << toHex(i.second) << endl;
-		for (auto const& i: m_subs)
-		{
-			_out << _prefix << "  " << hex << (unsigned)(u256)i.first << ": " << endl;
-			i.second.streamRLP(_out, _prefix + "  ");
-		}
-	}
-	return _out;
-}
-
-AssemblyItem const& Assembly::append(AssemblyItem const& _i)
-{
-	m_deposit += _i.deposit();
-	m_items.push_back(_i);
-	return back();
-}
-
-void Assembly::injectStart(AssemblyItem const& _i)
-{
-	m_items.insert(m_items.begin(), _i);
-}
-
-inline bool matches(AssemblyItemsConstRef _a, AssemblyItemsConstRef _b)
-{
-	if (_a.size() != _b.size())
-		return false;
-	for (unsigned i = 0; i < _a.size(); ++i)
-		if (!_a[i].match(_b[i]))
-			return false;
-	return true;
-}
-
-struct OptimiserChannel: public LogChannel { static const char* name() { return "OPT"; } static const int verbosity = 12; };
-#define copt dev::LogOutputStream<OptimiserChannel, true>()
-
-Assembly& Assembly::optimise(bool _enable)
-{
-	if (!_enable)
-		return *this;
-	map<Instruction, function<u256(u256, u256)>> c_simple =
-	{
-		{ Instruction::SUB, [](u256 a, u256 b)->u256{return a - b;} },
-		{ Instruction::DIV, [](u256 a, u256 b)->u256{return a / b;} },
-		{ Instruction::SDIV, [](u256 a, u256 b)->u256{return s2u(u2s(a) / u2s(b));} },
-		{ Instruction::MOD, [](u256 a, u256 b)->u256{return a % b;} },
-		{ Instruction::SMOD, [](u256 a, u256 b)->u256{return s2u(u2s(a) % u2s(b));} },
-		{ Instruction::EXP, [](u256 a, u256 b)->u256{return (u256)boost::multiprecision::powm((bigint)a, (bigint)b, bigint(2) << 256);} },
-		{ Instruction::LT, [](u256 a, u256 b)->u256{return a < b ? 1 : 0;} },
-		{ Instruction::GT, [](u256 a, u256 b)->u256{return a > b ? 1 : 0;} },
-		{ Instruction::SLT, [](u256 a, u256 b)->u256{return u2s(a) < u2s(b) ? 1 : 0;} },
-		{ Instruction::SGT, [](u256 a, u256 b)->u256{return u2s(a) > u2s(b) ? 1 : 0;} },
-		{ Instruction::EQ, [](u256 a, u256 b)->u256{return a == b ? 1 : 0;} },
-	};
-	map<Instruction, function<u256(u256, u256)>> c_associative =
-	{
-		{ Instruction::ADD, [](u256 a, u256 b)->u256{return a + b;} },
-		{ Instruction::MUL, [](u256 a, u256 b)->u256{return a * b;} },
-	};
-	std::vector<pair<AssemblyItems, function<AssemblyItems(AssemblyItemsConstRef)>>> rules =
-	{
-		{ { Push, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
-		{ { PushTag, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
-		{ { PushString, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
-		{ { PushSub, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
-		{ { PushSubSize, Instruction::POP }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
-		{ { Push, PushTag, Instruction::JUMPI }, [](AssemblyItemsConstRef m) -> AssemblyItems { if (m[0].data()) return { m[1], Instruction::JUMP }; else return {}; } },
-		{ { Instruction::ISZERO, Instruction::ISZERO }, [](AssemblyItemsConstRef) -> AssemblyItems { return {}; } },
-	};
-
-	for (auto const& i: c_simple)
-		rules.push_back({ { Push, Push, i.first }, [&](AssemblyItemsConstRef m) -> AssemblyItems { return { i.second(m[1].data(), m[0].data()) }; } });
-	for (auto const& i: c_associative)
-	{
-		rules.push_back({ { Push, Push, i.first }, [&](AssemblyItemsConstRef m) -> AssemblyItems { return { i.second(m[1].data(), m[0].data()) }; } });
-		rules.push_back({ { Push, i.first, Push, i.first }, [&](AssemblyItemsConstRef m) -> AssemblyItems { return { i.second(m[2].data(), m[0].data()), i.first }; } });
-		rules.push_back({ { PushTag, Instruction::JUMP, Tag }, [&](AssemblyItemsConstRef m) -> AssemblyItems { if (m[0].m_data == m[2].m_data) return {}; else return m.toVector(); }});
-	}
-
-	copt << *this;
-
-	unsigned total = 0;
-	for (unsigned count = 1; count > 0; total += count)
-	{
-		count = 0;
-		map<u256, unsigned> tags;
-		for (unsigned i = 0; i < m_items.size(); ++i)
-		{
-			for (auto const& r: rules)
-			{
-				auto vr = AssemblyItemsConstRef(&m_items).cropped(i, r.first.size());
-				if (matches(&r.first, vr))
-				{
-					auto rw = r.second(vr);
-					if (rw.size() < vr.size())
-					{
-						copt << vr << "matches" << AssemblyItemsConstRef(&r.first) << "becomes...";
-						for (unsigned j = 0; j < vr.size(); ++j)
-							if (j < rw.size())
-								m_items[i + j] = rw[j];
-							else
-								m_items.erase(m_items.begin() + i + rw.size());
-						copt << AssemblyItemsConstRef(&rw);
-						count++;
-						copt << "Now:\n" << m_items;
-					}
-				}
-			}
-			if (m_items[i].type() == Operation && m_items[i].data() == (byte)Instruction::JUMP)
-			{
-				bool o = false;
-				while (m_items.size() > i + 1 && m_items[i + 1].type() != Tag)
-				{
-					m_items.erase(m_items.begin() + i + 1);
-					o = true;
-				}
-				if (o)
-				{
-					copt << "Jump with no tag. Now:\n" << m_items;
-					++count;
-				}
-			}
-		}
-
-		for (unsigned i = 0; i < m_items.size(); ++i)
-			if (m_items[i].type() == Tag)
-				tags.insert(make_pair(m_items[i].data(), i));
-
-		for (auto const& i: m_items)
-			if (i.type() == PushTag)
-				tags.erase(i.data());
-
-		if (tags.size())
-		{
-			auto t = *tags.begin();
-			unsigned i = t.second;
-			if (i && m_items[i - 1].type() == Operation && m_items[i - 1].data() == (byte)Instruction::JUMP)
-				while (i < m_items.size() && (m_items[i].type() != Tag || tags.count(m_items[i].data())))
-				{
-					if (m_items[i].type() == Tag && tags.count(m_items[i].data()))
-						tags.erase(m_items[i].data());
-					m_items.erase(m_items.begin() + i);
-				}
-			else
-			{
-				m_items.erase(m_items.begin() + i);
-				tags.erase(t.first);
-			}
-			copt << "Unused tag. Now:\n" << m_items;
-			++count;
-		}
-	}
-
-	copt << total << " optimisations done.";
-
-	for (auto& i: m_subs)
-	  i.second.optimise(true);
-
-	return *this;
-}
-
-bytes Assembly::assemble() const
-{
-	bytes ret;
-
-	unsigned totalBytes = bytesRequired();
-	ret.reserve(totalBytes);
-	vector<unsigned> tagPos(m_usedTags);
-	map<unsigned, unsigned> tagRef;
-	multimap<h256, unsigned> dataRef;
-	unsigned bytesPerTag = dev::bytesRequired(totalBytes);
-	byte tagPush = (byte)Instruction::PUSH1 - 1 + bytesPerTag;
-
-	for (auto const& i: m_subs)
-		m_data[i.first] = i.second.assemble();
-
-	for (AssemblyItem const& i: m_items)
-		switch (i.m_type)
-		{
-		case Operation:
-			ret.push_back((byte)i.m_data);
-			break;
-		case PushString:
-		{
-			ret.push_back((byte)Instruction::PUSH32);
-			unsigned ii = 0;
-			for (auto j: m_strings.at((h256)i.m_data))
-				if (++ii > 32)
-					break;
-				else
-					ret.push_back((byte)j);
-			while (ii++ < 32)
-				ret.push_back(0);
-			break;
-		}
-		case Push:
-		{
-			byte b = max<unsigned>(1, dev::bytesRequired(i.m_data));
-			ret.push_back((byte)Instruction::PUSH1 - 1 + b);
-			ret.resize(ret.size() + b);
-			bytesRef byr(&ret.back() + 1 - b, b);
-			toBigEndian(i.m_data, byr);
-			break;
-		}
-		case PushTag:
-		{
-			ret.push_back(tagPush);
-			tagRef[ret.size()] = (unsigned)i.m_data;
-			ret.resize(ret.size() + bytesPerTag);
-			break;
-		}
-		case PushData: case PushSub:
-		{
-			ret.push_back(tagPush);
-			dataRef.insert(make_pair((h256)i.m_data, ret.size()));
-			ret.resize(ret.size() + bytesPerTag);
-			break;
-		}
-		case PushSubSize:
-		{
-			auto s = m_data[i.m_data].size();
-			byte b = max<unsigned>(1, dev::bytesRequired(s));
-			ret.push_back((byte)Instruction::PUSH1 - 1 + b);
-			ret.resize(ret.size() + b);
-			bytesRef byr(&ret.back() + 1 - b, b);
-			toBigEndian(s, byr);
-			break;
-		}
-		case Tag:
-			tagPos[(unsigned)i.m_data] = ret.size();
-			ret.push_back((byte)Instruction::JUMPDEST);
-			break;
-		default:;
-		}
-
-	for (auto const& i: tagRef)
-	{
-		bytesRef r(ret.data() + i.first, bytesPerTag);
-		toBigEndian(tagPos[i.second], r);
-	}
-
-	if (m_data.size())
-	{
-		ret.push_back(0);
-		for (auto const& i: m_data)
-		{
-			auto its = dataRef.equal_range(i.first);
-			if (its.first != its.second)
-			{
-				for (auto it = its.first; it != its.second; ++it)
-				{
-					bytesRef r(ret.data() + it->second, bytesPerTag);
-					toBigEndian(ret.size(), r);
-				}
-				for (auto b: i.second)
-					ret.push_back(b);
-			}
-		}
-	}
-	return ret;
-}
diff --git a/Assembly.h b/Assembly.h
deleted file mode 100644
index e39f1899..00000000
--- a/Assembly.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file CodeFragment.h
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#pragma once
-
-#include <iostream>
-#include <sstream>
-#include <libdevcore/Common.h>
-#include <libevmface/Instruction.h>
-#include "Exceptions.h"
-
-namespace dev
-{
-namespace eth
-{
-
-enum AssemblyItemType { UndefinedItem, Operation, Push, PushString, PushTag, PushSub, PushSubSize, Tag, PushData };
-
-class Assembly;
-
-class AssemblyItem
-{
-	friend class Assembly;
-
-public:
-	AssemblyItem(u256 _push): m_type(Push), m_data(_push) {}
-	AssemblyItem(Instruction _i): m_type(Operation), m_data((byte)_i) {}
-	AssemblyItem(AssemblyItemType _type, u256 _data = 0): m_type(_type), m_data(_data) {}
-
-	AssemblyItem tag() const { if (asserts(m_type == PushTag || m_type == Tag)) BOOST_THROW_EXCEPTION(Exception()); return AssemblyItem(Tag, m_data); }
-	AssemblyItem pushTag() const { if (asserts(m_type == PushTag || m_type == Tag)) BOOST_THROW_EXCEPTION(Exception()); return AssemblyItem(PushTag, m_data); }
-
-	AssemblyItemType type() const { return m_type; }
-	u256 data() const { return m_data; }
-
-	int deposit() const;
-
-	bool match(AssemblyItem const& _i) const { return _i.m_type == UndefinedItem || (m_type == _i.m_type && (m_type != Operation || m_data == _i.m_data)); }
-
-private:
-	AssemblyItemType m_type;
-	u256 m_data;
-};
-
-typedef std::vector<AssemblyItem> AssemblyItems;
-typedef vector_ref<AssemblyItem const> AssemblyItemsConstRef;
-
-std::ostream& operator<<(std::ostream& _out, AssemblyItemsConstRef _i);
-inline std::ostream& operator<<(std::ostream& _out, AssemblyItems const& _i) { return operator<<(_out, AssemblyItemsConstRef(&_i)); }
-
-class Assembly
-{
-public:
-	AssemblyItem newTag() { return AssemblyItem(Tag, m_usedTags++); }
-	AssemblyItem newPushTag() { return AssemblyItem(PushTag, m_usedTags++); }
-	AssemblyItem newData(bytes const& _data) { h256 h = (u256)std::hash<std::string>()(asString(_data)); m_data[h] = _data; return AssemblyItem(PushData, h); }
-	AssemblyItem newSub(Assembly const& _sub) { h256 h = h256::random(s_fixedHashEngine); m_subs[h] = _sub; return AssemblyItem(PushSub, h); }
-	AssemblyItem newPushString(std::string const& _data) { h256 h = (u256)std::hash<std::string>()(_data); m_strings[h] = _data; return AssemblyItem(PushString, h); }
-	AssemblyItem newPushSubSize(h256 const& _subId) { return AssemblyItem(PushSubSize, _subId); }
-
-	AssemblyItem append() { return append(newTag()); }
-	void append(Assembly const& _a);
-	void append(Assembly const& _a, int _deposit);
-	AssemblyItem const& append(AssemblyItem const& _i);
-	AssemblyItem const& append(std::string const& _data) { return append(newPushString(_data)); }
-	AssemblyItem const& append(bytes const& _data) { return append(newData(_data)); }
-	AssemblyItem appendSubSize(Assembly const& _a) { auto ret = newSub(_a); append(newPushSubSize(ret.data())); return ret; }
-
-	AssemblyItem appendJump() { auto ret = append(newPushTag()); append(Instruction::JUMP); return ret; }
-	AssemblyItem appendJumpI() { auto ret = append(newPushTag()); append(Instruction::JUMPI); return ret; }
-	AssemblyItem appendJump(AssemblyItem const& _tag) { auto ret = append(_tag.pushTag()); append(Instruction::JUMP); return ret; }
-	AssemblyItem appendJumpI(AssemblyItem const& _tag) { auto ret = append(_tag.pushTag()); append(Instruction::JUMPI); return ret; }
-
-	template <class T> Assembly& operator<<(T const& _d) { append(_d); return *this; }
-
-	AssemblyItem const& back() { return m_items.back(); }
-	std::string backString() const { return m_items.size() && m_items.back().m_type == PushString ? m_strings.at((h256)m_items.back().m_data) : std::string(); }
-
-	void onePath() { if (asserts(!m_totalDeposit && !m_baseDeposit)) BOOST_THROW_EXCEPTION(InvalidDeposit()); m_baseDeposit = m_deposit; m_totalDeposit = INT_MAX; }
-	void otherPath() { donePath(); m_totalDeposit = m_deposit; m_deposit = m_baseDeposit; }
-	void donePaths() { donePath(); m_totalDeposit = m_baseDeposit = 0; }
-	void ignored() { m_baseDeposit = m_deposit; }
-	void endIgnored() { m_deposit = m_baseDeposit; m_baseDeposit = 0; }
-
-	void popTo(int _deposit) { while (m_deposit > _deposit) append(Instruction::POP); }
-
-	void injectStart(AssemblyItem const& _i);
-
-	std::string out() const { std::stringstream ret; streamRLP(ret); return ret.str(); }
-
-	int deposit() const { return m_deposit; }
-	void adjustDeposit(int _adjustment) { m_deposit += _adjustment; if (asserts(m_deposit >= 0)) BOOST_THROW_EXCEPTION(InvalidDeposit()); }
-	void setDeposit(int _deposit) { m_deposit = _deposit; if (asserts(m_deposit >= 0)) BOOST_THROW_EXCEPTION(InvalidDeposit()); }
-
-	bytes assemble() const;
-	Assembly& optimise(bool _enable);
-	std::ostream& streamRLP(std::ostream& _out, std::string const& _prefix = "") const;
-
-private:
-	void donePath() { if (m_totalDeposit != INT_MAX && m_totalDeposit != m_deposit) BOOST_THROW_EXCEPTION(InvalidDeposit()); }
-	unsigned bytesRequired() const;
-
-	unsigned m_usedTags = 0;
-	AssemblyItems m_items;
-	mutable std::map<h256, bytes> m_data;
-	std::map<h256, Assembly> m_subs;
-	std::map<h256, std::string> m_strings;
-
-	int m_deposit = 0;
-	int m_baseDeposit = 0;
-	int m_totalDeposit = 0;
-};
-
-inline std::ostream& operator<<(std::ostream& _out, Assembly const& _a)
-{
-	_a.streamRLP(_out);
-	return _out;
-}
-
-}
-}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cb50cc36..8b158178 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -15,7 +15,7 @@ endif()
 
 include_directories(..)
 
-target_link_libraries(${EXECUTABLE} evmface)
+target_link_libraries(${EXECUTABLE} evmcore)
 target_link_libraries(${EXECUTABLE} devcore)
 
 
diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index 47df8f3b..2c200caa 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -25,7 +25,7 @@
 #include <boost/spirit/include/support_utree.hpp>
 #include <libdevcore/Log.h>
 #include <libdevcore/CommonIO.h>
-#include <libevmface/Instruction.h>
+#include <libevmcore/Instruction.h>
 #include "CompilerState.h"
 #include "Parser.h"
 using namespace std;
diff --git a/CodeFragment.h b/CodeFragment.h
index d6ca86bb..b24b474d 100644
--- a/CodeFragment.h
+++ b/CodeFragment.h
@@ -22,8 +22,8 @@
 #pragma once
 
 #include <libdevcore/Common.h>
-#include <libevmface/Instruction.h>
-#include "Assembly.h"
+#include <libevmcore/Instruction.h>
+#include <libevmcore/Assembly.h>
 #include "Exceptions.h"
 
 namespace boost { namespace spirit { class utree; } }
diff --git a/Exceptions.h b/Exceptions.h
index c45215f1..1e9671b3 100644
--- a/Exceptions.h
+++ b/Exceptions.h
@@ -32,16 +32,13 @@ namespace eth
 class CompilerException: public dev::Exception {};
 class InvalidOperation: public CompilerException {};
 class IntegerOutOfRange: public CompilerException {};
-class StringTooLong: public CompilerException {};
 class EmptyList: public CompilerException {};
 class DataNotExecutable: public CompilerException {};
 class IncorrectParameterCount: public CompilerException {};
-class InvalidDeposit: public CompilerException {};
 class InvalidName: public CompilerException {};
 class InvalidMacroArgs: public CompilerException {};
 class InvalidLiteral: public CompilerException {};
 class BareSymbol: public CompilerException {};
-class ExpectedLiteral: public CompilerException {};
 
 }
 }
-- 
cgit v1.2.3


From c60def06b504bda1cc61923c8d1951465996c7a1 Mon Sep 17 00:00:00 2001
From: Marek Kotewicz <marek.kotewicz@gmail.com>
Date: Thu, 4 Dec 2014 09:55:54 +0100
Subject: removed automocs

---
 CMakeLists.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8b158178..4e694135 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,5 @@
 cmake_policy(SET CMP0015 NEW)
+set(CMAKE_AUTOMOC OFF)
 
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
 
-- 
cgit v1.2.3


From 33ac800c01ca080cea4b954a0c609782c9f3bbe3 Mon Sep 17 00:00:00 2001
From: debris <marek.kotewicz@gmail.com>
Date: Fri, 5 Dec 2014 16:40:41 +0100
Subject: lll, buildinfo.h and llc compiling on windows

---
 CMakeLists.txt | 30 +++---------------------------
 1 file changed, 3 insertions(+), 27 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4e694135..e2c00001 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,6 +5,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
 
 aux_source_directory(. SRC_LIST)
 
+include_directories(${Boost_INCLUDE_DIRS})
+include_directories(..)
+
 set(EXECUTABLE lll)
 
 file(GLOB HEADERS "*.h")
@@ -14,36 +17,9 @@ else()
 	add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS})
 endif()
 
-include_directories(..)
-
 target_link_libraries(${EXECUTABLE} evmcore)
 target_link_libraries(${EXECUTABLE} devcore)
 
-
-if("${TARGET_PLATFORM}" STREQUAL "w64")
-	target_link_libraries(${EXECUTABLE} boost_system-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_system-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_SYSTEM_LIBRARY})
-	target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY})
-	target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
-else ()
-	target_link_libraries(${EXECUTABLE} boost_system)
-	target_link_libraries(${EXECUTABLE} boost_thread)
-	find_package(Threads REQUIRED)
-	target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
-endif ()
-
 install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
 install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )
 
-- 
cgit v1.2.3


From 8f3f5275c01e40bbbf0e1a5df3ec01115e757478 Mon Sep 17 00:00:00 2001
From: Marek Kotewicz <marek.kotewicz@gmail.com>
Date: Wed, 10 Dec 2014 11:39:41 +0100
Subject: jsonrpc option in cmakes, removed all warnings

---
 CMakeLists.txt | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e2c00001..908b8caf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,10 @@
 cmake_policy(SET CMP0015 NEW)
+# this policy was introduced in cmake 3.0
+# remove if, once 3.0 will be used on unix
+if (APPLE)
+	# old policy do not use MACOSX_RPATH
+	cmake_policy(SET CMP0042 OLD)
+endif()
 set(CMAKE_AUTOMOC OFF)
 
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
-- 
cgit v1.2.3


From c8ad93914148a3a0c191f22bb21e9eabf217d1ae Mon Sep 17 00:00:00 2001
From: Marek Kotewicz <marek.kotewicz@gmail.com>
Date: Wed, 10 Dec 2014 12:49:12 +0100
Subject: updated cmake policies

---
 CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 908b8caf..28e5cb75 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
 cmake_policy(SET CMP0015 NEW)
 # this policy was introduced in cmake 3.0
 # remove if, once 3.0 will be used on unix
-if (APPLE)
+if (${CMAKE_MAJOR_VERSION} GREATER 2)
 	# old policy do not use MACOSX_RPATH
 	cmake_policy(SET CMP0042 OLD)
 endif()
-- 
cgit v1.2.3


From 005f551bfbf153a11af7cb3c2015ccfe6cf70e08 Mon Sep 17 00:00:00 2001
From: Marek Kotewicz <marek.kotewicz@gmail.com>
Date: Thu, 11 Dec 2014 15:06:11 +0100
Subject: fixed styling issues

---
 CMakeLists.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 28e5cb75..fb79d587 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,6 +17,7 @@ include_directories(..)
 set(EXECUTABLE lll)
 
 file(GLOB HEADERS "*.h")
+
 if(ETH_STATIC)
 	add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS})
 else()
-- 
cgit v1.2.3


From fee1a7f44cbb3a7743531b12bf1091075d435e6a Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Thu, 11 Dec 2014 18:25:21 +0100
Subject: Fix for crazy compiler lambda behaviour.

---
 CompilerState.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/CompilerState.cpp b/CompilerState.cpp
index c3dc2dda..63351bc4 100644
--- a/CompilerState.cpp
+++ b/CompilerState.cpp
@@ -72,6 +72,11 @@ void CompilerState::populateStandard()
 	"(def 'regname (name) { [32]'register [64]name (call allgas namereg 0 32 64 0 0) })"
 	"(def 'regcoin (name) { [32]name (call allgas coinreg 0 32 32 0 0) })"
 	"(def 'regcoin (name denom) { [32]name [64]denom (call allgas coinreg 0 32 64 0 0) })"
+	"(def 'ecrecover (r s v hash) { [0] r [32] s [64] v [96] hash (msg allgas 1 0 0 128) })"
+	"(def 'sha256 (data datasize) (msg allgas 2 0 data datasize))"
+	"(def 'ripemd160 (data datasize) (msg allgas 3 0 data datasize))"
+	"(def 'sha256 (val) { [0]:val (sha256 0 32) })"
+	"(def 'ripemd160 (val) { [0]:val (ripemd160 0 32) })"
 	"}";
 	CodeFragment::compile(s, *this);
 }
-- 
cgit v1.2.3


From 529847d8e1e91f3c764b5adddc5d832a2d598d0c Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Wed, 21 Jan 2015 11:31:14 -0800
Subject: Claim ether makes wallet & trasfers. "#require" in solidity.

---
 CodeFragment.cpp | 1 -
 CodeFragment.h   | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index 2c200caa..1e776643 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -266,7 +266,6 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 				}
 				++ii;
 			}
-
 		}
 		else if (us == "LIT")
 		{
diff --git a/CodeFragment.h b/CodeFragment.h
index b24b474d..554f90b4 100644
--- a/CodeFragment.h
+++ b/CodeFragment.h
@@ -61,3 +61,4 @@ static const CodeFragment NullCodeFragment;
 
 }
 }
+
-- 
cgit v1.2.3


From 887627fd284440b346818d17b139d3bd876ba4e6 Mon Sep 17 00:00:00 2001
From: Lu Guanqun <guanqun.lu@gmail.com>
Date: Fri, 6 Feb 2015 15:19:22 +0800
Subject: change typedef to using according to preferred coding style

---
 Parser.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Parser.cpp b/Parser.cpp
index e94e88e1..df30f389 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -89,8 +89,8 @@ void dev::eth::parseTreeLLL(string const& _s, sp::utree& o_out)
 	using qi::standard::space;
 	using qi::standard::space_type;
 	using dev::eth::parseTreeLLL_::tagNode;
-	typedef sp::basic_string<std::string, sp::utree_type::symbol_type> symbol_type;
-	typedef string::const_iterator it;
+	using symbol_type = sp::basic_string<std::string, sp::utree_type::symbol_type>;
+	using it = string::const_iterator;
 
 	static const u256 ether = u256(1000000000) * 1000000000;
 	static const u256 finney = u256(1000000000) * 1000000;
-- 
cgit v1.2.3


From 1137e84828c44120cf0300f0b434a8dd20dcc298 Mon Sep 17 00:00:00 2001
From: Marek Kotewicz <marek.kotewicz@gmail.com>
Date: Mon, 16 Feb 2015 13:48:25 +0100
Subject: fixed #1022

---
 CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index fb79d587..3b9dc603 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,8 +11,8 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
 
 aux_source_directory(. SRC_LIST)
 
+include_directories(BEFORE ..)
 include_directories(${Boost_INCLUDE_DIRS})
-include_directories(..)
 
 set(EXECUTABLE lll)
 
-- 
cgit v1.2.3


From b804ef818a07d53faa3b3cdeca6914a5871cc8a9 Mon Sep 17 00:00:00 2001
From: Gav Wood <i@gavwood.com>
Date: Fri, 20 Feb 2015 21:59:21 +0100
Subject: Add EVMJIT.

---
 All.h             |   6 -
 CMakeLists.txt    |  32 ---
 CodeFragment.cpp  | 581 ------------------------------------------------------
 CodeFragment.h    |  64 ------
 Compiler.cpp      |  95 ---------
 Compiler.h        |  38 ----
 CompilerState.cpp |  82 --------
 CompilerState.h   |  57 ------
 Exceptions.h      |  44 -----
 Parser.cpp        | 145 --------------
 Parser.h          |  41 ----
 11 files changed, 1185 deletions(-)
 delete mode 100644 All.h
 delete mode 100644 CMakeLists.txt
 delete mode 100644 CodeFragment.cpp
 delete mode 100644 CodeFragment.h
 delete mode 100644 Compiler.cpp
 delete mode 100644 Compiler.h
 delete mode 100644 CompilerState.cpp
 delete mode 100644 CompilerState.h
 delete mode 100644 Exceptions.h
 delete mode 100644 Parser.cpp
 delete mode 100644 Parser.h

diff --git a/All.h b/All.h
deleted file mode 100644
index 7c4192f6..00000000
--- a/All.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-
-#include "CodeFragment.h"
-#include "Compiler.h"
-#include "CompilerState.h"
-#include "Parser.h"
diff --git a/CMakeLists.txt b/CMakeLists.txt
deleted file mode 100644
index 3b9dc603..00000000
--- a/CMakeLists.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-cmake_policy(SET CMP0015 NEW)
-# this policy was introduced in cmake 3.0
-# remove if, once 3.0 will be used on unix
-if (${CMAKE_MAJOR_VERSION} GREATER 2)
-	# old policy do not use MACOSX_RPATH
-	cmake_policy(SET CMP0042 OLD)
-endif()
-set(CMAKE_AUTOMOC OFF)
-
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
-
-aux_source_directory(. SRC_LIST)
-
-include_directories(BEFORE ..)
-include_directories(${Boost_INCLUDE_DIRS})
-
-set(EXECUTABLE lll)
-
-file(GLOB HEADERS "*.h")
-
-if(ETH_STATIC)
-	add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS})
-else()
-	add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS})
-endif()
-
-target_link_libraries(${EXECUTABLE} evmcore)
-target_link_libraries(${EXECUTABLE} devcore)
-
-install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
-install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )
-
diff --git a/CodeFragment.cpp b/CodeFragment.cpp
deleted file mode 100644
index 1e776643..00000000
--- a/CodeFragment.cpp
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file CodeFragment.cpp
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#include "CodeFragment.h"
-
-#include <boost/algorithm/string.hpp>
-#include <boost/spirit/include/support_utree.hpp>
-#include <libdevcore/Log.h>
-#include <libdevcore/CommonIO.h>
-#include <libevmcore/Instruction.h>
-#include "CompilerState.h"
-#include "Parser.h"
-using namespace std;
-using namespace dev;
-using namespace dev::eth;
-namespace qi = boost::spirit::qi;
-namespace px = boost::phoenix;
-namespace sp = boost::spirit;
-
-void CodeFragment::finalise(CompilerState const& _cs)
-{
-	if (_cs.usedAlloc && _cs.vars.size() && !m_finalised)
-	{
-		m_finalised = true;
-		m_asm.injectStart(Instruction::MSTORE8);
-		m_asm.injectStart((u256)((_cs.vars.size() + 2) * 32) - 1);
-		m_asm.injectStart((u256)1);
-	}
-}
-
-CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowASM)
-{
-/*	cdebug << "CodeFragment. Locals:";
-	for (auto const& i: _s.defs)
-		cdebug << i.first << ":" << toHex(i.second.m_code);
-	cdebug << "Args:";
-	for (auto const& i: _s.args)
-		cdebug << i.first << ":" << toHex(i.second.m_code);
-	cdebug << "Outers:";
-	for (auto const& i: _s.outers)
-		cdebug << i.first << ":" << toHex(i.second.m_code);
-	debugOutAST(cout, _t);
-	cout << endl << flush;
-*/
-	switch (_t.which())
-	{
-	case sp::utree_type::list_type:
-		constructOperation(_t, _s);
-		break;
-	case sp::utree_type::string_type:
-	{
-		auto sr = _t.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
-		string s(sr.begin(), sr.end());
-		m_asm.append(s);
-		break;
-	}
-	case sp::utree_type::symbol_type:
-	{
-		auto sr = _t.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
-		string s(sr.begin(), sr.end());
-		string us = boost::algorithm::to_upper_copy(s);
-		if (_allowASM && c_instructions.count(us))
-			m_asm.append(c_instructions.at(us));
-		else if (_s.defs.count(s))
-			m_asm.append(_s.defs.at(s).m_asm);
-		else if (_s.args.count(s))
-			m_asm.append(_s.args.at(s).m_asm);
-		else if (_s.outers.count(s))
-			m_asm.append(_s.outers.at(s).m_asm);
-		else if (us.find_first_of("1234567890") != 0 && us.find_first_not_of("QWERTYUIOPASDFGHJKLZXCVBNM1234567890_") == string::npos)
-		{
-			auto it = _s.vars.find(s);
-			if (it == _s.vars.end())
-			{
-				bool ok;
-				tie(it, ok) = _s.vars.insert(make_pair(s, make_pair(_s.stackSize, 32)));
-				_s.stackSize += 32;
-			}
-			m_asm.append((u256)it->second.first);
-		}
-		else
-			error<BareSymbol>();
-
-		break;
-	}
-	case sp::utree_type::any_type:
-	{
-		bigint i = *_t.get<bigint*>();
-		if (i < 0 || i > bigint(u256(0) - 1))
-			error<IntegerOutOfRange>();
-		m_asm.append((u256)i);
-		break;
-	}
-	default: break;
-	}
-}
-
-void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
-{
-	if (_t.tag() == 0 && _t.empty())
-		error<EmptyList>();
-	else if (_t.tag() == 0 && _t.front().which() != sp::utree_type::symbol_type)
-		error<DataNotExecutable>();
-	else
-	{
-		string s;
-		string us;
-		switch (_t.tag())
-		{
-		case 0:
-		{
-			auto sr = _t.front().get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
-			s = string(sr.begin(), sr.end());
-			us = boost::algorithm::to_upper_copy(s);
-			break;
-		}
-		case 1:
-			us = "MLOAD";
-			break;
-		case 2:
-			us = "SLOAD";
-			break;
-		case 3:
-			us = "MSTORE";
-			break;
-		case 4:
-			us = "SSTORE";
-			break;
-		case 5:
-			us = "SEQ";
-			break;
-		case 6:
-			us = "CALLDATALOAD";
-			break;
-		default:;
-		}
-
-		auto firstAsString = [&]()
-		{
-			auto i = *++_t.begin();
-			if (i.tag())
-				error<InvalidName>();
-			if (i.which() == sp::utree_type::string_type)
-			{
-				auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
-				return string(sr.begin(), sr.end());
-			}
-			else if (i.which() == sp::utree_type::symbol_type)
-			{
-				auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
-				return _s.getDef(string(sr.begin(), sr.end())).m_asm.backString();
-			}
-			return string();
-		};
-
-		auto varAddress = [&](string const& n)
-		{
-			auto it = _s.vars.find(n);
-			if (it == _s.vars.end())
-			{
-				bool ok;
-				tie(it, ok) = _s.vars.insert(make_pair(n, make_pair(_s.stackSize, 32)));
-				_s.stackSize += 32;
-			}
-			return it->second.first;
-		};
-
-		// Operations who args are not standard stack-pushers.
-		bool nonStandard = true;
-		if (us == "ASM")
-		{
-			int c = 0;
-			for (auto const& i: _t)
-				if (c++)
-					m_asm.append(CodeFragment(i, _s, true).m_asm);
-		}
-		else if (us == "INCLUDE")
-		{
-			if (_t.size() != 2)
-				error<IncorrectParameterCount>();
-			m_asm.append(CodeFragment::compile(asString(contents(firstAsString())), _s).m_asm);
-		}
-		else if (us == "SET")
-		{
-			if (_t.size() != 3)
-				error<IncorrectParameterCount>();
-			int c = 0;
-			for (auto const& i: _t)
-				if (c++ == 2)
-					m_asm.append(CodeFragment(i, _s, false).m_asm);
-			m_asm.append((u256)varAddress(firstAsString()));
-			m_asm.append(Instruction::MSTORE);
-		}
-		else if (us == "GET")
-		{
-			if (_t.size() != 2)
-				error<IncorrectParameterCount>();
-			m_asm.append((u256)varAddress(firstAsString()));
-			m_asm.append(Instruction::MLOAD);
-		}
-		else if (us == "REF")
-			m_asm.append((u256)varAddress(firstAsString()));
-		else if (us == "DEF")
-		{
-			string n;
-			unsigned ii = 0;
-			if (_t.size() != 3 && _t.size() != 4)
-				error<IncorrectParameterCount>();
-			vector<string> args;
-			for (auto const& i: _t)
-			{
-				if (ii == 1)
-				{
-					if (i.tag())
-						error<InvalidName>();
-					if (i.which() == sp::utree_type::string_type)
-					{
-						auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
-						n = string(sr.begin(), sr.end());
-					}
-					else if (i.which() == sp::utree_type::symbol_type)
-					{
-						auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
-						n = _s.getDef(string(sr.begin(), sr.end())).m_asm.backString();
-					}
-				}
-				else if (ii == 2)
-					if (_t.size() == 3)
-						_s.defs[n] = CodeFragment(i, _s);
-					else
-						for (auto const& j: i)
-						{
-							if (j.tag() || j.which() != sp::utree_type::symbol_type)
-								error<InvalidMacroArgs>();
-							auto sr = j.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
-							args.push_back(string(sr.begin(), sr.end()));
-						}
-				else if (ii == 3)
-				{
-					auto k = make_pair(n, args.size());
-					_s.macros[k].code = i;
-					_s.macros[k].env = _s.outers;
-					_s.macros[k].args = args;
-					for (auto const& i: _s.args)
-						_s.macros[k].env[i.first] = i.second;
-					for (auto const& i: _s.defs)
-						_s.macros[k].env[i.first] = i.second;
-				}
-				++ii;
-			}
-		}
-		else if (us == "LIT")
-		{
-			if (_t.size() < 3)
-				error<IncorrectParameterCount>();
-			unsigned ii = 0;
-			CodeFragment pos;
-			bytes data;
-			for (auto const& i: _t)
-			{
-				if (ii == 1)
-				{
-					pos = CodeFragment(i, _s);
-					if (pos.m_asm.deposit() != 1)
-						error<InvalidDeposit>();
-				}
-				else if (ii == 2 && !i.tag() && i.which() == sp::utree_type::string_type)
-				{
-					auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
-					data = bytes((byte const*)sr.begin(), (byte const*)sr.end());
-				}
-				else if (ii >= 2 && !i.tag() && i.which() == sp::utree_type::any_type)
-				{
-					bigint bi = *i.get<bigint*>();
-					if (bi < 0)
-						error<IntegerOutOfRange>();
-					else if (bi > bigint(u256(0) - 1))
-					{
-						if (ii == 2 && _t.size() == 3)
-						{
-							// One big int - allow it as hex.
-							data.resize(bytesRequired(bi));
-							toBigEndian(bi, data);
-						}
-						else
-							error<IntegerOutOfRange>();
-					}
-					else
-					{
-						data.resize(data.size() + 32);
-						*(h256*)(&data.back() - 31) = (u256)bi;
-					}
-				}
-				else if (ii)
-					error<InvalidLiteral>();
-				++ii;
-			}
-			m_asm.append((u256)data.size());
-			m_asm.append(Instruction::DUP1);
-			m_asm.append(data);
-			m_asm.append(pos.m_asm, 1);
-			m_asm.append(Instruction::CODECOPY);
-		}
-		else
-			nonStandard = false;
-
-		if (nonStandard)
-			return;
-
-		std::map<std::string, Instruction> const c_arith = { { "+", Instruction::ADD }, { "-", Instruction::SUB }, { "*", Instruction::MUL }, { "/", Instruction::DIV }, { "%", Instruction::MOD }, { "&", Instruction::AND }, { "|", Instruction::OR }, { "^", Instruction::XOR } };
-		std::map<std::string, pair<Instruction, bool>> const c_binary = { { "<", { Instruction::LT, false } }, { "<=", { Instruction::GT, true } }, { ">", { Instruction::GT, false } }, { ">=", { Instruction::LT, true } }, { "S<", { Instruction::SLT, false } }, { "S<=", { Instruction::SGT, true } }, { "S>", { Instruction::SGT, false } }, { "S>=", { Instruction::SLT, true } }, { "=", { Instruction::EQ, false } }, { "!=", { Instruction::EQ, true } } };
-		std::map<std::string, Instruction> const c_unary = { { "!", Instruction::ISZERO } };
-
-		vector<CodeFragment> code;
-		CompilerState ns = _s;
-		ns.vars.clear();
-		ns.usedAlloc = false;
-		int c = _t.tag() ? 1 : 0;
-		for (auto const& i: _t)
-			if (c++)
-			{
-				if (us == "LLL" && c == 1)
-					code.push_back(CodeFragment(i, ns));
-				else
-					code.push_back(CodeFragment(i, _s));
-			}
-		auto requireSize = [&](unsigned s) { if (code.size() != s) error<IncorrectParameterCount>(); };
-		auto requireMinSize = [&](unsigned s) { if (code.size() < s) error<IncorrectParameterCount>(); };
-		auto requireMaxSize = [&](unsigned s) { if (code.size() > s) error<IncorrectParameterCount>(); };
-		auto requireDeposit = [&](unsigned i, int s) { if (code[i].m_asm.deposit() != s) error<InvalidDeposit>(); };
-
-		if (_s.macros.count(make_pair(s, code.size())))
-		{
-			Macro const& m = _s.macros.at(make_pair(s, code.size()));
-			CompilerState cs = _s;
-			for (auto const& i: m.env)
-				cs.outers[i.first] = i.second;
-			for (auto const& i: cs.defs)
-				cs.outers[i.first] = i.second;
-			cs.defs.clear();
-			for (unsigned i = 0; i < m.args.size(); ++i)
-			{
-				//requireDeposit(i, 1);
-				cs.args[m.args[i]] = code[i];
-			}
-			m_asm.append(CodeFragment(m.code, cs).m_asm);
-			for (auto const& i: cs.defs)
-				_s.defs[i.first] = i.second;
-			for (auto const& i: cs.macros)
-				_s.macros.insert(i);
-		}
-		else if (c_instructions.count(us))
-		{
-			auto it = c_instructions.find(us);
-			int ea = instructionInfo(it->second).args;
-			if (ea >= 0)
-				requireSize(ea);
-			else
-				requireMinSize(-ea);
-
-			for (unsigned i = code.size(); i; --i)
-				m_asm.append(code[i - 1].m_asm, 1);
-			m_asm.append(it->second);
-		}
-		else if (c_arith.count(us))
-		{
-			auto it = c_arith.find(us);
-			requireMinSize(1);
-			for (unsigned i = code.size(); i; --i)
-			{
-				requireDeposit(i - 1, 1);
-				m_asm.append(code[i - 1].m_asm, 1);
-			}
-			for (unsigned i = 1; i < code.size(); ++i)
-				m_asm.append(it->second);
-		}
-		else if (c_binary.count(us))
-		{
-			auto it = c_binary.find(us);
-			requireSize(2);
-			requireDeposit(0, 1);
-			requireDeposit(1, 1);
-			m_asm.append(code[1].m_asm, 1);
-			m_asm.append(code[0].m_asm, 1);
-			m_asm.append(it->second.first);
-			if (it->second.second)
-				m_asm.append(Instruction::ISZERO);
-		}
-		else if (c_unary.count(us))
-		{
-			auto it = c_unary.find(us);
-			requireSize(1);
-			requireDeposit(0, 1);
-			m_asm.append(code[0].m_asm, 1);
-			m_asm.append(it->second);
-		}
-		else if (us == "IF")
-		{
-			requireSize(3);
-			requireDeposit(0, 1);
-			int minDep = min(code[1].m_asm.deposit(), code[2].m_asm.deposit());
-
-			m_asm.append(code[0].m_asm);
-			auto pos = m_asm.appendJumpI();
-			m_asm.onePath();
-			m_asm.append(code[2].m_asm, minDep);
-			auto end = m_asm.appendJump();
-			m_asm.otherPath();
-			m_asm << pos.tag();
-			m_asm.append(code[1].m_asm, minDep);
-			m_asm << end.tag();
-			m_asm.donePaths();
-		}
-		else if (us == "WHEN" || us == "UNLESS")
-		{
-			requireSize(2);
-			requireDeposit(0, 1);
-
-			m_asm.append(code[0].m_asm);
-			if (us == "WHEN")
-				m_asm.append(Instruction::ISZERO);
-			auto end = m_asm.appendJumpI();
-			m_asm.onePath();
-			m_asm.otherPath();
-			m_asm.append(code[1].m_asm, 0);
-			m_asm << end.tag();
-			m_asm.donePaths();
-		}
-		else if (us == "WHILE")
-		{
-			requireSize(2);
-			requireDeposit(0, 1);
-
-			auto begin = m_asm.append();
-			m_asm.append(code[0].m_asm);
-			m_asm.append(Instruction::ISZERO);
-			auto end = m_asm.appendJumpI();
-			m_asm.append(code[1].m_asm, 0);
-			m_asm.appendJump(begin);
-			m_asm << end.tag();
-		}
-		else if (us == "FOR")
-		{
-			requireSize(4);
-			requireDeposit(1, 1);
-
-			m_asm.append(code[0].m_asm, 0);
-			auto begin = m_asm.append();
-			m_asm.append(code[1].m_asm);
-			m_asm.append(Instruction::ISZERO);
-			auto end = m_asm.appendJumpI();
-			m_asm.append(code[3].m_asm, 0);
-			m_asm.append(code[2].m_asm, 0);
-			m_asm.appendJump(begin);
-			m_asm << end.tag();
-		}
-		else if (us == "ALLOC")
-		{
-			requireSize(1);
-			requireDeposit(0, 1);
-
-			m_asm.append(Instruction::MSIZE);
-			m_asm.append(u256(0));
-			m_asm.append(u256(1));
-			m_asm.append(code[0].m_asm, 1);
-			m_asm.append(Instruction::MSIZE);
-			m_asm.append(Instruction::ADD);
-			m_asm.append(Instruction::SUB);
-			m_asm.append(Instruction::MSTORE8);
-
-			_s.usedAlloc = true;
-		}
-		else if (us == "LLL")
-		{
-			requireMinSize(2);
-			requireMaxSize(3);
-			requireDeposit(1, 1);
-
-			auto subPush = m_asm.appendSubSize(code[0].assembly(ns));
-			m_asm.append(Instruction::DUP1);
-			if (code.size() == 3)
-			{
-				requireDeposit(2, 1);
-				m_asm.append(code[2].m_asm, 1);
-				m_asm.append(Instruction::LT);
-				m_asm.append(Instruction::ISZERO);
-				m_asm.append(Instruction::MUL);
-				m_asm.append(Instruction::DUP1);
-			}
-			m_asm.append(subPush);
-			m_asm.append(code[1].m_asm, 1);
-			m_asm.append(Instruction::CODECOPY);
-		}
-		else if (us == "&&" || us == "||")
-		{
-			requireMinSize(1);
-			for (unsigned i = 0; i < code.size(); ++i)
-				requireDeposit(i, 1);
-
-			auto end = m_asm.newTag();
-			if (code.size() > 1)
-			{
-				m_asm.append((u256)(us == "||" ? 1 : 0));
-				for (unsigned i = 1; i < code.size(); ++i)
-				{
-					// Check if true - predicate
-					m_asm.append(code[i - 1].m_asm, 1);
-					if (us == "&&")
-						m_asm.append(Instruction::ISZERO);
-					m_asm.appendJumpI(end);
-				}
-				m_asm.append(Instruction::POP);
-			}
-
-			// Check if true - predicate
-			m_asm.append(code.back().m_asm, 1);
-
-			// At end now.
-			m_asm.append(end);
-		}
-		else if (us == "~")
-		{
-			requireSize(1);
-			requireDeposit(0, 1);
-
-			m_asm.append(code[0].m_asm, 1);
-			m_asm.append((u256)1);
-			m_asm.append((u256)0);
-			m_asm.append(Instruction::SUB);
-			m_asm.append(Instruction::SUB);
-		}
-		else if (us == "SEQ")
-		{
-			unsigned ii = 0;
-			for (auto const& i: code)
-				if (++ii < code.size())
-					m_asm.append(i.m_asm, 0);
-				else
-					m_asm.append(i.m_asm);
-		}
-		else if (us == "RAW")
-		{
-			for (auto const& i: code)
-				m_asm.append(i.m_asm);
-			m_asm.popTo(1);
-		}
-		else if (us.find_first_of("1234567890") != 0 && us.find_first_not_of("QWERTYUIOPASDFGHJKLZXCVBNM1234567890_") == string::npos)
-			m_asm.append((u256)varAddress(s));
-		else
-			error<InvalidOperation>();
-	}
-}
-
-CodeFragment CodeFragment::compile(string const& _src, CompilerState& _s)
-{
-	CodeFragment ret;
-	sp::utree o;
-	parseTreeLLL(_src, o);
-	if (!o.empty())
-		ret = CodeFragment(o, _s);
-	_s.treesToKill.push_back(o);
-	return ret;
-}
diff --git a/CodeFragment.h b/CodeFragment.h
deleted file mode 100644
index 554f90b4..00000000
--- a/CodeFragment.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file CodeFragment.h
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#pragma once
-
-#include <libdevcore/Common.h>
-#include <libevmcore/Instruction.h>
-#include <libevmcore/Assembly.h>
-#include "Exceptions.h"
-
-namespace boost { namespace spirit { class utree; } }
-namespace sp = boost::spirit;
-
-namespace dev
-{
-namespace eth
-{
-
-struct CompilerState;
-
-class CodeFragment
-{
-public:
-	CodeFragment() {}
-	CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowASM = false);
-
-	static CodeFragment compile(std::string const& _src, CompilerState& _s);
-
-	/// Consolidates data and compiles code.
-	Assembly& assembly(CompilerState const& _cs) { finalise(_cs); return m_asm; }
-
-private:
-	void finalise(CompilerState const& _cs);
-
-	template <class T> void error() const { BOOST_THROW_EXCEPTION(T() ); }
-	void constructOperation(sp::utree const& _t, CompilerState& _s);
-
-	bool m_finalised = false;
-	Assembly m_asm;
-};
-
-static const CodeFragment NullCodeFragment;
-
-}
-}
-
diff --git a/Compiler.cpp b/Compiler.cpp
deleted file mode 100644
index 37fb3c34..00000000
--- a/Compiler.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file Compiler.cpp
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#include "Compiler.h"
-#include "Parser.h"
-#include "CompilerState.h"
-#include "CodeFragment.h"
-
-using namespace std;
-using namespace dev;
-using namespace dev::eth;
-
-bytes dev::eth::compileLLL(string const& _src, bool _opt, vector<string>* _errors)
-{
-	try
-	{
-		CompilerState cs;
-		cs.populateStandard();
-		auto f = CodeFragment::compile(_src, cs);
-		bytes ret = f.assembly(cs).optimise(_opt).assemble();
-		for (auto i: cs.treesToKill)
-			killBigints(i);
-		return ret;
-	}
-	catch (Exception const& _e)
-	{
-		if (_errors)
-		{
-			_errors->push_back("Parse error.");
-			_errors->push_back(diagnostic_information(_e));
-		}
-	}
-	catch (std::exception)
-	{
-		if (_errors)
-			_errors->push_back("Parse error.");
-	}
-	return bytes();
-}
-
-std::string dev::eth::compileLLLToAsm(std::string const& _src, bool _opt, std::vector<std::string>* _errors)
-{
-	try
-	{
-		CompilerState cs;
-		cs.populateStandard();
-		string ret = CodeFragment::compile(_src, cs).assembly(cs).optimise(_opt).out();
-		for (auto i: cs.treesToKill)
-			killBigints(i);
-		return ret;
-	}
-	catch (Exception const& _e)
-	{
-		if (_errors)
-			_errors->push_back(diagnostic_information(_e));
-	}
-	catch (std::exception)
-	{
-		if (_errors)
-			_errors->push_back("Parse error.");
-	}
-	return string();
-}
-
-string dev::eth::parseLLL(string const& _src)
-{
-	sp::utree o;
-	try
-	{
-		parseTreeLLL(_src, o);
-	}
-	catch (...) {}
-	ostringstream ret;
-	debugOutAST(ret, o);
-	killBigints(o);
-	return ret.str();
-}
diff --git a/Compiler.h b/Compiler.h
deleted file mode 100644
index 0fadd278..00000000
--- a/Compiler.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file Compiler.h
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#pragma once
-
-#include <string>
-#include <vector>
-#include <libdevcore/Common.h>
-
-namespace dev
-{
-namespace eth
-{
-
-std::string parseLLL(std::string const& _src);
-std::string compileLLLToAsm(std::string const& _src, bool _opt = true, std::vector<std::string>* _errors = nullptr);
-bytes compileLLL(std::string const& _src, bool _opt = true, std::vector<std::string>* _errors = nullptr);
-
-}
-}
diff --git a/CompilerState.cpp b/CompilerState.cpp
deleted file mode 100644
index 63351bc4..00000000
--- a/CompilerState.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file CompilerState.cpp
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#include "CompilerState.h"
-#include "CodeFragment.h"
-
-using namespace std;
-using namespace dev;
-using namespace dev::eth;
-
-CompilerState::CompilerState()
-{
-}
-
-CodeFragment const& CompilerState::getDef(std::string const& _s)
-{
-	if (defs.count(_s))
-		return defs.at(_s);
-	else if (args.count(_s))
-		return args.at(_s);
-	else if (outers.count(_s))
-		return outers.at(_s);
-	else
-		return NullCodeFragment;
-}
-
-void CompilerState::populateStandard()
-{
-	static const string s = "{"
-	"(def 'gav 0x51ba59315b3a95761d0863b05ccc7a7f54703d99)"
-	"(def 'config 0x661005d2720d855f1d9976f88bb10c1a3398c77f)"
-	"(def 'allgas (- (gas) 21))"
-	"(def 'send (to value) (call allgas to value 0 0 0 0))"
-	"(def 'send (gaslimit to value) (call gaslimit to value 0 0 0 0))"
-	"(def 'msg (gaslimit to value data datasize outsize) { (set x outsize) (set y (alloc @32)) (call gaslimit to value data datasize @0 @32) @0 })"
-	"(def 'msg (gaslimit to value data datasize) { (call gaslimit to value data datasize 0 32) @0 })"
-	"(def 'msg (gaslimit to value data) { [0]:data (msg gaslimit to value 0 32) })"
-	"(def 'msg (to value data) { [0]:data (msg allgas to value 0 32) })"
-	"(def 'msg (to data) { [0]:data (msg allgas to 0 0 32) })"
-	"(def 'create (value code) { [0]:(msize) (create value @0 (lll code @0)) })"
-	"(def 'create (code) { [0]:(msize) (create 0 @0 (lll code @0)) })"
-	"(def 'sha3 (val) { [0]:val (sha3 0 32) })"
-	"(def 'sha3pair (a b) { [0]:a [32]:b (sha3 0 64) })"
-	"(def 'sha3trip (a b c) { [0]:a [32]:b [64]:c (sha3 0 96) })"
-	"(def 'return (val) { [0]:val (return 0 32) })"
-	"(def 'returnlll (code) (return 0 (lll code 0)) )"
-	"(def 'makeperm (name pos) { (def name (sload pos)) (def name (v) (sstore pos v)) } )"
-	"(def 'permcount 0)"
-	"(def 'perm (name) { (makeperm name permcount) (def 'permcount (+ permcount 1)) } )"
-	"(def 'namereg (msg config 0))"
-	"(def 'coinreg (msg config 1))"
-	"(def 'gavcoin (msg config 2))"
-	"(def 'sendgavcoin (to value) { [32]'send [64]:to [96]:value (call allgas gavcoin 0 32 96 0 0) })"
-	"(def 'regname (name) { [32]'register [64]name (call allgas namereg 0 32 64 0 0) })"
-	"(def 'regcoin (name) { [32]name (call allgas coinreg 0 32 32 0 0) })"
-	"(def 'regcoin (name denom) { [32]name [64]denom (call allgas coinreg 0 32 64 0 0) })"
-	"(def 'ecrecover (r s v hash) { [0] r [32] s [64] v [96] hash (msg allgas 1 0 0 128) })"
-	"(def 'sha256 (data datasize) (msg allgas 2 0 data datasize))"
-	"(def 'ripemd160 (data datasize) (msg allgas 3 0 data datasize))"
-	"(def 'sha256 (val) { [0]:val (sha256 0 32) })"
-	"(def 'ripemd160 (val) { [0]:val (ripemd160 0 32) })"
-	"}";
-	CodeFragment::compile(s, *this);
-}
diff --git a/CompilerState.h b/CompilerState.h
deleted file mode 100644
index bfe56f92..00000000
--- a/CompilerState.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file CompilerState.h
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#pragma once
-
-#include <boost/spirit/include/support_utree.hpp>
-#include "CodeFragment.h"
-
-namespace dev
-{
-namespace eth
-{
-
-struct Macro
-{
-	std::vector<std::string> args;
-	boost::spirit::utree code;
-	std::map<std::string, CodeFragment> env;
-};
-
-struct CompilerState
-{
-	CompilerState();
-
-	CodeFragment const& getDef(std::string const& _s);
-	void populateStandard();
-
-	unsigned stackSize = 128;
-	std::map<std::string, std::pair<unsigned, unsigned>> vars;       ///< maps name to stack offset & size.
-	std::map<std::string, CodeFragment> defs;
-	std::map<std::string, CodeFragment> args;
-	std::map<std::string, CodeFragment> outers;
-	std::map<std::pair<std::string, unsigned>, Macro> macros;
-	std::vector<boost::spirit::utree> treesToKill;
-	bool usedAlloc = false;
-};
-
-}
-}
diff --git a/Exceptions.h b/Exceptions.h
deleted file mode 100644
index 1e9671b3..00000000
--- a/Exceptions.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file Exceptions.h
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#pragma once
-
-#include <libdevcore/Exceptions.h>
-
-namespace dev
-{
-namespace eth
-{
-
-/// Compile a Low-level Lisp-like Language program into EVM-code.
-class CompilerException: public dev::Exception {};
-class InvalidOperation: public CompilerException {};
-class IntegerOutOfRange: public CompilerException {};
-class EmptyList: public CompilerException {};
-class DataNotExecutable: public CompilerException {};
-class IncorrectParameterCount: public CompilerException {};
-class InvalidName: public CompilerException {};
-class InvalidMacroArgs: public CompilerException {};
-class InvalidLiteral: public CompilerException {};
-class BareSymbol: public CompilerException {};
-
-}
-}
diff --git a/Parser.cpp b/Parser.cpp
deleted file mode 100644
index df30f389..00000000
--- a/Parser.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file Parser.cpp
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#include "Parser.h"
-
-#define BOOST_RESULT_OF_USE_DECLTYPE
-#define BOOST_SPIRIT_USE_PHOENIX_V3
-#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/phoenix.hpp>
-#include <boost/spirit/include/support_utree.hpp>
-
-using namespace std;
-using namespace dev;
-using namespace dev::eth;
-namespace qi = boost::spirit::qi;
-namespace px = boost::phoenix;
-namespace sp = boost::spirit;
-
-void dev::eth::killBigints(sp::utree const& _this)
-{
-	switch (_this.which())
-	{
-	case sp::utree_type::list_type: for (auto const& i: _this) killBigints(i); break;
-	case sp::utree_type::any_type: delete _this.get<bigint*>(); break;
-	default:;
-	}
-}
-
-void dev::eth::debugOutAST(ostream& _out, sp::utree const& _this)
-{
-	switch (_this.which())
-	{
-	case sp::utree_type::list_type:
-		switch (_this.tag())
-		{
-		case 0: _out << "( "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << ")"; break;
-		case 1: _out << "@ "; debugOutAST(_out, _this.front()); break;
-		case 2: _out << "@@ "; debugOutAST(_out, _this.front()); break;
-		case 3: _out << "[ "; debugOutAST(_out, _this.front()); _out << " ] "; debugOutAST(_out, _this.back()); break;
-		case 4: _out << "[[ "; debugOutAST(_out, _this.front()); _out << " ]] "; debugOutAST(_out, _this.back()); break;
-		case 5: _out << "{ "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << "}"; break;
-		case 6: _out << "$ "; debugOutAST(_out, _this.front()); break;
-		default:;
-		}
-
-		break;
-	case sp::utree_type::int_type: _out << _this.get<int>(); break;
-	case sp::utree_type::string_type: _out << "\"" << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>() << "\""; break;
-	case sp::utree_type::symbol_type: _out << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>(); break;
-	case sp::utree_type::any_type: _out << *_this.get<bigint*>(); break;
-	default: _out << "nil";
-	}
-}
-
-namespace dev { namespace eth {
-namespace parseTreeLLL_ {
-
-template<unsigned N>
-struct tagNode
-{
-	void operator()(sp::utree& n, qi::rule<string::const_iterator, qi::ascii::space_type, sp::utree()>::context_type& c) const
-	{
-		(boost::fusion::at_c<0>(c.attributes) = n).tag(N);
-	}
-};
-
-}}}
-
-void dev::eth::parseTreeLLL(string const& _s, sp::utree& o_out)
-{
-	using qi::standard::space;
-	using qi::standard::space_type;
-	using dev::eth::parseTreeLLL_::tagNode;
-	using symbol_type = sp::basic_string<std::string, sp::utree_type::symbol_type>;
-	using it = string::const_iterator;
-
-	static const u256 ether = u256(1000000000) * 1000000000;
-	static const u256 finney = u256(1000000000) * 1000000;
-	static const u256 szabo = u256(1000000000) * 1000;
-
-	qi::rule<it, space_type, sp::utree()> element;
-	qi::rule<it, string()> str = '"' > qi::lexeme[+(~qi::char_(std::string("\"") + '\0'))] > '"';
-	qi::rule<it, string()> strsh = '\'' > qi::lexeme[+(~qi::char_(std::string(" ;$@()[]{}:\n\t") + '\0'))];
-	qi::rule<it, symbol_type()> symbol = qi::lexeme[+(~qi::char_(std::string(" $@[]{}:();\"\x01-\x1f\x7f") + '\0'))];
-	qi::rule<it, string()> intstr = qi::lexeme[ qi::no_case["0x"][qi::_val = "0x"] >> *qi::char_("0-9a-fA-F")[qi::_val += qi::_1]] | qi::lexeme[+qi::char_("0-9")[qi::_val += qi::_1]];
-	qi::rule<it, bigint()> integer = intstr;
-	qi::rule<it, bigint()> multiplier = qi::lit("wei")[qi::_val = 1] | qi::lit("szabo")[qi::_val = szabo] | qi::lit("finney")[qi::_val = finney] | qi::lit("ether")[qi::_val = ether];
-	qi::rule<it, space_type, bigint()> quantity = integer[qi::_val = qi::_1] >> -multiplier[qi::_val *= qi::_1];
-	qi::rule<it, space_type, sp::utree()> atom = quantity[qi::_val = px::construct<sp::any_ptr>(px::new_<bigint>(qi::_1))] | (str | strsh)[qi::_val = qi::_1] | symbol[qi::_val = qi::_1];
-	qi::rule<it, space_type, sp::utree::list_type()> seq = '{' > *element > '}';
-	qi::rule<it, space_type, sp::utree::list_type()> mload = '@' > element;
-	qi::rule<it, space_type, sp::utree::list_type()> sload = qi::lit("@@") > element;
-	qi::rule<it, space_type, sp::utree::list_type()> mstore = '[' > element > ']' > -qi::lit(":") > element;
-	qi::rule<it, space_type, sp::utree::list_type()> sstore = qi::lit("[[") > element > qi::lit("]]") > -qi::lit(":") > element;
-	qi::rule<it, space_type, sp::utree::list_type()> calldataload = qi::lit("$") > element;
-	qi::rule<it, space_type, sp::utree::list_type()> list = '(' > *element > ')';
-
-	qi::rule<it, space_type, sp::utree()> extra = sload[tagNode<2>()] | mload[tagNode<1>()] | sstore[tagNode<4>()] | mstore[tagNode<3>()] | seq[tagNode<5>()] | calldataload[tagNode<6>()];
-	element = atom | list | extra;
-
-	string s;
-	s.reserve(_s.size());
-	bool incomment = false;
-	bool instring = false;
-	bool insstring = false;
-	for (auto i: _s)
-	{
-		if (i == ';' && !instring && !insstring)
-			incomment = true;
-		else if (i == '\n')
-			incomment = instring = insstring = false;
-		else if (i == '"' && !insstring)
-			instring = !instring;
-		else if (i == '\'')
-			insstring = true;
-		else if (i == ' ')
-			insstring = false;
-		if (!incomment)
-			s.push_back(i);
-	}
-	auto ret = s.cbegin();
-	qi::phrase_parse(ret, s.cend(), element, space, qi::skip_flag::dont_postskip, o_out);
-	for (auto i = ret; i != s.cend(); ++i)
-		if (!isspace(*i))
-			BOOST_THROW_EXCEPTION(std::exception());
-}
-
diff --git a/Parser.h b/Parser.h
deleted file mode 100644
index b21989f0..00000000
--- a/Parser.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file Parser.h
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#pragma once
-
-#include <string>
-#include <vector>
-#include <libdevcore/Common.h>
-
-namespace boost { namespace spirit { class utree; } }
-namespace sp = boost::spirit;
-
-namespace dev
-{
-namespace eth
-{
-
-void killBigints(sp::utree const& _this);
-void parseTreeLLL(std::string const& _s, sp::utree& o_out);
-void debugOutAST(std::ostream& _out, sp::utree const& _this);
-
-}
-}
-- 
cgit v1.2.3


From 62ec556a9d2b308648b089cfbad810cbb50a16b9 Mon Sep 17 00:00:00 2001
From: jhuntley <jhuntley@houghtonassociates.com>
Date: Fri, 16 Jan 2015 16:37:20 -0500
Subject: Mingw cmake updates. Make sure Boost_INCLUDE_DIRS is included for
 each library using boost. When installing libraries, don't forget to copy
 DLLs, add target 'RUNTIME DESTINATION bin'.

---
 CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3b9dc603..e60522a7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -27,6 +27,6 @@ endif()
 target_link_libraries(${EXECUTABLE} evmcore)
 target_link_libraries(${EXECUTABLE} devcore)
 
-install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
+install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
 install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )
 
-- 
cgit v1.2.3


From d99247cb5dd34d49e23f09cd78a9618cfafab466 Mon Sep 17 00:00:00 2001
From: Liana Husikyan <liana@ethdev.com>
Date: Fri, 17 Apr 2015 16:15:25 +0200
Subject: reordered output

Conflicts:
	libevmcore/Assembly.cpp
---
 CMakeLists.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e60522a7..b865d4af 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,6 +11,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
 
 aux_source_directory(. SRC_LIST)
 
+include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS})
 include_directories(BEFORE ..)
 include_directories(${Boost_INCLUDE_DIRS})
 
-- 
cgit v1.2.3


From ed096881b97222357ac636b41eb21e20225beaf1 Mon Sep 17 00:00:00 2001
From: chriseth <c@ethdev.com>
Date: Wed, 22 Apr 2015 11:30:33 +0200
Subject: Use BUILD_SHARED_LIB

---
 CMakeLists.txt | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b865d4af..d3f465f3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,11 +19,7 @@ set(EXECUTABLE lll)
 
 file(GLOB HEADERS "*.h")
 
-if(ETH_STATIC)
-	add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS})
-else()
-	add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS})
-endif()
+add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
 
 target_link_libraries(${EXECUTABLE} evmcore)
 target_link_libraries(${EXECUTABLE} devcore)
-- 
cgit v1.2.3


From 3ec162e910c34f049332d487d9f07674a42c40aa Mon Sep 17 00:00:00 2001
From: chriseth <c@ethdev.com>
Date: Fri, 24 Apr 2015 17:35:16 +0200
Subject: Move assembly related files to libevmasm and Params.h/.cpp to
 libevmcore.

---
 CMakeLists.txt | 3 +--
 CodeFragment.h | 2 +-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index d3f465f3..66f32e4d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,8 +21,7 @@ file(GLOB HEADERS "*.h")
 
 add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
 
-target_link_libraries(${EXECUTABLE} evmcore)
-target_link_libraries(${EXECUTABLE} devcore)
+target_link_libraries(${EXECUTABLE} evmasm)
 
 install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
 install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )
diff --git a/CodeFragment.h b/CodeFragment.h
index 554f90b4..03f812b6 100644
--- a/CodeFragment.h
+++ b/CodeFragment.h
@@ -23,7 +23,7 @@
 
 #include <libdevcore/Common.h>
 #include <libevmcore/Instruction.h>
-#include <libevmcore/Assembly.h>
+#include <libevmasm/Assembly.h>
 #include "Exceptions.h"
 
 namespace boost { namespace spirit { class utree; } }
-- 
cgit v1.2.3


From e3597bf21368af07225d7d427105f72b3b19b364 Mon Sep 17 00:00:00 2001
From: chriseth <c@ethdev.com>
Date: Tue, 16 Jun 2015 14:58:03 +0200
Subject: Some changes in libdevcore.

---
 CodeFragment.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index 1e776643..b50e316d 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -196,7 +196,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
 		{
 			if (_t.size() != 2)
 				error<IncorrectParameterCount>();
-			m_asm.append(CodeFragment::compile(asString(contents(firstAsString())), _s).m_asm);
+			m_asm.append(CodeFragment::compile(contentsString(firstAsString()), _s).m_asm);
 		}
 		else if (us == "SET")
 		{
-- 
cgit v1.2.3


From d512c8639cd8cd0e8781bf3bda7a0a1ef4fac5bf Mon Sep 17 00:00:00 2001
From: debris <marek.kotewicz@gmail.com>
Date: Wed, 5 Aug 2015 11:35:05 +0200
Subject: fixed cmake policy CMP0042, MACOSX RPATH

---
 CMakeLists.txt | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 66f32e4d..21fc18f9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,10 +1,4 @@
 cmake_policy(SET CMP0015 NEW)
-# this policy was introduced in cmake 3.0
-# remove if, once 3.0 will be used on unix
-if (${CMAKE_MAJOR_VERSION} GREATER 2)
-	# old policy do not use MACOSX_RPATH
-	cmake_policy(SET CMP0042 OLD)
-endif()
 set(CMAKE_AUTOMOC OFF)
 
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
-- 
cgit v1.2.3


From 876f54694aa2ec98eb17e2d0d96a59e55f0d0ad9 Mon Sep 17 00:00:00 2001
From: Gav Wood <g@ethdev.com>
Date: Wed, 5 Aug 2015 17:57:22 +0200
Subject: Revert "fixed cmake policy CMP0042, MACOSX RPATH"

---
 CMakeLists.txt | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 21fc18f9..66f32e4d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,10 @@
 cmake_policy(SET CMP0015 NEW)
+# this policy was introduced in cmake 3.0
+# remove if, once 3.0 will be used on unix
+if (${CMAKE_MAJOR_VERSION} GREATER 2)
+	# old policy do not use MACOSX_RPATH
+	cmake_policy(SET CMP0042 OLD)
+endif()
 set(CMAKE_AUTOMOC OFF)
 
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
-- 
cgit v1.2.3


From cbe7593460312f364b3677ecff2d71ef901c4648 Mon Sep 17 00:00:00 2001
From: debris <marek.kotewicz@gmail.com>
Date: Wed, 5 Aug 2015 23:48:19 +0200
Subject: now policy CMP0042 is set to OLD

This reverts commit 61e99b1040b80685c70c57cfb23f92e898cd41fb.
---
 CMakeLists.txt | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 66f32e4d..21fc18f9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,10 +1,4 @@
 cmake_policy(SET CMP0015 NEW)
-# this policy was introduced in cmake 3.0
-# remove if, once 3.0 will be used on unix
-if (${CMAKE_MAJOR_VERSION} GREATER 2)
-	# old policy do not use MACOSX_RPATH
-	cmake_policy(SET CMP0042 OLD)
-endif()
 set(CMAKE_AUTOMOC OFF)
 
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
-- 
cgit v1.2.3


From 6945c2eb898da72e434378bfa983b2875e8d94a7 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin.wood@ethereum.org>
Date: Thu, 6 Aug 2015 21:00:29 +0200
Subject: Warning fix.

---
 CodeFragment.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/CodeFragment.cpp b/CodeFragment.cpp
index b50e316d..64680d5a 100644
--- a/CodeFragment.cpp
+++ b/CodeFragment.cpp
@@ -22,7 +22,12 @@
 #include "CodeFragment.h"
 
 #include <boost/algorithm/string.hpp>
+#pragma warning(push)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
 #include <boost/spirit/include/support_utree.hpp>
+#pragma warning(pop)
+#pragma GCC diagnostic pop
 #include <libdevcore/Log.h>
 #include <libdevcore/CommonIO.h>
 #include <libevmcore/Instruction.h>
-- 
cgit v1.2.3


From f47ca4ad14dce9a1d7c576d410aca0750c171f11 Mon Sep 17 00:00:00 2001
From: debris <marek.kotewicz@gmail.com>
Date: Thu, 27 Aug 2015 12:19:33 +0200
Subject: cmake refactor in progress

---
 CMakeLists.txt | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 21fc18f9..0b468d7a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,9 +5,9 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
 
 aux_source_directory(. SRC_LIST)
 
-include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS})
+#include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS})
 include_directories(BEFORE ..)
-include_directories(${Boost_INCLUDE_DIRS})
+#include_directories(${Boost_INCLUDE_DIRS})
 
 set(EXECUTABLE lll)
 
@@ -15,7 +15,8 @@ file(GLOB HEADERS "*.h")
 
 add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
 
-target_link_libraries(${EXECUTABLE} evmasm)
+eth_use(${EXECUTABLE} REQUIRED Eth::evmasm)
+#target_link_libraries(${EXECUTABLE} evmasm)
 
 install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
 install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )
-- 
cgit v1.2.3


From f9447147466178e2ae5aa6507d91b8ff4b5d923f Mon Sep 17 00:00:00 2001
From: chriseth <c@ethdev.com>
Date: Thu, 10 Sep 2015 12:02:18 +0200
Subject: Transition from bytecode to more general linker objects.

---
 Compiler.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Compiler.cpp b/Compiler.cpp
index 37fb3c34..f1538789 100644
--- a/Compiler.cpp
+++ b/Compiler.cpp
@@ -35,7 +35,7 @@ bytes dev::eth::compileLLL(string const& _src, bool _opt, vector<string>* _error
 		CompilerState cs;
 		cs.populateStandard();
 		auto f = CodeFragment::compile(_src, cs);
-		bytes ret = f.assembly(cs).optimise(_opt).assemble();
+		bytes ret = f.assembly(cs).optimise(_opt).assemble().bytecode;
 		for (auto i: cs.treesToKill)
 			killBigints(i);
 		return ret;
-- 
cgit v1.2.3


From e95dd9203ac17a65bb5c08c57237717d29b7b158 Mon Sep 17 00:00:00 2001
From: Dimitry <winsvega@mail.ru>
Date: Mon, 21 Mar 2016 14:58:34 +0300
Subject: move liblll

---
 All.h                    |   6 -
 CMakeLists.txt           |  23 --
 CodeFragment.cpp         | 586 -----------------------------------------------
 CodeFragment.h           |  64 ------
 Compiler.cpp             |  95 --------
 Compiler.h               |  38 ---
 CompilerState.cpp        |  82 -------
 CompilerState.h          |  57 -----
 Exceptions.h             |  44 ----
 Parser.cpp               | 145 ------------
 Parser.h                 |  41 ----
 liblll/All.h             |   6 +
 liblll/CMakeLists.txt    |  23 ++
 liblll/CodeFragment.cpp  | 586 +++++++++++++++++++++++++++++++++++++++++++++++
 liblll/CodeFragment.h    |  64 ++++++
 liblll/Compiler.cpp      |  95 ++++++++
 liblll/Compiler.h        |  38 +++
 liblll/CompilerState.cpp |  82 +++++++
 liblll/CompilerState.h   |  57 +++++
 liblll/Exceptions.h      |  44 ++++
 liblll/Parser.cpp        | 145 ++++++++++++
 liblll/Parser.h          |  41 ++++
 22 files changed, 1181 insertions(+), 1181 deletions(-)
 delete mode 100644 All.h
 delete mode 100644 CMakeLists.txt
 delete mode 100644 CodeFragment.cpp
 delete mode 100644 CodeFragment.h
 delete mode 100644 Compiler.cpp
 delete mode 100644 Compiler.h
 delete mode 100644 CompilerState.cpp
 delete mode 100644 CompilerState.h
 delete mode 100644 Exceptions.h
 delete mode 100644 Parser.cpp
 delete mode 100644 Parser.h
 create mode 100644 liblll/All.h
 create mode 100644 liblll/CMakeLists.txt
 create mode 100644 liblll/CodeFragment.cpp
 create mode 100644 liblll/CodeFragment.h
 create mode 100644 liblll/Compiler.cpp
 create mode 100644 liblll/Compiler.h
 create mode 100644 liblll/CompilerState.cpp
 create mode 100644 liblll/CompilerState.h
 create mode 100644 liblll/Exceptions.h
 create mode 100644 liblll/Parser.cpp
 create mode 100644 liblll/Parser.h

diff --git a/All.h b/All.h
deleted file mode 100644
index 7c4192f6..00000000
--- a/All.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-
-#include "CodeFragment.h"
-#include "Compiler.h"
-#include "CompilerState.h"
-#include "Parser.h"
diff --git a/CMakeLists.txt b/CMakeLists.txt
deleted file mode 100644
index 0b468d7a..00000000
--- a/CMakeLists.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-cmake_policy(SET CMP0015 NEW)
-set(CMAKE_AUTOMOC OFF)
-
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
-
-aux_source_directory(. SRC_LIST)
-
-#include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS})
-include_directories(BEFORE ..)
-#include_directories(${Boost_INCLUDE_DIRS})
-
-set(EXECUTABLE lll)
-
-file(GLOB HEADERS "*.h")
-
-add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
-
-eth_use(${EXECUTABLE} REQUIRED Eth::evmasm)
-#target_link_libraries(${EXECUTABLE} evmasm)
-
-install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
-install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )
-
diff --git a/CodeFragment.cpp b/CodeFragment.cpp
deleted file mode 100644
index 64680d5a..00000000
--- a/CodeFragment.cpp
+++ /dev/null
@@ -1,586 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file CodeFragment.cpp
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#include "CodeFragment.h"
-
-#include <boost/algorithm/string.hpp>
-#pragma warning(push)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#include <boost/spirit/include/support_utree.hpp>
-#pragma warning(pop)
-#pragma GCC diagnostic pop
-#include <libdevcore/Log.h>
-#include <libdevcore/CommonIO.h>
-#include <libevmcore/Instruction.h>
-#include "CompilerState.h"
-#include "Parser.h"
-using namespace std;
-using namespace dev;
-using namespace dev::eth;
-namespace qi = boost::spirit::qi;
-namespace px = boost::phoenix;
-namespace sp = boost::spirit;
-
-void CodeFragment::finalise(CompilerState const& _cs)
-{
-	if (_cs.usedAlloc && _cs.vars.size() && !m_finalised)
-	{
-		m_finalised = true;
-		m_asm.injectStart(Instruction::MSTORE8);
-		m_asm.injectStart((u256)((_cs.vars.size() + 2) * 32) - 1);
-		m_asm.injectStart((u256)1);
-	}
-}
-
-CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowASM)
-{
-/*	cdebug << "CodeFragment. Locals:";
-	for (auto const& i: _s.defs)
-		cdebug << i.first << ":" << toHex(i.second.m_code);
-	cdebug << "Args:";
-	for (auto const& i: _s.args)
-		cdebug << i.first << ":" << toHex(i.second.m_code);
-	cdebug << "Outers:";
-	for (auto const& i: _s.outers)
-		cdebug << i.first << ":" << toHex(i.second.m_code);
-	debugOutAST(cout, _t);
-	cout << endl << flush;
-*/
-	switch (_t.which())
-	{
-	case sp::utree_type::list_type:
-		constructOperation(_t, _s);
-		break;
-	case sp::utree_type::string_type:
-	{
-		auto sr = _t.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
-		string s(sr.begin(), sr.end());
-		m_asm.append(s);
-		break;
-	}
-	case sp::utree_type::symbol_type:
-	{
-		auto sr = _t.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
-		string s(sr.begin(), sr.end());
-		string us = boost::algorithm::to_upper_copy(s);
-		if (_allowASM && c_instructions.count(us))
-			m_asm.append(c_instructions.at(us));
-		else if (_s.defs.count(s))
-			m_asm.append(_s.defs.at(s).m_asm);
-		else if (_s.args.count(s))
-			m_asm.append(_s.args.at(s).m_asm);
-		else if (_s.outers.count(s))
-			m_asm.append(_s.outers.at(s).m_asm);
-		else if (us.find_first_of("1234567890") != 0 && us.find_first_not_of("QWERTYUIOPASDFGHJKLZXCVBNM1234567890_") == string::npos)
-		{
-			auto it = _s.vars.find(s);
-			if (it == _s.vars.end())
-			{
-				bool ok;
-				tie(it, ok) = _s.vars.insert(make_pair(s, make_pair(_s.stackSize, 32)));
-				_s.stackSize += 32;
-			}
-			m_asm.append((u256)it->second.first);
-		}
-		else
-			error<BareSymbol>();
-
-		break;
-	}
-	case sp::utree_type::any_type:
-	{
-		bigint i = *_t.get<bigint*>();
-		if (i < 0 || i > bigint(u256(0) - 1))
-			error<IntegerOutOfRange>();
-		m_asm.append((u256)i);
-		break;
-	}
-	default: break;
-	}
-}
-
-void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
-{
-	if (_t.tag() == 0 && _t.empty())
-		error<EmptyList>();
-	else if (_t.tag() == 0 && _t.front().which() != sp::utree_type::symbol_type)
-		error<DataNotExecutable>();
-	else
-	{
-		string s;
-		string us;
-		switch (_t.tag())
-		{
-		case 0:
-		{
-			auto sr = _t.front().get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
-			s = string(sr.begin(), sr.end());
-			us = boost::algorithm::to_upper_copy(s);
-			break;
-		}
-		case 1:
-			us = "MLOAD";
-			break;
-		case 2:
-			us = "SLOAD";
-			break;
-		case 3:
-			us = "MSTORE";
-			break;
-		case 4:
-			us = "SSTORE";
-			break;
-		case 5:
-			us = "SEQ";
-			break;
-		case 6:
-			us = "CALLDATALOAD";
-			break;
-		default:;
-		}
-
-		auto firstAsString = [&]()
-		{
-			auto i = *++_t.begin();
-			if (i.tag())
-				error<InvalidName>();
-			if (i.which() == sp::utree_type::string_type)
-			{
-				auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
-				return string(sr.begin(), sr.end());
-			}
-			else if (i.which() == sp::utree_type::symbol_type)
-			{
-				auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
-				return _s.getDef(string(sr.begin(), sr.end())).m_asm.backString();
-			}
-			return string();
-		};
-
-		auto varAddress = [&](string const& n)
-		{
-			auto it = _s.vars.find(n);
-			if (it == _s.vars.end())
-			{
-				bool ok;
-				tie(it, ok) = _s.vars.insert(make_pair(n, make_pair(_s.stackSize, 32)));
-				_s.stackSize += 32;
-			}
-			return it->second.first;
-		};
-
-		// Operations who args are not standard stack-pushers.
-		bool nonStandard = true;
-		if (us == "ASM")
-		{
-			int c = 0;
-			for (auto const& i: _t)
-				if (c++)
-					m_asm.append(CodeFragment(i, _s, true).m_asm);
-		}
-		else if (us == "INCLUDE")
-		{
-			if (_t.size() != 2)
-				error<IncorrectParameterCount>();
-			m_asm.append(CodeFragment::compile(contentsString(firstAsString()), _s).m_asm);
-		}
-		else if (us == "SET")
-		{
-			if (_t.size() != 3)
-				error<IncorrectParameterCount>();
-			int c = 0;
-			for (auto const& i: _t)
-				if (c++ == 2)
-					m_asm.append(CodeFragment(i, _s, false).m_asm);
-			m_asm.append((u256)varAddress(firstAsString()));
-			m_asm.append(Instruction::MSTORE);
-		}
-		else if (us == "GET")
-		{
-			if (_t.size() != 2)
-				error<IncorrectParameterCount>();
-			m_asm.append((u256)varAddress(firstAsString()));
-			m_asm.append(Instruction::MLOAD);
-		}
-		else if (us == "REF")
-			m_asm.append((u256)varAddress(firstAsString()));
-		else if (us == "DEF")
-		{
-			string n;
-			unsigned ii = 0;
-			if (_t.size() != 3 && _t.size() != 4)
-				error<IncorrectParameterCount>();
-			vector<string> args;
-			for (auto const& i: _t)
-			{
-				if (ii == 1)
-				{
-					if (i.tag())
-						error<InvalidName>();
-					if (i.which() == sp::utree_type::string_type)
-					{
-						auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
-						n = string(sr.begin(), sr.end());
-					}
-					else if (i.which() == sp::utree_type::symbol_type)
-					{
-						auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
-						n = _s.getDef(string(sr.begin(), sr.end())).m_asm.backString();
-					}
-				}
-				else if (ii == 2)
-					if (_t.size() == 3)
-						_s.defs[n] = CodeFragment(i, _s);
-					else
-						for (auto const& j: i)
-						{
-							if (j.tag() || j.which() != sp::utree_type::symbol_type)
-								error<InvalidMacroArgs>();
-							auto sr = j.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
-							args.push_back(string(sr.begin(), sr.end()));
-						}
-				else if (ii == 3)
-				{
-					auto k = make_pair(n, args.size());
-					_s.macros[k].code = i;
-					_s.macros[k].env = _s.outers;
-					_s.macros[k].args = args;
-					for (auto const& i: _s.args)
-						_s.macros[k].env[i.first] = i.second;
-					for (auto const& i: _s.defs)
-						_s.macros[k].env[i.first] = i.second;
-				}
-				++ii;
-			}
-		}
-		else if (us == "LIT")
-		{
-			if (_t.size() < 3)
-				error<IncorrectParameterCount>();
-			unsigned ii = 0;
-			CodeFragment pos;
-			bytes data;
-			for (auto const& i: _t)
-			{
-				if (ii == 1)
-				{
-					pos = CodeFragment(i, _s);
-					if (pos.m_asm.deposit() != 1)
-						error<InvalidDeposit>();
-				}
-				else if (ii == 2 && !i.tag() && i.which() == sp::utree_type::string_type)
-				{
-					auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
-					data = bytes((byte const*)sr.begin(), (byte const*)sr.end());
-				}
-				else if (ii >= 2 && !i.tag() && i.which() == sp::utree_type::any_type)
-				{
-					bigint bi = *i.get<bigint*>();
-					if (bi < 0)
-						error<IntegerOutOfRange>();
-					else if (bi > bigint(u256(0) - 1))
-					{
-						if (ii == 2 && _t.size() == 3)
-						{
-							// One big int - allow it as hex.
-							data.resize(bytesRequired(bi));
-							toBigEndian(bi, data);
-						}
-						else
-							error<IntegerOutOfRange>();
-					}
-					else
-					{
-						data.resize(data.size() + 32);
-						*(h256*)(&data.back() - 31) = (u256)bi;
-					}
-				}
-				else if (ii)
-					error<InvalidLiteral>();
-				++ii;
-			}
-			m_asm.append((u256)data.size());
-			m_asm.append(Instruction::DUP1);
-			m_asm.append(data);
-			m_asm.append(pos.m_asm, 1);
-			m_asm.append(Instruction::CODECOPY);
-		}
-		else
-			nonStandard = false;
-
-		if (nonStandard)
-			return;
-
-		std::map<std::string, Instruction> const c_arith = { { "+", Instruction::ADD }, { "-", Instruction::SUB }, { "*", Instruction::MUL }, { "/", Instruction::DIV }, { "%", Instruction::MOD }, { "&", Instruction::AND }, { "|", Instruction::OR }, { "^", Instruction::XOR } };
-		std::map<std::string, pair<Instruction, bool>> const c_binary = { { "<", { Instruction::LT, false } }, { "<=", { Instruction::GT, true } }, { ">", { Instruction::GT, false } }, { ">=", { Instruction::LT, true } }, { "S<", { Instruction::SLT, false } }, { "S<=", { Instruction::SGT, true } }, { "S>", { Instruction::SGT, false } }, { "S>=", { Instruction::SLT, true } }, { "=", { Instruction::EQ, false } }, { "!=", { Instruction::EQ, true } } };
-		std::map<std::string, Instruction> const c_unary = { { "!", Instruction::ISZERO } };
-
-		vector<CodeFragment> code;
-		CompilerState ns = _s;
-		ns.vars.clear();
-		ns.usedAlloc = false;
-		int c = _t.tag() ? 1 : 0;
-		for (auto const& i: _t)
-			if (c++)
-			{
-				if (us == "LLL" && c == 1)
-					code.push_back(CodeFragment(i, ns));
-				else
-					code.push_back(CodeFragment(i, _s));
-			}
-		auto requireSize = [&](unsigned s) { if (code.size() != s) error<IncorrectParameterCount>(); };
-		auto requireMinSize = [&](unsigned s) { if (code.size() < s) error<IncorrectParameterCount>(); };
-		auto requireMaxSize = [&](unsigned s) { if (code.size() > s) error<IncorrectParameterCount>(); };
-		auto requireDeposit = [&](unsigned i, int s) { if (code[i].m_asm.deposit() != s) error<InvalidDeposit>(); };
-
-		if (_s.macros.count(make_pair(s, code.size())))
-		{
-			Macro const& m = _s.macros.at(make_pair(s, code.size()));
-			CompilerState cs = _s;
-			for (auto const& i: m.env)
-				cs.outers[i.first] = i.second;
-			for (auto const& i: cs.defs)
-				cs.outers[i.first] = i.second;
-			cs.defs.clear();
-			for (unsigned i = 0; i < m.args.size(); ++i)
-			{
-				//requireDeposit(i, 1);
-				cs.args[m.args[i]] = code[i];
-			}
-			m_asm.append(CodeFragment(m.code, cs).m_asm);
-			for (auto const& i: cs.defs)
-				_s.defs[i.first] = i.second;
-			for (auto const& i: cs.macros)
-				_s.macros.insert(i);
-		}
-		else if (c_instructions.count(us))
-		{
-			auto it = c_instructions.find(us);
-			int ea = instructionInfo(it->second).args;
-			if (ea >= 0)
-				requireSize(ea);
-			else
-				requireMinSize(-ea);
-
-			for (unsigned i = code.size(); i; --i)
-				m_asm.append(code[i - 1].m_asm, 1);
-			m_asm.append(it->second);
-		}
-		else if (c_arith.count(us))
-		{
-			auto it = c_arith.find(us);
-			requireMinSize(1);
-			for (unsigned i = code.size(); i; --i)
-			{
-				requireDeposit(i - 1, 1);
-				m_asm.append(code[i - 1].m_asm, 1);
-			}
-			for (unsigned i = 1; i < code.size(); ++i)
-				m_asm.append(it->second);
-		}
-		else if (c_binary.count(us))
-		{
-			auto it = c_binary.find(us);
-			requireSize(2);
-			requireDeposit(0, 1);
-			requireDeposit(1, 1);
-			m_asm.append(code[1].m_asm, 1);
-			m_asm.append(code[0].m_asm, 1);
-			m_asm.append(it->second.first);
-			if (it->second.second)
-				m_asm.append(Instruction::ISZERO);
-		}
-		else if (c_unary.count(us))
-		{
-			auto it = c_unary.find(us);
-			requireSize(1);
-			requireDeposit(0, 1);
-			m_asm.append(code[0].m_asm, 1);
-			m_asm.append(it->second);
-		}
-		else if (us == "IF")
-		{
-			requireSize(3);
-			requireDeposit(0, 1);
-			int minDep = min(code[1].m_asm.deposit(), code[2].m_asm.deposit());
-
-			m_asm.append(code[0].m_asm);
-			auto pos = m_asm.appendJumpI();
-			m_asm.onePath();
-			m_asm.append(code[2].m_asm, minDep);
-			auto end = m_asm.appendJump();
-			m_asm.otherPath();
-			m_asm << pos.tag();
-			m_asm.append(code[1].m_asm, minDep);
-			m_asm << end.tag();
-			m_asm.donePaths();
-		}
-		else if (us == "WHEN" || us == "UNLESS")
-		{
-			requireSize(2);
-			requireDeposit(0, 1);
-
-			m_asm.append(code[0].m_asm);
-			if (us == "WHEN")
-				m_asm.append(Instruction::ISZERO);
-			auto end = m_asm.appendJumpI();
-			m_asm.onePath();
-			m_asm.otherPath();
-			m_asm.append(code[1].m_asm, 0);
-			m_asm << end.tag();
-			m_asm.donePaths();
-		}
-		else if (us == "WHILE")
-		{
-			requireSize(2);
-			requireDeposit(0, 1);
-
-			auto begin = m_asm.append();
-			m_asm.append(code[0].m_asm);
-			m_asm.append(Instruction::ISZERO);
-			auto end = m_asm.appendJumpI();
-			m_asm.append(code[1].m_asm, 0);
-			m_asm.appendJump(begin);
-			m_asm << end.tag();
-		}
-		else if (us == "FOR")
-		{
-			requireSize(4);
-			requireDeposit(1, 1);
-
-			m_asm.append(code[0].m_asm, 0);
-			auto begin = m_asm.append();
-			m_asm.append(code[1].m_asm);
-			m_asm.append(Instruction::ISZERO);
-			auto end = m_asm.appendJumpI();
-			m_asm.append(code[3].m_asm, 0);
-			m_asm.append(code[2].m_asm, 0);
-			m_asm.appendJump(begin);
-			m_asm << end.tag();
-		}
-		else if (us == "ALLOC")
-		{
-			requireSize(1);
-			requireDeposit(0, 1);
-
-			m_asm.append(Instruction::MSIZE);
-			m_asm.append(u256(0));
-			m_asm.append(u256(1));
-			m_asm.append(code[0].m_asm, 1);
-			m_asm.append(Instruction::MSIZE);
-			m_asm.append(Instruction::ADD);
-			m_asm.append(Instruction::SUB);
-			m_asm.append(Instruction::MSTORE8);
-
-			_s.usedAlloc = true;
-		}
-		else if (us == "LLL")
-		{
-			requireMinSize(2);
-			requireMaxSize(3);
-			requireDeposit(1, 1);
-
-			auto subPush = m_asm.appendSubSize(code[0].assembly(ns));
-			m_asm.append(Instruction::DUP1);
-			if (code.size() == 3)
-			{
-				requireDeposit(2, 1);
-				m_asm.append(code[2].m_asm, 1);
-				m_asm.append(Instruction::LT);
-				m_asm.append(Instruction::ISZERO);
-				m_asm.append(Instruction::MUL);
-				m_asm.append(Instruction::DUP1);
-			}
-			m_asm.append(subPush);
-			m_asm.append(code[1].m_asm, 1);
-			m_asm.append(Instruction::CODECOPY);
-		}
-		else if (us == "&&" || us == "||")
-		{
-			requireMinSize(1);
-			for (unsigned i = 0; i < code.size(); ++i)
-				requireDeposit(i, 1);
-
-			auto end = m_asm.newTag();
-			if (code.size() > 1)
-			{
-				m_asm.append((u256)(us == "||" ? 1 : 0));
-				for (unsigned i = 1; i < code.size(); ++i)
-				{
-					// Check if true - predicate
-					m_asm.append(code[i - 1].m_asm, 1);
-					if (us == "&&")
-						m_asm.append(Instruction::ISZERO);
-					m_asm.appendJumpI(end);
-				}
-				m_asm.append(Instruction::POP);
-			}
-
-			// Check if true - predicate
-			m_asm.append(code.back().m_asm, 1);
-
-			// At end now.
-			m_asm.append(end);
-		}
-		else if (us == "~")
-		{
-			requireSize(1);
-			requireDeposit(0, 1);
-
-			m_asm.append(code[0].m_asm, 1);
-			m_asm.append((u256)1);
-			m_asm.append((u256)0);
-			m_asm.append(Instruction::SUB);
-			m_asm.append(Instruction::SUB);
-		}
-		else if (us == "SEQ")
-		{
-			unsigned ii = 0;
-			for (auto const& i: code)
-				if (++ii < code.size())
-					m_asm.append(i.m_asm, 0);
-				else
-					m_asm.append(i.m_asm);
-		}
-		else if (us == "RAW")
-		{
-			for (auto const& i: code)
-				m_asm.append(i.m_asm);
-			m_asm.popTo(1);
-		}
-		else if (us.find_first_of("1234567890") != 0 && us.find_first_not_of("QWERTYUIOPASDFGHJKLZXCVBNM1234567890_") == string::npos)
-			m_asm.append((u256)varAddress(s));
-		else
-			error<InvalidOperation>();
-	}
-}
-
-CodeFragment CodeFragment::compile(string const& _src, CompilerState& _s)
-{
-	CodeFragment ret;
-	sp::utree o;
-	parseTreeLLL(_src, o);
-	if (!o.empty())
-		ret = CodeFragment(o, _s);
-	_s.treesToKill.push_back(o);
-	return ret;
-}
diff --git a/CodeFragment.h b/CodeFragment.h
deleted file mode 100644
index 03f812b6..00000000
--- a/CodeFragment.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file CodeFragment.h
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#pragma once
-
-#include <libdevcore/Common.h>
-#include <libevmcore/Instruction.h>
-#include <libevmasm/Assembly.h>
-#include "Exceptions.h"
-
-namespace boost { namespace spirit { class utree; } }
-namespace sp = boost::spirit;
-
-namespace dev
-{
-namespace eth
-{
-
-struct CompilerState;
-
-class CodeFragment
-{
-public:
-	CodeFragment() {}
-	CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowASM = false);
-
-	static CodeFragment compile(std::string const& _src, CompilerState& _s);
-
-	/// Consolidates data and compiles code.
-	Assembly& assembly(CompilerState const& _cs) { finalise(_cs); return m_asm; }
-
-private:
-	void finalise(CompilerState const& _cs);
-
-	template <class T> void error() const { BOOST_THROW_EXCEPTION(T() ); }
-	void constructOperation(sp::utree const& _t, CompilerState& _s);
-
-	bool m_finalised = false;
-	Assembly m_asm;
-};
-
-static const CodeFragment NullCodeFragment;
-
-}
-}
-
diff --git a/Compiler.cpp b/Compiler.cpp
deleted file mode 100644
index f1538789..00000000
--- a/Compiler.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file Compiler.cpp
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#include "Compiler.h"
-#include "Parser.h"
-#include "CompilerState.h"
-#include "CodeFragment.h"
-
-using namespace std;
-using namespace dev;
-using namespace dev::eth;
-
-bytes dev::eth::compileLLL(string const& _src, bool _opt, vector<string>* _errors)
-{
-	try
-	{
-		CompilerState cs;
-		cs.populateStandard();
-		auto f = CodeFragment::compile(_src, cs);
-		bytes ret = f.assembly(cs).optimise(_opt).assemble().bytecode;
-		for (auto i: cs.treesToKill)
-			killBigints(i);
-		return ret;
-	}
-	catch (Exception const& _e)
-	{
-		if (_errors)
-		{
-			_errors->push_back("Parse error.");
-			_errors->push_back(diagnostic_information(_e));
-		}
-	}
-	catch (std::exception)
-	{
-		if (_errors)
-			_errors->push_back("Parse error.");
-	}
-	return bytes();
-}
-
-std::string dev::eth::compileLLLToAsm(std::string const& _src, bool _opt, std::vector<std::string>* _errors)
-{
-	try
-	{
-		CompilerState cs;
-		cs.populateStandard();
-		string ret = CodeFragment::compile(_src, cs).assembly(cs).optimise(_opt).out();
-		for (auto i: cs.treesToKill)
-			killBigints(i);
-		return ret;
-	}
-	catch (Exception const& _e)
-	{
-		if (_errors)
-			_errors->push_back(diagnostic_information(_e));
-	}
-	catch (std::exception)
-	{
-		if (_errors)
-			_errors->push_back("Parse error.");
-	}
-	return string();
-}
-
-string dev::eth::parseLLL(string const& _src)
-{
-	sp::utree o;
-	try
-	{
-		parseTreeLLL(_src, o);
-	}
-	catch (...) {}
-	ostringstream ret;
-	debugOutAST(ret, o);
-	killBigints(o);
-	return ret.str();
-}
diff --git a/Compiler.h b/Compiler.h
deleted file mode 100644
index 0fadd278..00000000
--- a/Compiler.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file Compiler.h
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#pragma once
-
-#include <string>
-#include <vector>
-#include <libdevcore/Common.h>
-
-namespace dev
-{
-namespace eth
-{
-
-std::string parseLLL(std::string const& _src);
-std::string compileLLLToAsm(std::string const& _src, bool _opt = true, std::vector<std::string>* _errors = nullptr);
-bytes compileLLL(std::string const& _src, bool _opt = true, std::vector<std::string>* _errors = nullptr);
-
-}
-}
diff --git a/CompilerState.cpp b/CompilerState.cpp
deleted file mode 100644
index 63351bc4..00000000
--- a/CompilerState.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file CompilerState.cpp
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#include "CompilerState.h"
-#include "CodeFragment.h"
-
-using namespace std;
-using namespace dev;
-using namespace dev::eth;
-
-CompilerState::CompilerState()
-{
-}
-
-CodeFragment const& CompilerState::getDef(std::string const& _s)
-{
-	if (defs.count(_s))
-		return defs.at(_s);
-	else if (args.count(_s))
-		return args.at(_s);
-	else if (outers.count(_s))
-		return outers.at(_s);
-	else
-		return NullCodeFragment;
-}
-
-void CompilerState::populateStandard()
-{
-	static const string s = "{"
-	"(def 'gav 0x51ba59315b3a95761d0863b05ccc7a7f54703d99)"
-	"(def 'config 0x661005d2720d855f1d9976f88bb10c1a3398c77f)"
-	"(def 'allgas (- (gas) 21))"
-	"(def 'send (to value) (call allgas to value 0 0 0 0))"
-	"(def 'send (gaslimit to value) (call gaslimit to value 0 0 0 0))"
-	"(def 'msg (gaslimit to value data datasize outsize) { (set x outsize) (set y (alloc @32)) (call gaslimit to value data datasize @0 @32) @0 })"
-	"(def 'msg (gaslimit to value data datasize) { (call gaslimit to value data datasize 0 32) @0 })"
-	"(def 'msg (gaslimit to value data) { [0]:data (msg gaslimit to value 0 32) })"
-	"(def 'msg (to value data) { [0]:data (msg allgas to value 0 32) })"
-	"(def 'msg (to data) { [0]:data (msg allgas to 0 0 32) })"
-	"(def 'create (value code) { [0]:(msize) (create value @0 (lll code @0)) })"
-	"(def 'create (code) { [0]:(msize) (create 0 @0 (lll code @0)) })"
-	"(def 'sha3 (val) { [0]:val (sha3 0 32) })"
-	"(def 'sha3pair (a b) { [0]:a [32]:b (sha3 0 64) })"
-	"(def 'sha3trip (a b c) { [0]:a [32]:b [64]:c (sha3 0 96) })"
-	"(def 'return (val) { [0]:val (return 0 32) })"
-	"(def 'returnlll (code) (return 0 (lll code 0)) )"
-	"(def 'makeperm (name pos) { (def name (sload pos)) (def name (v) (sstore pos v)) } )"
-	"(def 'permcount 0)"
-	"(def 'perm (name) { (makeperm name permcount) (def 'permcount (+ permcount 1)) } )"
-	"(def 'namereg (msg config 0))"
-	"(def 'coinreg (msg config 1))"
-	"(def 'gavcoin (msg config 2))"
-	"(def 'sendgavcoin (to value) { [32]'send [64]:to [96]:value (call allgas gavcoin 0 32 96 0 0) })"
-	"(def 'regname (name) { [32]'register [64]name (call allgas namereg 0 32 64 0 0) })"
-	"(def 'regcoin (name) { [32]name (call allgas coinreg 0 32 32 0 0) })"
-	"(def 'regcoin (name denom) { [32]name [64]denom (call allgas coinreg 0 32 64 0 0) })"
-	"(def 'ecrecover (r s v hash) { [0] r [32] s [64] v [96] hash (msg allgas 1 0 0 128) })"
-	"(def 'sha256 (data datasize) (msg allgas 2 0 data datasize))"
-	"(def 'ripemd160 (data datasize) (msg allgas 3 0 data datasize))"
-	"(def 'sha256 (val) { [0]:val (sha256 0 32) })"
-	"(def 'ripemd160 (val) { [0]:val (ripemd160 0 32) })"
-	"}";
-	CodeFragment::compile(s, *this);
-}
diff --git a/CompilerState.h b/CompilerState.h
deleted file mode 100644
index bfe56f92..00000000
--- a/CompilerState.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file CompilerState.h
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#pragma once
-
-#include <boost/spirit/include/support_utree.hpp>
-#include "CodeFragment.h"
-
-namespace dev
-{
-namespace eth
-{
-
-struct Macro
-{
-	std::vector<std::string> args;
-	boost::spirit::utree code;
-	std::map<std::string, CodeFragment> env;
-};
-
-struct CompilerState
-{
-	CompilerState();
-
-	CodeFragment const& getDef(std::string const& _s);
-	void populateStandard();
-
-	unsigned stackSize = 128;
-	std::map<std::string, std::pair<unsigned, unsigned>> vars;       ///< maps name to stack offset & size.
-	std::map<std::string, CodeFragment> defs;
-	std::map<std::string, CodeFragment> args;
-	std::map<std::string, CodeFragment> outers;
-	std::map<std::pair<std::string, unsigned>, Macro> macros;
-	std::vector<boost::spirit::utree> treesToKill;
-	bool usedAlloc = false;
-};
-
-}
-}
diff --git a/Exceptions.h b/Exceptions.h
deleted file mode 100644
index 1e9671b3..00000000
--- a/Exceptions.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file Exceptions.h
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#pragma once
-
-#include <libdevcore/Exceptions.h>
-
-namespace dev
-{
-namespace eth
-{
-
-/// Compile a Low-level Lisp-like Language program into EVM-code.
-class CompilerException: public dev::Exception {};
-class InvalidOperation: public CompilerException {};
-class IntegerOutOfRange: public CompilerException {};
-class EmptyList: public CompilerException {};
-class DataNotExecutable: public CompilerException {};
-class IncorrectParameterCount: public CompilerException {};
-class InvalidName: public CompilerException {};
-class InvalidMacroArgs: public CompilerException {};
-class InvalidLiteral: public CompilerException {};
-class BareSymbol: public CompilerException {};
-
-}
-}
diff --git a/Parser.cpp b/Parser.cpp
deleted file mode 100644
index df30f389..00000000
--- a/Parser.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file Parser.cpp
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#include "Parser.h"
-
-#define BOOST_RESULT_OF_USE_DECLTYPE
-#define BOOST_SPIRIT_USE_PHOENIX_V3
-#include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/phoenix.hpp>
-#include <boost/spirit/include/support_utree.hpp>
-
-using namespace std;
-using namespace dev;
-using namespace dev::eth;
-namespace qi = boost::spirit::qi;
-namespace px = boost::phoenix;
-namespace sp = boost::spirit;
-
-void dev::eth::killBigints(sp::utree const& _this)
-{
-	switch (_this.which())
-	{
-	case sp::utree_type::list_type: for (auto const& i: _this) killBigints(i); break;
-	case sp::utree_type::any_type: delete _this.get<bigint*>(); break;
-	default:;
-	}
-}
-
-void dev::eth::debugOutAST(ostream& _out, sp::utree const& _this)
-{
-	switch (_this.which())
-	{
-	case sp::utree_type::list_type:
-		switch (_this.tag())
-		{
-		case 0: _out << "( "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << ")"; break;
-		case 1: _out << "@ "; debugOutAST(_out, _this.front()); break;
-		case 2: _out << "@@ "; debugOutAST(_out, _this.front()); break;
-		case 3: _out << "[ "; debugOutAST(_out, _this.front()); _out << " ] "; debugOutAST(_out, _this.back()); break;
-		case 4: _out << "[[ "; debugOutAST(_out, _this.front()); _out << " ]] "; debugOutAST(_out, _this.back()); break;
-		case 5: _out << "{ "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << "}"; break;
-		case 6: _out << "$ "; debugOutAST(_out, _this.front()); break;
-		default:;
-		}
-
-		break;
-	case sp::utree_type::int_type: _out << _this.get<int>(); break;
-	case sp::utree_type::string_type: _out << "\"" << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>() << "\""; break;
-	case sp::utree_type::symbol_type: _out << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>(); break;
-	case sp::utree_type::any_type: _out << *_this.get<bigint*>(); break;
-	default: _out << "nil";
-	}
-}
-
-namespace dev { namespace eth {
-namespace parseTreeLLL_ {
-
-template<unsigned N>
-struct tagNode
-{
-	void operator()(sp::utree& n, qi::rule<string::const_iterator, qi::ascii::space_type, sp::utree()>::context_type& c) const
-	{
-		(boost::fusion::at_c<0>(c.attributes) = n).tag(N);
-	}
-};
-
-}}}
-
-void dev::eth::parseTreeLLL(string const& _s, sp::utree& o_out)
-{
-	using qi::standard::space;
-	using qi::standard::space_type;
-	using dev::eth::parseTreeLLL_::tagNode;
-	using symbol_type = sp::basic_string<std::string, sp::utree_type::symbol_type>;
-	using it = string::const_iterator;
-
-	static const u256 ether = u256(1000000000) * 1000000000;
-	static const u256 finney = u256(1000000000) * 1000000;
-	static const u256 szabo = u256(1000000000) * 1000;
-
-	qi::rule<it, space_type, sp::utree()> element;
-	qi::rule<it, string()> str = '"' > qi::lexeme[+(~qi::char_(std::string("\"") + '\0'))] > '"';
-	qi::rule<it, string()> strsh = '\'' > qi::lexeme[+(~qi::char_(std::string(" ;$@()[]{}:\n\t") + '\0'))];
-	qi::rule<it, symbol_type()> symbol = qi::lexeme[+(~qi::char_(std::string(" $@[]{}:();\"\x01-\x1f\x7f") + '\0'))];
-	qi::rule<it, string()> intstr = qi::lexeme[ qi::no_case["0x"][qi::_val = "0x"] >> *qi::char_("0-9a-fA-F")[qi::_val += qi::_1]] | qi::lexeme[+qi::char_("0-9")[qi::_val += qi::_1]];
-	qi::rule<it, bigint()> integer = intstr;
-	qi::rule<it, bigint()> multiplier = qi::lit("wei")[qi::_val = 1] | qi::lit("szabo")[qi::_val = szabo] | qi::lit("finney")[qi::_val = finney] | qi::lit("ether")[qi::_val = ether];
-	qi::rule<it, space_type, bigint()> quantity = integer[qi::_val = qi::_1] >> -multiplier[qi::_val *= qi::_1];
-	qi::rule<it, space_type, sp::utree()> atom = quantity[qi::_val = px::construct<sp::any_ptr>(px::new_<bigint>(qi::_1))] | (str | strsh)[qi::_val = qi::_1] | symbol[qi::_val = qi::_1];
-	qi::rule<it, space_type, sp::utree::list_type()> seq = '{' > *element > '}';
-	qi::rule<it, space_type, sp::utree::list_type()> mload = '@' > element;
-	qi::rule<it, space_type, sp::utree::list_type()> sload = qi::lit("@@") > element;
-	qi::rule<it, space_type, sp::utree::list_type()> mstore = '[' > element > ']' > -qi::lit(":") > element;
-	qi::rule<it, space_type, sp::utree::list_type()> sstore = qi::lit("[[") > element > qi::lit("]]") > -qi::lit(":") > element;
-	qi::rule<it, space_type, sp::utree::list_type()> calldataload = qi::lit("$") > element;
-	qi::rule<it, space_type, sp::utree::list_type()> list = '(' > *element > ')';
-
-	qi::rule<it, space_type, sp::utree()> extra = sload[tagNode<2>()] | mload[tagNode<1>()] | sstore[tagNode<4>()] | mstore[tagNode<3>()] | seq[tagNode<5>()] | calldataload[tagNode<6>()];
-	element = atom | list | extra;
-
-	string s;
-	s.reserve(_s.size());
-	bool incomment = false;
-	bool instring = false;
-	bool insstring = false;
-	for (auto i: _s)
-	{
-		if (i == ';' && !instring && !insstring)
-			incomment = true;
-		else if (i == '\n')
-			incomment = instring = insstring = false;
-		else if (i == '"' && !insstring)
-			instring = !instring;
-		else if (i == '\'')
-			insstring = true;
-		else if (i == ' ')
-			insstring = false;
-		if (!incomment)
-			s.push_back(i);
-	}
-	auto ret = s.cbegin();
-	qi::phrase_parse(ret, s.cend(), element, space, qi::skip_flag::dont_postskip, o_out);
-	for (auto i = ret; i != s.cend(); ++i)
-		if (!isspace(*i))
-			BOOST_THROW_EXCEPTION(std::exception());
-}
-
diff --git a/Parser.h b/Parser.h
deleted file mode 100644
index b21989f0..00000000
--- a/Parser.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
-	This file is part of cpp-ethereum.
-
-	cpp-ethereum is free software: you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation, either version 3 of the License, or
-	(at your option) any later version.
-
-	cpp-ethereum is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
-*/
-/** @file Parser.h
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- */
-
-#pragma once
-
-#include <string>
-#include <vector>
-#include <libdevcore/Common.h>
-
-namespace boost { namespace spirit { class utree; } }
-namespace sp = boost::spirit;
-
-namespace dev
-{
-namespace eth
-{
-
-void killBigints(sp::utree const& _this);
-void parseTreeLLL(std::string const& _s, sp::utree& o_out);
-void debugOutAST(std::ostream& _out, sp::utree const& _this);
-
-}
-}
diff --git a/liblll/All.h b/liblll/All.h
new file mode 100644
index 00000000..7c4192f6
--- /dev/null
+++ b/liblll/All.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#include "CodeFragment.h"
+#include "Compiler.h"
+#include "CompilerState.h"
+#include "Parser.h"
diff --git a/liblll/CMakeLists.txt b/liblll/CMakeLists.txt
new file mode 100644
index 00000000..0b468d7a
--- /dev/null
+++ b/liblll/CMakeLists.txt
@@ -0,0 +1,23 @@
+cmake_policy(SET CMP0015 NEW)
+set(CMAKE_AUTOMOC OFF)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
+
+aux_source_directory(. SRC_LIST)
+
+#include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS})
+include_directories(BEFORE ..)
+#include_directories(${Boost_INCLUDE_DIRS})
+
+set(EXECUTABLE lll)
+
+file(GLOB HEADERS "*.h")
+
+add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
+
+eth_use(${EXECUTABLE} REQUIRED Eth::evmasm)
+#target_link_libraries(${EXECUTABLE} evmasm)
+
+install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
+install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )
+
diff --git a/liblll/CodeFragment.cpp b/liblll/CodeFragment.cpp
new file mode 100644
index 00000000..64680d5a
--- /dev/null
+++ b/liblll/CodeFragment.cpp
@@ -0,0 +1,586 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file CodeFragment.cpp
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#include "CodeFragment.h"
+
+#include <boost/algorithm/string.hpp>
+#pragma warning(push)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#include <boost/spirit/include/support_utree.hpp>
+#pragma warning(pop)
+#pragma GCC diagnostic pop
+#include <libdevcore/Log.h>
+#include <libdevcore/CommonIO.h>
+#include <libevmcore/Instruction.h>
+#include "CompilerState.h"
+#include "Parser.h"
+using namespace std;
+using namespace dev;
+using namespace dev::eth;
+namespace qi = boost::spirit::qi;
+namespace px = boost::phoenix;
+namespace sp = boost::spirit;
+
+void CodeFragment::finalise(CompilerState const& _cs)
+{
+	if (_cs.usedAlloc && _cs.vars.size() && !m_finalised)
+	{
+		m_finalised = true;
+		m_asm.injectStart(Instruction::MSTORE8);
+		m_asm.injectStart((u256)((_cs.vars.size() + 2) * 32) - 1);
+		m_asm.injectStart((u256)1);
+	}
+}
+
+CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowASM)
+{
+/*	cdebug << "CodeFragment. Locals:";
+	for (auto const& i: _s.defs)
+		cdebug << i.first << ":" << toHex(i.second.m_code);
+	cdebug << "Args:";
+	for (auto const& i: _s.args)
+		cdebug << i.first << ":" << toHex(i.second.m_code);
+	cdebug << "Outers:";
+	for (auto const& i: _s.outers)
+		cdebug << i.first << ":" << toHex(i.second.m_code);
+	debugOutAST(cout, _t);
+	cout << endl << flush;
+*/
+	switch (_t.which())
+	{
+	case sp::utree_type::list_type:
+		constructOperation(_t, _s);
+		break;
+	case sp::utree_type::string_type:
+	{
+		auto sr = _t.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
+		string s(sr.begin(), sr.end());
+		m_asm.append(s);
+		break;
+	}
+	case sp::utree_type::symbol_type:
+	{
+		auto sr = _t.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
+		string s(sr.begin(), sr.end());
+		string us = boost::algorithm::to_upper_copy(s);
+		if (_allowASM && c_instructions.count(us))
+			m_asm.append(c_instructions.at(us));
+		else if (_s.defs.count(s))
+			m_asm.append(_s.defs.at(s).m_asm);
+		else if (_s.args.count(s))
+			m_asm.append(_s.args.at(s).m_asm);
+		else if (_s.outers.count(s))
+			m_asm.append(_s.outers.at(s).m_asm);
+		else if (us.find_first_of("1234567890") != 0 && us.find_first_not_of("QWERTYUIOPASDFGHJKLZXCVBNM1234567890_") == string::npos)
+		{
+			auto it = _s.vars.find(s);
+			if (it == _s.vars.end())
+			{
+				bool ok;
+				tie(it, ok) = _s.vars.insert(make_pair(s, make_pair(_s.stackSize, 32)));
+				_s.stackSize += 32;
+			}
+			m_asm.append((u256)it->second.first);
+		}
+		else
+			error<BareSymbol>();
+
+		break;
+	}
+	case sp::utree_type::any_type:
+	{
+		bigint i = *_t.get<bigint*>();
+		if (i < 0 || i > bigint(u256(0) - 1))
+			error<IntegerOutOfRange>();
+		m_asm.append((u256)i);
+		break;
+	}
+	default: break;
+	}
+}
+
+void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
+{
+	if (_t.tag() == 0 && _t.empty())
+		error<EmptyList>();
+	else if (_t.tag() == 0 && _t.front().which() != sp::utree_type::symbol_type)
+		error<DataNotExecutable>();
+	else
+	{
+		string s;
+		string us;
+		switch (_t.tag())
+		{
+		case 0:
+		{
+			auto sr = _t.front().get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
+			s = string(sr.begin(), sr.end());
+			us = boost::algorithm::to_upper_copy(s);
+			break;
+		}
+		case 1:
+			us = "MLOAD";
+			break;
+		case 2:
+			us = "SLOAD";
+			break;
+		case 3:
+			us = "MSTORE";
+			break;
+		case 4:
+			us = "SSTORE";
+			break;
+		case 5:
+			us = "SEQ";
+			break;
+		case 6:
+			us = "CALLDATALOAD";
+			break;
+		default:;
+		}
+
+		auto firstAsString = [&]()
+		{
+			auto i = *++_t.begin();
+			if (i.tag())
+				error<InvalidName>();
+			if (i.which() == sp::utree_type::string_type)
+			{
+				auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
+				return string(sr.begin(), sr.end());
+			}
+			else if (i.which() == sp::utree_type::symbol_type)
+			{
+				auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
+				return _s.getDef(string(sr.begin(), sr.end())).m_asm.backString();
+			}
+			return string();
+		};
+
+		auto varAddress = [&](string const& n)
+		{
+			auto it = _s.vars.find(n);
+			if (it == _s.vars.end())
+			{
+				bool ok;
+				tie(it, ok) = _s.vars.insert(make_pair(n, make_pair(_s.stackSize, 32)));
+				_s.stackSize += 32;
+			}
+			return it->second.first;
+		};
+
+		// Operations who args are not standard stack-pushers.
+		bool nonStandard = true;
+		if (us == "ASM")
+		{
+			int c = 0;
+			for (auto const& i: _t)
+				if (c++)
+					m_asm.append(CodeFragment(i, _s, true).m_asm);
+		}
+		else if (us == "INCLUDE")
+		{
+			if (_t.size() != 2)
+				error<IncorrectParameterCount>();
+			m_asm.append(CodeFragment::compile(contentsString(firstAsString()), _s).m_asm);
+		}
+		else if (us == "SET")
+		{
+			if (_t.size() != 3)
+				error<IncorrectParameterCount>();
+			int c = 0;
+			for (auto const& i: _t)
+				if (c++ == 2)
+					m_asm.append(CodeFragment(i, _s, false).m_asm);
+			m_asm.append((u256)varAddress(firstAsString()));
+			m_asm.append(Instruction::MSTORE);
+		}
+		else if (us == "GET")
+		{
+			if (_t.size() != 2)
+				error<IncorrectParameterCount>();
+			m_asm.append((u256)varAddress(firstAsString()));
+			m_asm.append(Instruction::MLOAD);
+		}
+		else if (us == "REF")
+			m_asm.append((u256)varAddress(firstAsString()));
+		else if (us == "DEF")
+		{
+			string n;
+			unsigned ii = 0;
+			if (_t.size() != 3 && _t.size() != 4)
+				error<IncorrectParameterCount>();
+			vector<string> args;
+			for (auto const& i: _t)
+			{
+				if (ii == 1)
+				{
+					if (i.tag())
+						error<InvalidName>();
+					if (i.which() == sp::utree_type::string_type)
+					{
+						auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
+						n = string(sr.begin(), sr.end());
+					}
+					else if (i.which() == sp::utree_type::symbol_type)
+					{
+						auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
+						n = _s.getDef(string(sr.begin(), sr.end())).m_asm.backString();
+					}
+				}
+				else if (ii == 2)
+					if (_t.size() == 3)
+						_s.defs[n] = CodeFragment(i, _s);
+					else
+						for (auto const& j: i)
+						{
+							if (j.tag() || j.which() != sp::utree_type::symbol_type)
+								error<InvalidMacroArgs>();
+							auto sr = j.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>();
+							args.push_back(string(sr.begin(), sr.end()));
+						}
+				else if (ii == 3)
+				{
+					auto k = make_pair(n, args.size());
+					_s.macros[k].code = i;
+					_s.macros[k].env = _s.outers;
+					_s.macros[k].args = args;
+					for (auto const& i: _s.args)
+						_s.macros[k].env[i.first] = i.second;
+					for (auto const& i: _s.defs)
+						_s.macros[k].env[i.first] = i.second;
+				}
+				++ii;
+			}
+		}
+		else if (us == "LIT")
+		{
+			if (_t.size() < 3)
+				error<IncorrectParameterCount>();
+			unsigned ii = 0;
+			CodeFragment pos;
+			bytes data;
+			for (auto const& i: _t)
+			{
+				if (ii == 1)
+				{
+					pos = CodeFragment(i, _s);
+					if (pos.m_asm.deposit() != 1)
+						error<InvalidDeposit>();
+				}
+				else if (ii == 2 && !i.tag() && i.which() == sp::utree_type::string_type)
+				{
+					auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
+					data = bytes((byte const*)sr.begin(), (byte const*)sr.end());
+				}
+				else if (ii >= 2 && !i.tag() && i.which() == sp::utree_type::any_type)
+				{
+					bigint bi = *i.get<bigint*>();
+					if (bi < 0)
+						error<IntegerOutOfRange>();
+					else if (bi > bigint(u256(0) - 1))
+					{
+						if (ii == 2 && _t.size() == 3)
+						{
+							// One big int - allow it as hex.
+							data.resize(bytesRequired(bi));
+							toBigEndian(bi, data);
+						}
+						else
+							error<IntegerOutOfRange>();
+					}
+					else
+					{
+						data.resize(data.size() + 32);
+						*(h256*)(&data.back() - 31) = (u256)bi;
+					}
+				}
+				else if (ii)
+					error<InvalidLiteral>();
+				++ii;
+			}
+			m_asm.append((u256)data.size());
+			m_asm.append(Instruction::DUP1);
+			m_asm.append(data);
+			m_asm.append(pos.m_asm, 1);
+			m_asm.append(Instruction::CODECOPY);
+		}
+		else
+			nonStandard = false;
+
+		if (nonStandard)
+			return;
+
+		std::map<std::string, Instruction> const c_arith = { { "+", Instruction::ADD }, { "-", Instruction::SUB }, { "*", Instruction::MUL }, { "/", Instruction::DIV }, { "%", Instruction::MOD }, { "&", Instruction::AND }, { "|", Instruction::OR }, { "^", Instruction::XOR } };
+		std::map<std::string, pair<Instruction, bool>> const c_binary = { { "<", { Instruction::LT, false } }, { "<=", { Instruction::GT, true } }, { ">", { Instruction::GT, false } }, { ">=", { Instruction::LT, true } }, { "S<", { Instruction::SLT, false } }, { "S<=", { Instruction::SGT, true } }, { "S>", { Instruction::SGT, false } }, { "S>=", { Instruction::SLT, true } }, { "=", { Instruction::EQ, false } }, { "!=", { Instruction::EQ, true } } };
+		std::map<std::string, Instruction> const c_unary = { { "!", Instruction::ISZERO } };
+
+		vector<CodeFragment> code;
+		CompilerState ns = _s;
+		ns.vars.clear();
+		ns.usedAlloc = false;
+		int c = _t.tag() ? 1 : 0;
+		for (auto const& i: _t)
+			if (c++)
+			{
+				if (us == "LLL" && c == 1)
+					code.push_back(CodeFragment(i, ns));
+				else
+					code.push_back(CodeFragment(i, _s));
+			}
+		auto requireSize = [&](unsigned s) { if (code.size() != s) error<IncorrectParameterCount>(); };
+		auto requireMinSize = [&](unsigned s) { if (code.size() < s) error<IncorrectParameterCount>(); };
+		auto requireMaxSize = [&](unsigned s) { if (code.size() > s) error<IncorrectParameterCount>(); };
+		auto requireDeposit = [&](unsigned i, int s) { if (code[i].m_asm.deposit() != s) error<InvalidDeposit>(); };
+
+		if (_s.macros.count(make_pair(s, code.size())))
+		{
+			Macro const& m = _s.macros.at(make_pair(s, code.size()));
+			CompilerState cs = _s;
+			for (auto const& i: m.env)
+				cs.outers[i.first] = i.second;
+			for (auto const& i: cs.defs)
+				cs.outers[i.first] = i.second;
+			cs.defs.clear();
+			for (unsigned i = 0; i < m.args.size(); ++i)
+			{
+				//requireDeposit(i, 1);
+				cs.args[m.args[i]] = code[i];
+			}
+			m_asm.append(CodeFragment(m.code, cs).m_asm);
+			for (auto const& i: cs.defs)
+				_s.defs[i.first] = i.second;
+			for (auto const& i: cs.macros)
+				_s.macros.insert(i);
+		}
+		else if (c_instructions.count(us))
+		{
+			auto it = c_instructions.find(us);
+			int ea = instructionInfo(it->second).args;
+			if (ea >= 0)
+				requireSize(ea);
+			else
+				requireMinSize(-ea);
+
+			for (unsigned i = code.size(); i; --i)
+				m_asm.append(code[i - 1].m_asm, 1);
+			m_asm.append(it->second);
+		}
+		else if (c_arith.count(us))
+		{
+			auto it = c_arith.find(us);
+			requireMinSize(1);
+			for (unsigned i = code.size(); i; --i)
+			{
+				requireDeposit(i - 1, 1);
+				m_asm.append(code[i - 1].m_asm, 1);
+			}
+			for (unsigned i = 1; i < code.size(); ++i)
+				m_asm.append(it->second);
+		}
+		else if (c_binary.count(us))
+		{
+			auto it = c_binary.find(us);
+			requireSize(2);
+			requireDeposit(0, 1);
+			requireDeposit(1, 1);
+			m_asm.append(code[1].m_asm, 1);
+			m_asm.append(code[0].m_asm, 1);
+			m_asm.append(it->second.first);
+			if (it->second.second)
+				m_asm.append(Instruction::ISZERO);
+		}
+		else if (c_unary.count(us))
+		{
+			auto it = c_unary.find(us);
+			requireSize(1);
+			requireDeposit(0, 1);
+			m_asm.append(code[0].m_asm, 1);
+			m_asm.append(it->second);
+		}
+		else if (us == "IF")
+		{
+			requireSize(3);
+			requireDeposit(0, 1);
+			int minDep = min(code[1].m_asm.deposit(), code[2].m_asm.deposit());
+
+			m_asm.append(code[0].m_asm);
+			auto pos = m_asm.appendJumpI();
+			m_asm.onePath();
+			m_asm.append(code[2].m_asm, minDep);
+			auto end = m_asm.appendJump();
+			m_asm.otherPath();
+			m_asm << pos.tag();
+			m_asm.append(code[1].m_asm, minDep);
+			m_asm << end.tag();
+			m_asm.donePaths();
+		}
+		else if (us == "WHEN" || us == "UNLESS")
+		{
+			requireSize(2);
+			requireDeposit(0, 1);
+
+			m_asm.append(code[0].m_asm);
+			if (us == "WHEN")
+				m_asm.append(Instruction::ISZERO);
+			auto end = m_asm.appendJumpI();
+			m_asm.onePath();
+			m_asm.otherPath();
+			m_asm.append(code[1].m_asm, 0);
+			m_asm << end.tag();
+			m_asm.donePaths();
+		}
+		else if (us == "WHILE")
+		{
+			requireSize(2);
+			requireDeposit(0, 1);
+
+			auto begin = m_asm.append();
+			m_asm.append(code[0].m_asm);
+			m_asm.append(Instruction::ISZERO);
+			auto end = m_asm.appendJumpI();
+			m_asm.append(code[1].m_asm, 0);
+			m_asm.appendJump(begin);
+			m_asm << end.tag();
+		}
+		else if (us == "FOR")
+		{
+			requireSize(4);
+			requireDeposit(1, 1);
+
+			m_asm.append(code[0].m_asm, 0);
+			auto begin = m_asm.append();
+			m_asm.append(code[1].m_asm);
+			m_asm.append(Instruction::ISZERO);
+			auto end = m_asm.appendJumpI();
+			m_asm.append(code[3].m_asm, 0);
+			m_asm.append(code[2].m_asm, 0);
+			m_asm.appendJump(begin);
+			m_asm << end.tag();
+		}
+		else if (us == "ALLOC")
+		{
+			requireSize(1);
+			requireDeposit(0, 1);
+
+			m_asm.append(Instruction::MSIZE);
+			m_asm.append(u256(0));
+			m_asm.append(u256(1));
+			m_asm.append(code[0].m_asm, 1);
+			m_asm.append(Instruction::MSIZE);
+			m_asm.append(Instruction::ADD);
+			m_asm.append(Instruction::SUB);
+			m_asm.append(Instruction::MSTORE8);
+
+			_s.usedAlloc = true;
+		}
+		else if (us == "LLL")
+		{
+			requireMinSize(2);
+			requireMaxSize(3);
+			requireDeposit(1, 1);
+
+			auto subPush = m_asm.appendSubSize(code[0].assembly(ns));
+			m_asm.append(Instruction::DUP1);
+			if (code.size() == 3)
+			{
+				requireDeposit(2, 1);
+				m_asm.append(code[2].m_asm, 1);
+				m_asm.append(Instruction::LT);
+				m_asm.append(Instruction::ISZERO);
+				m_asm.append(Instruction::MUL);
+				m_asm.append(Instruction::DUP1);
+			}
+			m_asm.append(subPush);
+			m_asm.append(code[1].m_asm, 1);
+			m_asm.append(Instruction::CODECOPY);
+		}
+		else if (us == "&&" || us == "||")
+		{
+			requireMinSize(1);
+			for (unsigned i = 0; i < code.size(); ++i)
+				requireDeposit(i, 1);
+
+			auto end = m_asm.newTag();
+			if (code.size() > 1)
+			{
+				m_asm.append((u256)(us == "||" ? 1 : 0));
+				for (unsigned i = 1; i < code.size(); ++i)
+				{
+					// Check if true - predicate
+					m_asm.append(code[i - 1].m_asm, 1);
+					if (us == "&&")
+						m_asm.append(Instruction::ISZERO);
+					m_asm.appendJumpI(end);
+				}
+				m_asm.append(Instruction::POP);
+			}
+
+			// Check if true - predicate
+			m_asm.append(code.back().m_asm, 1);
+
+			// At end now.
+			m_asm.append(end);
+		}
+		else if (us == "~")
+		{
+			requireSize(1);
+			requireDeposit(0, 1);
+
+			m_asm.append(code[0].m_asm, 1);
+			m_asm.append((u256)1);
+			m_asm.append((u256)0);
+			m_asm.append(Instruction::SUB);
+			m_asm.append(Instruction::SUB);
+		}
+		else if (us == "SEQ")
+		{
+			unsigned ii = 0;
+			for (auto const& i: code)
+				if (++ii < code.size())
+					m_asm.append(i.m_asm, 0);
+				else
+					m_asm.append(i.m_asm);
+		}
+		else if (us == "RAW")
+		{
+			for (auto const& i: code)
+				m_asm.append(i.m_asm);
+			m_asm.popTo(1);
+		}
+		else if (us.find_first_of("1234567890") != 0 && us.find_first_not_of("QWERTYUIOPASDFGHJKLZXCVBNM1234567890_") == string::npos)
+			m_asm.append((u256)varAddress(s));
+		else
+			error<InvalidOperation>();
+	}
+}
+
+CodeFragment CodeFragment::compile(string const& _src, CompilerState& _s)
+{
+	CodeFragment ret;
+	sp::utree o;
+	parseTreeLLL(_src, o);
+	if (!o.empty())
+		ret = CodeFragment(o, _s);
+	_s.treesToKill.push_back(o);
+	return ret;
+}
diff --git a/liblll/CodeFragment.h b/liblll/CodeFragment.h
new file mode 100644
index 00000000..03f812b6
--- /dev/null
+++ b/liblll/CodeFragment.h
@@ -0,0 +1,64 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file CodeFragment.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#pragma once
+
+#include <libdevcore/Common.h>
+#include <libevmcore/Instruction.h>
+#include <libevmasm/Assembly.h>
+#include "Exceptions.h"
+
+namespace boost { namespace spirit { class utree; } }
+namespace sp = boost::spirit;
+
+namespace dev
+{
+namespace eth
+{
+
+struct CompilerState;
+
+class CodeFragment
+{
+public:
+	CodeFragment() {}
+	CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowASM = false);
+
+	static CodeFragment compile(std::string const& _src, CompilerState& _s);
+
+	/// Consolidates data and compiles code.
+	Assembly& assembly(CompilerState const& _cs) { finalise(_cs); return m_asm; }
+
+private:
+	void finalise(CompilerState const& _cs);
+
+	template <class T> void error() const { BOOST_THROW_EXCEPTION(T() ); }
+	void constructOperation(sp::utree const& _t, CompilerState& _s);
+
+	bool m_finalised = false;
+	Assembly m_asm;
+};
+
+static const CodeFragment NullCodeFragment;
+
+}
+}
+
diff --git a/liblll/Compiler.cpp b/liblll/Compiler.cpp
new file mode 100644
index 00000000..f1538789
--- /dev/null
+++ b/liblll/Compiler.cpp
@@ -0,0 +1,95 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file Compiler.cpp
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#include "Compiler.h"
+#include "Parser.h"
+#include "CompilerState.h"
+#include "CodeFragment.h"
+
+using namespace std;
+using namespace dev;
+using namespace dev::eth;
+
+bytes dev::eth::compileLLL(string const& _src, bool _opt, vector<string>* _errors)
+{
+	try
+	{
+		CompilerState cs;
+		cs.populateStandard();
+		auto f = CodeFragment::compile(_src, cs);
+		bytes ret = f.assembly(cs).optimise(_opt).assemble().bytecode;
+		for (auto i: cs.treesToKill)
+			killBigints(i);
+		return ret;
+	}
+	catch (Exception const& _e)
+	{
+		if (_errors)
+		{
+			_errors->push_back("Parse error.");
+			_errors->push_back(diagnostic_information(_e));
+		}
+	}
+	catch (std::exception)
+	{
+		if (_errors)
+			_errors->push_back("Parse error.");
+	}
+	return bytes();
+}
+
+std::string dev::eth::compileLLLToAsm(std::string const& _src, bool _opt, std::vector<std::string>* _errors)
+{
+	try
+	{
+		CompilerState cs;
+		cs.populateStandard();
+		string ret = CodeFragment::compile(_src, cs).assembly(cs).optimise(_opt).out();
+		for (auto i: cs.treesToKill)
+			killBigints(i);
+		return ret;
+	}
+	catch (Exception const& _e)
+	{
+		if (_errors)
+			_errors->push_back(diagnostic_information(_e));
+	}
+	catch (std::exception)
+	{
+		if (_errors)
+			_errors->push_back("Parse error.");
+	}
+	return string();
+}
+
+string dev::eth::parseLLL(string const& _src)
+{
+	sp::utree o;
+	try
+	{
+		parseTreeLLL(_src, o);
+	}
+	catch (...) {}
+	ostringstream ret;
+	debugOutAST(ret, o);
+	killBigints(o);
+	return ret.str();
+}
diff --git a/liblll/Compiler.h b/liblll/Compiler.h
new file mode 100644
index 00000000..0fadd278
--- /dev/null
+++ b/liblll/Compiler.h
@@ -0,0 +1,38 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file Compiler.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#pragma once
+
+#include <string>
+#include <vector>
+#include <libdevcore/Common.h>
+
+namespace dev
+{
+namespace eth
+{
+
+std::string parseLLL(std::string const& _src);
+std::string compileLLLToAsm(std::string const& _src, bool _opt = true, std::vector<std::string>* _errors = nullptr);
+bytes compileLLL(std::string const& _src, bool _opt = true, std::vector<std::string>* _errors = nullptr);
+
+}
+}
diff --git a/liblll/CompilerState.cpp b/liblll/CompilerState.cpp
new file mode 100644
index 00000000..63351bc4
--- /dev/null
+++ b/liblll/CompilerState.cpp
@@ -0,0 +1,82 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file CompilerState.cpp
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#include "CompilerState.h"
+#include "CodeFragment.h"
+
+using namespace std;
+using namespace dev;
+using namespace dev::eth;
+
+CompilerState::CompilerState()
+{
+}
+
+CodeFragment const& CompilerState::getDef(std::string const& _s)
+{
+	if (defs.count(_s))
+		return defs.at(_s);
+	else if (args.count(_s))
+		return args.at(_s);
+	else if (outers.count(_s))
+		return outers.at(_s);
+	else
+		return NullCodeFragment;
+}
+
+void CompilerState::populateStandard()
+{
+	static const string s = "{"
+	"(def 'gav 0x51ba59315b3a95761d0863b05ccc7a7f54703d99)"
+	"(def 'config 0x661005d2720d855f1d9976f88bb10c1a3398c77f)"
+	"(def 'allgas (- (gas) 21))"
+	"(def 'send (to value) (call allgas to value 0 0 0 0))"
+	"(def 'send (gaslimit to value) (call gaslimit to value 0 0 0 0))"
+	"(def 'msg (gaslimit to value data datasize outsize) { (set x outsize) (set y (alloc @32)) (call gaslimit to value data datasize @0 @32) @0 })"
+	"(def 'msg (gaslimit to value data datasize) { (call gaslimit to value data datasize 0 32) @0 })"
+	"(def 'msg (gaslimit to value data) { [0]:data (msg gaslimit to value 0 32) })"
+	"(def 'msg (to value data) { [0]:data (msg allgas to value 0 32) })"
+	"(def 'msg (to data) { [0]:data (msg allgas to 0 0 32) })"
+	"(def 'create (value code) { [0]:(msize) (create value @0 (lll code @0)) })"
+	"(def 'create (code) { [0]:(msize) (create 0 @0 (lll code @0)) })"
+	"(def 'sha3 (val) { [0]:val (sha3 0 32) })"
+	"(def 'sha3pair (a b) { [0]:a [32]:b (sha3 0 64) })"
+	"(def 'sha3trip (a b c) { [0]:a [32]:b [64]:c (sha3 0 96) })"
+	"(def 'return (val) { [0]:val (return 0 32) })"
+	"(def 'returnlll (code) (return 0 (lll code 0)) )"
+	"(def 'makeperm (name pos) { (def name (sload pos)) (def name (v) (sstore pos v)) } )"
+	"(def 'permcount 0)"
+	"(def 'perm (name) { (makeperm name permcount) (def 'permcount (+ permcount 1)) } )"
+	"(def 'namereg (msg config 0))"
+	"(def 'coinreg (msg config 1))"
+	"(def 'gavcoin (msg config 2))"
+	"(def 'sendgavcoin (to value) { [32]'send [64]:to [96]:value (call allgas gavcoin 0 32 96 0 0) })"
+	"(def 'regname (name) { [32]'register [64]name (call allgas namereg 0 32 64 0 0) })"
+	"(def 'regcoin (name) { [32]name (call allgas coinreg 0 32 32 0 0) })"
+	"(def 'regcoin (name denom) { [32]name [64]denom (call allgas coinreg 0 32 64 0 0) })"
+	"(def 'ecrecover (r s v hash) { [0] r [32] s [64] v [96] hash (msg allgas 1 0 0 128) })"
+	"(def 'sha256 (data datasize) (msg allgas 2 0 data datasize))"
+	"(def 'ripemd160 (data datasize) (msg allgas 3 0 data datasize))"
+	"(def 'sha256 (val) { [0]:val (sha256 0 32) })"
+	"(def 'ripemd160 (val) { [0]:val (ripemd160 0 32) })"
+	"}";
+	CodeFragment::compile(s, *this);
+}
diff --git a/liblll/CompilerState.h b/liblll/CompilerState.h
new file mode 100644
index 00000000..bfe56f92
--- /dev/null
+++ b/liblll/CompilerState.h
@@ -0,0 +1,57 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file CompilerState.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#pragma once
+
+#include <boost/spirit/include/support_utree.hpp>
+#include "CodeFragment.h"
+
+namespace dev
+{
+namespace eth
+{
+
+struct Macro
+{
+	std::vector<std::string> args;
+	boost::spirit::utree code;
+	std::map<std::string, CodeFragment> env;
+};
+
+struct CompilerState
+{
+	CompilerState();
+
+	CodeFragment const& getDef(std::string const& _s);
+	void populateStandard();
+
+	unsigned stackSize = 128;
+	std::map<std::string, std::pair<unsigned, unsigned>> vars;       ///< maps name to stack offset & size.
+	std::map<std::string, CodeFragment> defs;
+	std::map<std::string, CodeFragment> args;
+	std::map<std::string, CodeFragment> outers;
+	std::map<std::pair<std::string, unsigned>, Macro> macros;
+	std::vector<boost::spirit::utree> treesToKill;
+	bool usedAlloc = false;
+};
+
+}
+}
diff --git a/liblll/Exceptions.h b/liblll/Exceptions.h
new file mode 100644
index 00000000..1e9671b3
--- /dev/null
+++ b/liblll/Exceptions.h
@@ -0,0 +1,44 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file Exceptions.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#pragma once
+
+#include <libdevcore/Exceptions.h>
+
+namespace dev
+{
+namespace eth
+{
+
+/// Compile a Low-level Lisp-like Language program into EVM-code.
+class CompilerException: public dev::Exception {};
+class InvalidOperation: public CompilerException {};
+class IntegerOutOfRange: public CompilerException {};
+class EmptyList: public CompilerException {};
+class DataNotExecutable: public CompilerException {};
+class IncorrectParameterCount: public CompilerException {};
+class InvalidName: public CompilerException {};
+class InvalidMacroArgs: public CompilerException {};
+class InvalidLiteral: public CompilerException {};
+class BareSymbol: public CompilerException {};
+
+}
+}
diff --git a/liblll/Parser.cpp b/liblll/Parser.cpp
new file mode 100644
index 00000000..df30f389
--- /dev/null
+++ b/liblll/Parser.cpp
@@ -0,0 +1,145 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file Parser.cpp
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#include "Parser.h"
+
+#define BOOST_RESULT_OF_USE_DECLTYPE
+#define BOOST_SPIRIT_USE_PHOENIX_V3
+#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/phoenix.hpp>
+#include <boost/spirit/include/support_utree.hpp>
+
+using namespace std;
+using namespace dev;
+using namespace dev::eth;
+namespace qi = boost::spirit::qi;
+namespace px = boost::phoenix;
+namespace sp = boost::spirit;
+
+void dev::eth::killBigints(sp::utree const& _this)
+{
+	switch (_this.which())
+	{
+	case sp::utree_type::list_type: for (auto const& i: _this) killBigints(i); break;
+	case sp::utree_type::any_type: delete _this.get<bigint*>(); break;
+	default:;
+	}
+}
+
+void dev::eth::debugOutAST(ostream& _out, sp::utree const& _this)
+{
+	switch (_this.which())
+	{
+	case sp::utree_type::list_type:
+		switch (_this.tag())
+		{
+		case 0: _out << "( "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << ")"; break;
+		case 1: _out << "@ "; debugOutAST(_out, _this.front()); break;
+		case 2: _out << "@@ "; debugOutAST(_out, _this.front()); break;
+		case 3: _out << "[ "; debugOutAST(_out, _this.front()); _out << " ] "; debugOutAST(_out, _this.back()); break;
+		case 4: _out << "[[ "; debugOutAST(_out, _this.front()); _out << " ]] "; debugOutAST(_out, _this.back()); break;
+		case 5: _out << "{ "; for (auto const& i: _this) { debugOutAST(_out, i); _out << " "; } _out << "}"; break;
+		case 6: _out << "$ "; debugOutAST(_out, _this.front()); break;
+		default:;
+		}
+
+		break;
+	case sp::utree_type::int_type: _out << _this.get<int>(); break;
+	case sp::utree_type::string_type: _out << "\"" << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>() << "\""; break;
+	case sp::utree_type::symbol_type: _out << _this.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::symbol_type>>(); break;
+	case sp::utree_type::any_type: _out << *_this.get<bigint*>(); break;
+	default: _out << "nil";
+	}
+}
+
+namespace dev { namespace eth {
+namespace parseTreeLLL_ {
+
+template<unsigned N>
+struct tagNode
+{
+	void operator()(sp::utree& n, qi::rule<string::const_iterator, qi::ascii::space_type, sp::utree()>::context_type& c) const
+	{
+		(boost::fusion::at_c<0>(c.attributes) = n).tag(N);
+	}
+};
+
+}}}
+
+void dev::eth::parseTreeLLL(string const& _s, sp::utree& o_out)
+{
+	using qi::standard::space;
+	using qi::standard::space_type;
+	using dev::eth::parseTreeLLL_::tagNode;
+	using symbol_type = sp::basic_string<std::string, sp::utree_type::symbol_type>;
+	using it = string::const_iterator;
+
+	static const u256 ether = u256(1000000000) * 1000000000;
+	static const u256 finney = u256(1000000000) * 1000000;
+	static const u256 szabo = u256(1000000000) * 1000;
+
+	qi::rule<it, space_type, sp::utree()> element;
+	qi::rule<it, string()> str = '"' > qi::lexeme[+(~qi::char_(std::string("\"") + '\0'))] > '"';
+	qi::rule<it, string()> strsh = '\'' > qi::lexeme[+(~qi::char_(std::string(" ;$@()[]{}:\n\t") + '\0'))];
+	qi::rule<it, symbol_type()> symbol = qi::lexeme[+(~qi::char_(std::string(" $@[]{}:();\"\x01-\x1f\x7f") + '\0'))];
+	qi::rule<it, string()> intstr = qi::lexeme[ qi::no_case["0x"][qi::_val = "0x"] >> *qi::char_("0-9a-fA-F")[qi::_val += qi::_1]] | qi::lexeme[+qi::char_("0-9")[qi::_val += qi::_1]];
+	qi::rule<it, bigint()> integer = intstr;
+	qi::rule<it, bigint()> multiplier = qi::lit("wei")[qi::_val = 1] | qi::lit("szabo")[qi::_val = szabo] | qi::lit("finney")[qi::_val = finney] | qi::lit("ether")[qi::_val = ether];
+	qi::rule<it, space_type, bigint()> quantity = integer[qi::_val = qi::_1] >> -multiplier[qi::_val *= qi::_1];
+	qi::rule<it, space_type, sp::utree()> atom = quantity[qi::_val = px::construct<sp::any_ptr>(px::new_<bigint>(qi::_1))] | (str | strsh)[qi::_val = qi::_1] | symbol[qi::_val = qi::_1];
+	qi::rule<it, space_type, sp::utree::list_type()> seq = '{' > *element > '}';
+	qi::rule<it, space_type, sp::utree::list_type()> mload = '@' > element;
+	qi::rule<it, space_type, sp::utree::list_type()> sload = qi::lit("@@") > element;
+	qi::rule<it, space_type, sp::utree::list_type()> mstore = '[' > element > ']' > -qi::lit(":") > element;
+	qi::rule<it, space_type, sp::utree::list_type()> sstore = qi::lit("[[") > element > qi::lit("]]") > -qi::lit(":") > element;
+	qi::rule<it, space_type, sp::utree::list_type()> calldataload = qi::lit("$") > element;
+	qi::rule<it, space_type, sp::utree::list_type()> list = '(' > *element > ')';
+
+	qi::rule<it, space_type, sp::utree()> extra = sload[tagNode<2>()] | mload[tagNode<1>()] | sstore[tagNode<4>()] | mstore[tagNode<3>()] | seq[tagNode<5>()] | calldataload[tagNode<6>()];
+	element = atom | list | extra;
+
+	string s;
+	s.reserve(_s.size());
+	bool incomment = false;
+	bool instring = false;
+	bool insstring = false;
+	for (auto i: _s)
+	{
+		if (i == ';' && !instring && !insstring)
+			incomment = true;
+		else if (i == '\n')
+			incomment = instring = insstring = false;
+		else if (i == '"' && !insstring)
+			instring = !instring;
+		else if (i == '\'')
+			insstring = true;
+		else if (i == ' ')
+			insstring = false;
+		if (!incomment)
+			s.push_back(i);
+	}
+	auto ret = s.cbegin();
+	qi::phrase_parse(ret, s.cend(), element, space, qi::skip_flag::dont_postskip, o_out);
+	for (auto i = ret; i != s.cend(); ++i)
+		if (!isspace(*i))
+			BOOST_THROW_EXCEPTION(std::exception());
+}
+
diff --git a/liblll/Parser.h b/liblll/Parser.h
new file mode 100644
index 00000000..b21989f0
--- /dev/null
+++ b/liblll/Parser.h
@@ -0,0 +1,41 @@
+/*
+	This file is part of cpp-ethereum.
+
+	cpp-ethereum is free software: you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation, either version 3 of the License, or
+	(at your option) any later version.
+
+	cpp-ethereum is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @file Parser.h
+ * @author Gav Wood <i@gavwood.com>
+ * @date 2014
+ */
+
+#pragma once
+
+#include <string>
+#include <vector>
+#include <libdevcore/Common.h>
+
+namespace boost { namespace spirit { class utree; } }
+namespace sp = boost::spirit;
+
+namespace dev
+{
+namespace eth
+{
+
+void killBigints(sp::utree const& _this);
+void parseTreeLLL(std::string const& _s, sp::utree& o_out);
+void debugOutAST(std::ostream& _out, sp::utree const& _this);
+
+}
+}
-- 
cgit v1.2.3