on master help sign in
Changes
commitdb3e0d29e47e4f2c83ae3eb9c5a7047d2ab8bc26 authorRob Blanckaert <basicer@basicer.com> dateWed 10 Oct 2018, 22:22 (8 years ago) parente8c0f45
21 files changed+700−258
.dockerignore+6 .gitignore+3 Makefile+12−4 extract.sh+3 languages/lua/main.go−74 languages/python2/main.go−43 languages/python3/main.go−43 languages/ruby/main.go−64 mk-deps.sh+22 osx-env.sh+1 src/language.go+82 src/languages/R/main.go+72 languages/lua/repl.c → src/languages/lua/lua.c+4−4 src/languages/lua/main.go+62 src/languages/lua/pry.c+46 src/languages/lua/pry.h+16 src/languages/python2/main.go+111 src/languages/python3/main.go+75 src/languages/ruby/main.go+83 src/languages/spidermonkey/main.go+95 main.go → src/main.go+7−26
.dockerignorenew file+6
@@ -0,0 +1,6 @@
1+prybar
2+plugins
3+Dockerfile
4+extract.sh
5+deps.lst
6+prybar.tar.gz
.gitignore+3
@@ -1,2 +1,5 @@
1+Dockerfile
12plugins/
23prybar
4+deps.lst
5+prybar.tar.gz
Makefile+12−4
@@ -1,9 +1,17 @@
1+.PHONY: clean default
12
2−prybar: main.go plugins/python2.so plugins/python3.so plugins/ruby.so plugins/lua.so
3− go build -o prybar
3+default: prybar
44
5−plugins/%.so: languages/%/*.go
6− cd languages/$* && CGO_LDFLAGS_ALLOW=".*" go build -buildmode=plugin -o ../../$@
5+deps.lst: mk-deps.sh
6+ ./mk-deps.sh > deps.lst
7+
8+-include deps.lst
9+
10+prybar: src/*.go $(plugins)
11+ cd src && go build -o ../prybar
12+
13+plugins/%.so: src/languages/%/*.*
14+ cd src/languages/$* && CGO_LDFLAGS_ALLOW=".*" go build -buildmode=plugin -o ../../../$@
715
816clean:
917 @rm prybar
extract.shnew file+3
@@ -0,0 +1,3 @@
1+#!/bin/sh
2+docker build -t prybar .
3+docker run prybar tar -zc prybar plugins > prybar.tar.gz
languages/lua/main.godeleted−74
@@ -1,74 +0,0 @@
1−package main
2−
3−/*
4−#cgo pkg-config: lua-5.2
5−#include <stdlib.h>
6−#include <lua.h>
7−#include <lauxlib.h>
8−#include <lualib.h>
9−
10−const char * pry_get_version() {
11− return LUA_COPYRIGHT;
12−}
13−
14−lua_State *pry_L;
15−
16−void pry_init() {
17− pry_L = luaL_newstate();
18− luaL_openlibs(pry_L);
19−}
20−
21−void pry_eval(const char *code) {
22− luaL_dostring(pry_L, code);
23−}
24−
25−#define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
26−#define luai_writeline() (luai_writestring("\n", 1), fflush(stdout))
27−
28−int lua_main (int argc, char **argv);
29−
30−void pry_main() {
31− char* args[2] = {"lua", NULL};
32− lua_main(0, args);
33−}
34−
35−void dotty (lua_State *L);
36−
37−*/
38−import "C"
39−
40−import (
41− "unsafe"
42−)
43−
44−
45−type Language struct {
46−
47−}
48−
49−func (p Language) Open() {
50− C.pry_init()
51−}
52−
53−func (p Language) Version() string {
54− return C.GoString(C.pry_get_version())
55−}
56−
57−func (p Language) Eval(code string) {
58− ccode := C.CString(code)
59− defer C.free(unsafe.Pointer(ccode))
60− C.pry_eval(ccode);
61−}
62−
63−func (p Language) REPL() {
64− fn := C.CString("<stdin>")
65− defer C.free(unsafe.Pointer(fn))
66− C.dotty(C.pry_L)
67−}
68−
69−func (p Language) Close() {
70− C.lua_close(C.pry_L)
71−}
72−
73−// exported
74−var Instance Language
languages/python2/main.godeleted−43
@@ -1,43 +0,0 @@
1−package main
2−
3−/*
4−#cgo pkg-config: python2
5−#include <Python.h>
6−*/
7−import "C"
8−
9−import (
10− "unsafe"
11−)
12−
13−
14−type Language struct {
15−
16−}
17−
18−func (p Language) Open() {
19− C.Py_Initialize()
20−}
21−
22−func (p Language) Version() string {
23− return C.GoString(C.Py_GetVersion())
24−}
25−
26−func (p Language) Eval(code string) {
27− ccode := C.CString(code)
28− defer C.free(unsafe.Pointer(ccode))
29− C.PyRun_SimpleStringFlags(ccode, nil)
30−}
31−
32−func (p Language) REPL() {
33− fn := C.CString("<stdin>")
34− defer C.free(unsafe.Pointer(fn))
35− C.PyRun_InteractiveLoopFlags(C.stdin, fn, nil)
36−}
37−
38−func (p Language) Close() {
39− C.Py_Finalize()
40−}
41−
42−// exported
43−var Instance Language
languages/python3/main.godeleted−43
@@ -1,43 +0,0 @@
1−package main
2−
3−/*
4−#cgo pkg-config: python3
5−#include <Python.h>
6−*/
7−import "C"
8−
9−import (
10− "unsafe"
11−)
12−
13−
14−type Language struct {
15−
16−}
17−
18−func (p Language) Open() {
19− C.Py_Initialize()
20−}
21−
22−func (p Language) Version() string {
23− return C.GoString(C.Py_GetVersion())
24−}
25−
26−func (p Language) Eval(code string) {
27− ccode := C.CString(code)
28− defer C.free(unsafe.Pointer(ccode))
29− C.PyRun_SimpleStringFlags(ccode, nil)
30−}
31−
32−func (p Language) REPL() {
33− fn := C.CString("<stdin>")
34− defer C.free(unsafe.Pointer(fn))
35− C.PyRun_InteractiveLoopFlags(C.stdin, fn, nil)
36−}
37−
38−func (p Language) Close() {
39− C.Py_Finalize()
40−}
41−
42−// exported
43−var Instance Language
languages/ruby/main.godeleted−64
@@ -1,64 +0,0 @@
1−package main
2−
3−
4−/*
5−#cgo pkg-config: ruby-2.5
6−#include <ruby.h>
7−#include <ruby/version.h>
8−
9−const char* prybar_ruby_version() {
10− return ruby_description;
11−}
12−
13−void prybar_eval(const char* code) {
14− int state;
15− VALUE result;
16− result = rb_eval_string_protect(code, &state);
17−
18− if (state)
19− {
20− VALUE exception = rb_errinfo();
21− rb_set_errinfo(Qnil);
22− if (RTEST(exception)) rb_warn("%"PRIsVALUE"", rb_funcall(exception, rb_intern("full_message"), 0));
23− }
24−
25−}
26−
27−*/
28−import "C"
29−
30−import (
31− "unsafe"
32−)
33−
34−/* */
35−type Language struct {
36−
37−}
38−
39−func (p Language) Open() {
40− C.ruby_init()
41− C.ruby_init_loadpath()
42−}
43−
44−func (p Language) Version() string {
45− //return C.GoString(C.ruby_version)
46− return C.GoString(C.prybar_ruby_version())
47−}
48−
49−func (p Language) Eval(code string) {
50− ccode := C.CString(code)
51− defer C.free(unsafe.Pointer(ccode))
52− C.prybar_eval(ccode)
53−}
54−
55−func (p Language) REPL() {
56− p.Eval("require 'irb'\nbinding.irb")
57−}
58−
59−func (p Language) Close() {
60− C.ruby_cleanup(0)
61−}
62−
63−// exported
64−var Instance Language
mk-deps.shnew file+22
@@ -0,0 +1,22 @@
1+#/bin/bash
2+
3+FOUND=""
4+check() {
5+ pkg-config --exists $2
6+ if [ $? -eq 0 ]; then
7+ echo "Found plugin $1 => $2" 1>&2
8+ FOUND="$FOUND plugins/$1.so"
9+ else
10+ echo "Couldnt find $1" 1>&2
11+ fi
12+}
13+
14+for plugin in $(ls -1 src/languages/); do
15+ PKG=$(grep cgo.*pkg-config src/languages/$plugin/main.go | cut -d ':' -f 2)
16+ check $plugin $PKG
17+done
18+
19+
20+echo "plugins = $FOUND"
21+
22+
osx-env.shnew file+1
@@ -0,0 +1 @@
1+export PKG_CONFIG_PATH="/usr/local/opt/ruby@2.3/lib/pkgconfig"
src/language.gonew file+82
@@ -0,0 +1,82 @@
1+package main
2+
3+import(
4+ "os"
5+ "plugin"
6+ "fmt"
7+ "runtime"
8+)
9+
10+type PluginBase interface {
11+ Open()
12+ Close()
13+ Version() string
14+}
15+
16+type PluginEval interface {
17+ PluginBase
18+ Eval(code string)
19+}
20+
21+type PluginEvalFile interface {
22+ PluginBase
23+ EvalFile(file string, args []string)
24+}
25+
26+type PluginREPL interface {
27+ PluginBase
28+ REPL()
29+}
30+
31+type Langauge struct {
32+ ptr PluginBase
33+}
34+
35+func finalizer(f *Langauge) {
36+ fmt.Println("a finalizer has run.")
37+}
38+
39+func GetLanguage(name string) *Langauge {
40+ plug, err := plugin.Open("./plugins/" + name + ".so")
41+
42+ if err != nil {
43+ fmt.Println(err)
44+ os.Exit(1)
45+ }
46+
47+ sym, err := plug.Lookup("Instance")
48+ if err != nil {
49+ fmt.Println(err)
50+ os.Exit(1)
51+ }
52+
53+ var lang PluginBase
54+ lang, ok := sym.(PluginBase)
55+ if !ok {
56+ fmt.Println("module did not export Language interface")
57+ os.Exit(1)
58+ }
59+
60+ result := &Langauge {
61+ ptr: lang,
62+ }
63+ lang.Open();
64+ runtime.SetFinalizer(result, finalizer)
65+ return result
66+}
67+
68+func (lang Langauge) Version() string {
69+ return lang.ptr.Version()
70+}
71+
72+func (lang Langauge) Eval(code string) {
73+ lang.ptr.(PluginEval).Eval(code)
74+}
75+
76+func (lang Langauge) EvalFile(file string, args []string) {
77+ lang.ptr.(PluginEvalFile).EvalFile(file, args)
78+}
79+
80+func (lang Langauge) REPL() {
81+ lang.ptr.(PluginREPL).REPL()
82+}
src/languages/R/main.gonew file+72
@@ -0,0 +1,72 @@
1+package main
2+
3+/*
4+#cgo pkg-config: libr
5+#include <stdlib.h>
6+#include <Rembedded.h>
7+#include <RVersion.h>
8+#include <Rinternals.h>
9+#include <R_ext/Parse.h>
10+#include <Rembedded.h>
11+
12+void pry_open() {
13+ const char *args[] = {"/usr/local/bin/R", "--silent", NULL};
14+ Rf_initEmbeddedR(2, args);
15+}
16+
17+const char* pry_version() {
18+ return "R version " R_MAJOR "." R_MINOR " (" R_YEAR "-" R_MONTH "-" R_DAY ") -- \"" R_NICK "\"";
19+}
20+
21+pry_eval(const char* code) {
22+ ParseStatus status;
23+ SEXP x = R_ParseVector(mkString(code), 1, &status, R_NilValue);
24+ SEXP result = eval(VECTOR_ELT(x, 0), R_GlobalEnv);
25+ PrintValue(result);
26+}
27+
28+void pry_repl() {
29+ R_ReplDLLinit();
30+ while (R_ReplDLLdo1() > 0) {
31+
32+ }
33+}
34+
35+*/
36+import "C"
37+
38+import (
39+ "unsafe"
40+ //"strings"
41+)
42+
43+
44+type R struct {
45+
46+}
47+
48+func (p R) Open() {
49+ C.pry_open()
50+}
51+
52+func (p R) Version() string {
53+ return C.GoString(C.pry_version())
54+}
55+
56+func (p R) Eval(code string) {
57+ ccode := C.CString(code)
58+ defer C.free(unsafe.Pointer(ccode))
59+ C.pry_eval(ccode)
60+}
61+
62+
63+func (p R) REPL() {
64+ C.pry_repl();
65+}
66+
67+func (p R) Close() {
68+ C.Rf_endEmbeddedR(0)
69+}
70+
71+// exported
72+var Instance R
languages/lua/repl.c → src/languages/lua/lua.crenamed+4−4
@@ -4,7 +4,7 @@
44** See Copyright Notice in lua.h
55*/
66
7−
7+#include "pry.h"
88#include <signal.h>
99#include <stdio.h>
1010#include <stdlib.h>
@@ -146,7 +146,7 @@ static int report (lua_State *L, int status) {
146146
147147
148148/* the next function is called unprotected, so it must avoid errors */
149−static void finalreport (lua_State *L, int status) {
149+void finalreport (lua_State *L, int status) {
150150 if (status != LUA_OK) {
151151 const char *msg = (lua_type(L, -1) == LUA_TSTRING) ? lua_tostring(L, -1)
152152 : NULL;
@@ -323,7 +323,7 @@ void dotty (lua_State *L) {
323323}
324324
325325
326−static int handle_script (lua_State *L, char **argv, int n) {
326+int handle_script (lua_State *L, char **argv, int n) {
327327 int status;
328328 const char *fname;
329329 int narg = getargs(L, argv, n); /* collect arguments */
@@ -435,7 +435,7 @@ static int handle_luainit (lua_State *L) {
435435}
436436
437437
438−static int pmain (lua_State *L) {
438+int pmain (lua_State *L) {
439439 int argc = (int)lua_tointeger(L, 1);
440440 char **argv = (char **)lua_touserdata(L, 2);
441441 int script;
src/languages/lua/main.gonew file+62
@@ -0,0 +1,62 @@
1+package main
2+
3+/*
4+#cgo pkg-config: lua-5.2
5+#include <stdlib.h>
6+#include <lua.h>
7+#include "pry.h"
8+
9+int lua_main (int argc, char **argv);
10+void dotty (lua_State *L);
11+int pmain (lua_State *L);
12+
13+
14+
15+*/
16+import "C"
17+
18+import (
19+ "unsafe"
20+ "strings"
21+)
22+
23+
24+type Lua struct {
25+
26+}
27+
28+func (p Lua) Open() {
29+ C.pry_init()
30+}
31+
32+func (p Lua) Version() string {
33+ return C.GoString(C.pry_get_version())
34+}
35+
36+func (p Lua) Eval(code string) {
37+ ccode := C.CString(code)
38+ defer C.free(unsafe.Pointer(ccode))
39+ C.pry_eval(ccode);
40+}
41+
42+func (p Lua) EvalFile(file string, args []string) {
43+ cfile := C.CString(file)
44+ defer C.free(unsafe.Pointer(cfile))
45+
46+ argv := C.CString(file + "\x00" + strings.Join(args, "\x00"))
47+ defer C.free(unsafe.Pointer(argv))
48+ C.pry_eval_file(cfile, C.int(len(args) + 1), argv)
49+}
50+
51+func (p Lua) REPL() {
52+ fn := C.CString("<stdin>")
53+ defer C.free(unsafe.Pointer(fn))
54+ C.dotty(C.pry_L)
55+}
56+
57+func (p Lua) Close() {
58+ C.lua_close(C.pry_L)
59+}
60+
61+// exported
62+var Instance Lua
src/languages/lua/pry.cnew file+46
@@ -0,0 +1,46 @@
1+#include <string.h>
2+
3+#include <lauxlib.h>
4+#include <lualib.h>
5+
6+#include "pry.h"
7+
8+char* pry_prompt = "> ";
9+char* pry_prompt2 = ">> ";
10+lua_State *pry_L;
11+
12+const char * pry_get_version() {
13+ return LUA_COPYRIGHT;
14+}
15+
16+
17+void pry_init() {
18+ pry_L = luaL_newstate();
19+ luaL_openlibs(pry_L);
20+}
21+
22+void pry_eval(const char *code) {
23+ luaL_dostring(pry_L, code);
24+}
25+
26+
27+int lua_main (int argc, char **argv);
28+
29+void pry_main() {
30+ char* args[2] = {"lua", NULL};
31+ lua_main(0, args);
32+}
33+
34+int handle_script (lua_State *L, char **argv, int n);
35+void pry_eval_file(const char* file, int argn, const char *argv) {
36+ int status, result;
37+ const char* xargv[argn+1];
38+ const char* ptr = argv;
39+ for (int i = 0; i < argn; ++i) {
40+ xargv[i] = ptr;
41+ ptr += strlen(ptr) + 1;
42+ }
43+ xargv[argn] = NULL;
44+
45+ handle_script(pry_L, xargv, 0);
46+}
src/languages/lua/pry.hnew file+16
@@ -0,0 +1,16 @@
1+#include <lua.h>
2+
3+#define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
4+#define luai_writeline() (luai_writestring("\n", 1), fflush(stdout))
5+#define LUA_PROMPT pry_prompt
6+#define LUA_PROMPT2 pry_prompt2
7+
8+extern lua_State *pry_L;
9+extern char* pry_prompt;
10+extern char* pry_prompt2;
11+
12+const char * pry_get_version();
13+void pry_init();
14+void pry_eval(const char *code);
15+void pry_main();
16+void pry_eval_file(const char* file, int argn, const char *argv);
src/languages/python2/main.gonew file+111
@@ -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
src/languages/python3/main.gonew file+75
@@ -0,0 +1,75 @@
1+package main
2+
3+/*
4+#cgo pkg-config: python3
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+*/
20+import "C"
21+
22+import (
23+ "unsafe"
24+ "strings"
25+)
26+
27+
28+type Python struct {
29+
30+}
31+
32+func (p Python) Open() {
33+ C.Py_Initialize()
34+}
35+
36+func (p Python) Version() string {
37+ return "Python " + C.GoString(C.Py_GetVersion()) + " on " + C.GoString(C.Py_GetPlatform())
38+}
39+
40+func (p Python) Eval(code string) {
41+ ccode := C.CString(code)
42+ defer C.free(unsafe.Pointer(ccode))
43+ C.PyRun_SimpleStringFlags(ccode, nil)
44+}
45+
46+func (p Python) EvalFile(file string, args []string) {
47+ handle := C.stdin
48+ cfile := C.CString(file)
49+ defer C.free(unsafe.Pointer(cfile))
50+
51+ if file != "-" {
52+ cmode := C.CString("r")
53+
54+ defer C.free(unsafe.Pointer(cmode))
55+ handle = C.fopen(cfile, cmode)
56+ defer C.fclose(handle)
57+ }
58+
59+ argv := C.CString(file + "\x00" + strings.Join(args, "\x00"))
60+ defer C.free(unsafe.Pointer(argv))
61+ C.pry_eval_file(handle, cfile, C.int(len(args) + 1), argv)
62+}
63+
64+func (p Python) REPL() {
65+ fn := C.CString("<stdin>")
66+ defer C.free(unsafe.Pointer(fn))
67+ C.PyRun_InteractiveLoopFlags(C.stdin, fn, nil)
68+}
69+
70+func (p Python) Close() {
71+ C.Py_Finalize()
72+}
73+
74+// exported
75+var Instance Python
src/languages/ruby/main.gonew file+83
@@ -0,0 +1,83 @@
1+package main
2+
3+
4+/*
5+#cgo pkg-config: ruby-2.5
6+#include <ruby.h>
7+#include <ruby/version.h>
8+
9+VALUE binding;
10+
11+void pry_open() {
12+ ruby_init();
13+ ruby_init_loadpath();
14+ binding = rb_binding_new();
15+}
16+
17+const char* prybar_ruby_version() {
18+ return ruby_description;
19+}
20+
21+
22+
23+char * prybar_eval(const char* code) {
24+
25+ int state;
26+ VALUE result;
27+ result = rb_eval_string_wrap(code, &state);
28+
29+ if (state)
30+ {
31+ VALUE exception = rb_errinfo();
32+ rb_set_errinfo(Qnil);
33+ if (RTEST(exception)) rb_warn("%"PRIsVALUE"", rb_funcall(exception, rb_intern("full_message"), 0));
34+ return NULL;
35+ } else {
36+ VALUE str = rb_sprintf("%"PRIsVALUE"", result);
37+ return StringValueCStr(str);
38+ }
39+
40+}
41+
42+
43+*/
44+import "C"
45+
46+import (
47+ "unsafe"
48+)
49+
50+/* */
51+type Ruby struct {
52+
53+}
54+
55+func (p Ruby) Open() {
56+ C.pry_open();
57+}
58+
59+func (p Ruby) Version() string {
60+ return C.GoString(C.prybar_ruby_version())
61+}
62+
63+func (p Ruby) Eval(code string) {
64+ p.EvalExpression(code)
65+}
66+
67+func (p Ruby) EvalExpression(code string) string {
68+ ccode := C.CString(code)
69+ defer C.free(unsafe.Pointer(ccode))
70+ res := C.prybar_eval(ccode)
71+ return C.GoString(res);
72+}
73+
74+func (p Ruby) REPL() {
75+ p.Eval("require 'irb'\nbinding.irb")
76+}
77+
78+func (p Ruby) Close() {
79+ C.ruby_cleanup(0)
80+}
81+
82+// exported
83+var Instance Ruby
src/languages/spidermonkey/main.gonew file+95
@@ -0,0 +1,95 @@
1+package main
2+
3+
4+/*
5+#cgo pkg-config: mozjs185
6+#include "jsapi.h"
7+
8+static JSClass global_class = {
9+ "global", JSCLASS_GLOBAL_FLAGS,
10+ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
11+ JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
12+ JSCLASS_NO_OPTIONAL_MEMBERS
13+};
14+
15+JSRuntime *rt;
16+JSContext *cx;
17+JSObject *global;
18+
19+int pry_open() {
20+
21+
22+ rt = JS_NewRuntime(8 * 1024 * 1024);
23+ if (rt == NULL) return 1;
24+
25+ cx = JS_NewContext(rt, 8192);
26+ if (cx == NULL) return 1;
27+
28+ JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT);
29+ JS_SetVersion(cx, JSVERSION_LATEST);
30+ //JS_SetErrorReporter(cx, reportError);
31+
32+
33+ global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
34+ if (global == NULL) return 1;
35+
36+
37+ if (!JS_InitStandardClasses(cx, global)) return 1;
38+ return 0;
39+}
40+
41+int pry_eval(const char* script) {
42+ jsval rval;
43+ JSString *str;
44+ JSBool ok;
45+ const char *filename = "noname";
46+ uintN lineno = 0;
47+
48+ ok = JS_EvaluateScript(cx, global, script, strlen(script), filename, lineno, &rval);
49+ if (rval == JS_FALSE)
50+ return 1;
51+
52+ str = JS_ValueToString(cx, rval);
53+ printf("%s\n", JS_EncodeString(cx, str));
54+}
55+
56+void pry_close() {
57+ JS_DestroyContext(cx);
58+ JS_DestroyRuntime(rt);
59+ JS_ShutDown();
60+}
61+
62+*/
63+import "C"
64+
65+import (
66+ "unsafe"
67+)
68+
69+
70+type Language struct {
71+
72+}
73+
74+func (p Language) Open() {
75+ C.pry_open()
76+}
77+
78+func (p Language) Version() string {
79+ return C.GoString(C.JS_GetImplementationVersion())
80+ //return "JS";
81+}
82+
83+func (p Language) Eval(code string) {
84+ ccode := C.CString(code)
85+ defer C.free(unsafe.Pointer(ccode))
86+ C.pry_eval(ccode)
87+}
88+
89+
90+func (p Language) Close() {
91+ C.pry_close()
92+}
93+
94+// exported
95+var Instance Language
main.go → src/main.gorenamed+7−26
@@ -2,18 +2,10 @@ package main
22
33import (
44 "fmt"
5− "os"
6− "plugin"
75 "flag"
86)
97
10−type Language interface {
11− Open()
12− Close()
13− Eval(string)
14− Version() string
15− REPL()
16−}
8+
179
1810
1911func main() {
@@ -29,35 +21,24 @@ func main() {
2921 flag.BoolVar(&quiet, "q", false, "quiet")
3022 flag.Parse()
3123
24+ args := flag.Args()
3225
33− plug, err := plugin.Open("./plugins/" + language + ".so")
34−
35− symGreeter, err := plug.Lookup("Instance")
36− if err != nil {
37− fmt.Println(err)
38− os.Exit(1)
39− }
40−
41− var lang Language
42− lang, ok := symGreeter.(Language)
43− if !ok {
44− fmt.Println("unexpected type from module symbol")
45− os.Exit(1)
46− }
26+
4727
4828 // 4. use the module
49− lang.Open()
29+ lang := GetLanguage(language)
5030 if !quiet {
5131 fmt.Println(lang.Version())
5232 }
5333 if code != "" {
5434 lang.Eval(code)
35+ } else if len(args) > 0 {
36+ lang.EvalFile(args[0], args[1:])
5537 }
5638 if interactive {
5739 lang.REPL()
5840 }
59− lang.Close()
41+
6042
6143}
6244
63−var instance Language