@@ -0,0 +1,111 @@
1+package main
2+
3+/*
4+#cgo pkg-config: python2
5+#include <Python.h>
6+
7+void pry_eval_file(FILE* f, const char* file, int argn, const char *argv) {
8+ const char* xargv[argn+1];
9+ const char* ptr = argv;
10+ for (int i = 0; i < argn; ++i) {
11+ xargv[i] = ptr;
12+ ptr += strlen(ptr) + 1;
13+ }
14+ xargv[argn] = NULL;
15+ PySys_SetArgvEx(argn, xargv, 1);
16+ PyRun_AnyFile(f, file);
17+}
18+
19+const char* pry_eval(const char *code, int start) {
20+
21+ PyObject *m, *d, *s, *v;
22+ PyCodeObject *c;
23+ m = PyImport_AddModule("__main__");
24+
25+ if (m == NULL) return NULL;
26+
27+ d = PyModule_GetDict(m);
28+ c = Py_CompileString(code, "(eval)", start);
29+ if (c == NULL) {
30+ PyErr_Print();
31+ return NULL;
32+ }
33+ v = PyEval_EvalCode(c, d, d);
34+ if (v == NULL) {
35+ PyErr_Print();
36+ return NULL;
37+ }
38+ s = PyObject_Str(v);
39+ if (s == NULL) {
40+ PyErr_Print();
41+ return NULL;
42+ }
43+ char *str = PyString_AS_STRING(s);
44+ Py_DECREF(v);
45+ Py_DECREF(s);
46+ return str;
47+}
48+
49+*/
50+import "C"
51+
52+import (
53+ "unsafe"
54+ "strings"
55+)
56+
57+
58+type Python struct {
59+
60+}
61+
62+func (p Python) Open() {
63+ C.Py_Initialize()
64+}
65+
66+func (p Python) Version() string {
67+ return "Python " + C.GoString(C.Py_GetVersion()) + " on " + C.GoString(C.Py_GetPlatform())
68+}
69+
70+func (p Python) Eval(code string) {
71+ ccode := C.CString(code)
72+ defer C.free(unsafe.Pointer(ccode))
73+ C.GoString(C.pry_eval(ccode, C.Py_file_input))
74+}
75+
76+func (p Python) EvalExpression(code string) string {
77+ ccode := C.CString(code)
78+ defer C.free(unsafe.Pointer(ccode))
79+ return C.GoString(C.pry_eval(ccode, C.Py_eval_input))
80+}
81+
82+func (p Python) EvalFile(file string, args []string) {
83+ handle := C.stdin
84+ cfile := C.CString(file)
85+ defer C.free(unsafe.Pointer(cfile))
86+
87+ if file != "-" {
88+ cmode := C.CString("r")
89+
90+ defer C.free(unsafe.Pointer(cmode))
91+ handle = C.fopen(cfile, cmode)
92+ defer C.fclose(handle)
93+ }
94+
95+ argv := C.CString(file + "\x00" + strings.Join(args, "\x00"))
96+ defer C.free(unsafe.Pointer(argv))
97+ C.pry_eval_file(handle, cfile, C.int(len(args) + 1), argv)
98+}
99+
100+func (p Python) REPL() {
101+ fn := C.CString("<stdin>")
102+ defer C.free(unsafe.Pointer(fn))
103+ C.PyRun_InteractiveLoopFlags(C.stdin, fn, nil)
104+}
105+
106+func (p Python) Close() {
107+ C.Py_Finalize()
108+}
109+
110+// exported
111+var Instance Python