aboutsummaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/pyserpent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/pyserpent.cpp')
-rw-r--r--Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/pyserpent.cpp173
1 files changed, 173 insertions, 0 deletions
diff --git a/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/pyserpent.cpp b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/pyserpent.cpp
new file mode 100644
index 000000000..38398aa46
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/ethereum/serpent-go/serpent/pyserpent.cpp
@@ -0,0 +1,173 @@
+#include <Python.h>
+#include "structmember.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream>
+#include "funcs.h"
+
+#define PYMETHOD(name, FROM, method, TO) \
+ static PyObject * name(PyObject *, PyObject *args) { \
+ try { \
+ FROM(med) \
+ return TO(method(med)); \
+ } \
+ catch (std::string e) { \
+ PyErr_SetString(PyExc_Exception, e.c_str()); \
+ return NULL; \
+ } \
+ }
+
+#define FROMSTR(v) \
+ const char *command; \
+ int len; \
+ if (!PyArg_ParseTuple(args, "s#", &command, &len)) \
+ return NULL; \
+ std::string v = std::string(command, len); \
+
+#define FROMNODE(v) \
+ PyObject *node; \
+ if (!PyArg_ParseTuple(args, "O", &node)) \
+ return NULL; \
+ Node v = cppifyNode(node);
+
+#define FROMLIST(v) \
+ PyObject *node; \
+ if (!PyArg_ParseTuple(args, "O", &node)) \
+ return NULL; \
+ std::vector<Node> v = cppifyNodeList(node);
+
+// Convert metadata into python wrapper form [file, ln, ch]
+PyObject* pyifyMetadata(Metadata m) {
+ PyObject* a = PyList_New(0);
+ PyList_Append(a, Py_BuildValue("s#", m.file.c_str(), m.file.length()));
+ PyList_Append(a, Py_BuildValue("i", m.ln));
+ PyList_Append(a, Py_BuildValue("i", m.ch));
+ return a;
+}
+
+// Convert node into python wrapper form
+// [token=0/astnode=1, val, metadata, args]
+PyObject* pyifyNode(Node n) {
+ PyObject* a = PyList_New(0);
+ PyList_Append(a, Py_BuildValue("i", n.type == ASTNODE));
+ PyList_Append(a, Py_BuildValue("s#", n.val.c_str(), n.val.length()));
+ PyList_Append(a, pyifyMetadata(n.metadata));
+ for (unsigned i = 0; i < n.args.size(); i++)
+ PyList_Append(a, pyifyNode(n.args[i]));
+ return a;
+}
+
+// Convert string into python wrapper form
+PyObject* pyifyString(std::string s) {
+ return Py_BuildValue("s#", s.c_str(), s.length());
+}
+
+// Convert list of nodes into python wrapper form
+PyObject* pyifyNodeList(std::vector<Node> n) {
+ PyObject* a = PyList_New(0);
+ for (unsigned i = 0; i < n.size(); i++)
+ PyList_Append(a, pyifyNode(n[i]));
+ return a;
+}
+
+// Convert pyobject int into normal form
+int cppifyInt(PyObject* o) {
+ int out;
+ if (!PyArg_Parse(o, "i", &out))
+ err("Argument should be integer", Metadata());
+ return out;
+}
+
+// Convert pyobject string into normal form
+std::string cppifyString(PyObject* o) {
+ const char *command;
+ if (!PyArg_Parse(o, "s", &command))
+ err("Argument should be string", Metadata());
+ return std::string(command);
+}
+
+// Convert metadata from python wrapper form
+Metadata cppifyMetadata(PyObject* o) {
+ std::string file = cppifyString(PyList_GetItem(o, 0));
+ int ln = cppifyInt(PyList_GetItem(o, 1));
+ int ch = cppifyInt(PyList_GetItem(o, 2));
+ return Metadata(file, ln, ch);
+}
+
+// Convert node from python wrapper form
+Node cppifyNode(PyObject* o) {
+ Node n;
+ int isAstNode = cppifyInt(PyList_GetItem(o, 0));
+ n.type = isAstNode ? ASTNODE : TOKEN;
+ n.val = cppifyString(PyList_GetItem(o, 1));
+ n.metadata = cppifyMetadata(PyList_GetItem(o, 2));
+ std::vector<Node> args;
+ for (int i = 3; i < PyList_Size(o); i++) {
+ args.push_back(cppifyNode(PyList_GetItem(o, i)));
+ }
+ n.args = args;
+ return n;
+}
+
+//Convert list of nodes into normal form
+std::vector<Node> cppifyNodeList(PyObject* o) {
+ std::vector<Node> out;
+ for (int i = 0; i < PyList_Size(o); i++) {
+ out.push_back(cppifyNode(PyList_GetItem(o,i)));
+ }
+ return out;
+}
+
+PYMETHOD(ps_compile, FROMSTR, compile, pyifyString)
+PYMETHOD(ps_compile_chunk, FROMSTR, compileChunk, pyifyString)
+PYMETHOD(ps_compile_to_lll, FROMSTR, compileToLLL, pyifyNode)
+PYMETHOD(ps_compile_chunk_to_lll, FROMSTR, compileChunkToLLL, pyifyNode)
+PYMETHOD(ps_compile_lll, FROMNODE, compileLLL, pyifyString)
+PYMETHOD(ps_parse, FROMSTR, parseSerpent, pyifyNode)
+PYMETHOD(ps_rewrite, FROMNODE, rewrite, pyifyNode)
+PYMETHOD(ps_rewrite_chunk, FROMNODE, rewriteChunk, pyifyNode)
+PYMETHOD(ps_pretty_compile, FROMSTR, prettyCompile, pyifyNodeList)
+PYMETHOD(ps_pretty_compile_chunk, FROMSTR, prettyCompileChunk, pyifyNodeList)
+PYMETHOD(ps_pretty_compile_lll, FROMNODE, prettyCompileLLL, pyifyNodeList)
+PYMETHOD(ps_serialize, FROMLIST, serialize, pyifyString)
+PYMETHOD(ps_deserialize, FROMSTR, deserialize, pyifyNodeList)
+PYMETHOD(ps_parse_lll, FROMSTR, parseLLL, pyifyNode)
+
+
+static PyMethodDef PyextMethods[] = {
+ {"compile", ps_compile, METH_VARARGS,
+ "Compile code."},
+ {"compile_chunk", ps_compile_chunk, METH_VARARGS,
+ "Compile code chunk (no wrappers)."},
+ {"compile_to_lll", ps_compile_to_lll, METH_VARARGS,
+ "Compile code to LLL."},
+ {"compile_chunk_to_lll", ps_compile_chunk_to_lll, METH_VARARGS,
+ "Compile code chunk to LLL (no wrappers)."},
+ {"compile_lll", ps_compile_lll, METH_VARARGS,
+ "Compile LLL to EVM."},
+ {"parse", ps_parse, METH_VARARGS,
+ "Parse serpent"},
+ {"rewrite", ps_rewrite, METH_VARARGS,
+ "Rewrite parsed serpent to LLL"},
+ {"rewrite_chunk", ps_rewrite_chunk, METH_VARARGS,
+ "Rewrite parsed serpent to LLL (no wrappers)"},
+ {"pretty_compile", ps_pretty_compile, METH_VARARGS,
+ "Compile to EVM opcodes"},
+ {"pretty_compile_chunk", ps_pretty_compile_chunk, METH_VARARGS,
+ "Compile chunk to EVM opcodes (no wrappers)"},
+ {"pretty_compile_lll", ps_pretty_compile_lll, METH_VARARGS,
+ "Compile LLL to EVM opcodes"},
+ {"serialize", ps_serialize, METH_VARARGS,
+ "Convert EVM opcodes to bin"},
+ {"deserialize", ps_deserialize, METH_VARARGS,
+ "Convert EVM bin to opcodes"},
+ {"parse_lll", ps_parse_lll, METH_VARARGS,
+ "Parse LLL"},
+ {NULL, NULL, 0, NULL} /* Sentinel */
+};
+
+PyMODINIT_FUNC initserpent_pyext(void)
+{
+ Py_InitModule( "serpent_pyext", PyextMethods );
+}