igop - The Go+ interpreter (still in beta version)
Support multiple engines
How to build
git clone [email protected]:goplus/igop.git
cd igop
go install -tags yaegi -v ./... # you can replace `yaegi` to `igo` or other engines
git clone [email protected]:goplus/igop.git
cd igop
go install -tags yaegi -v ./... # you can replace `yaegi` to `igo` or other engines
igop 0.9.1
\load\embed_go116.go:94:29: not enough arguments in call to r.Load
r.Load(bp.Dir, v)
\go\pkg\mod\github.com\visualfc\[email protected]\resolve.go
Load(dir string, fset *token.FileSet, em *Embed) ([]*File, error)
like exec/cmd cmd := exec.CommandContext(...) cmd.Env = ....
env := map[string]string{"X": "Y"}
ctx := igop.NewContext(0)
ctx.Env = env
ctx.Run(....)
- io_extra/
- file.go
- main.go
how to import io_extra/file.go in main.go?
import "io_extra"
panic:
enhancementcould not import io_extra (not found provider for types.Importer)
igop default load net/rpc and net/rpc/jsonrpc from source
igop hook reflect api
fix https://github.com/goplus/igop/issues/153
fix https://github.com/goplus/igop/issues/178
runtime.unsafeslice
func unsafeslice(et *_type, ptr unsafe.Pointer, len int) {
if len < 0 {
panicunsafeslicelen()
}
mem, overflow := math.MulUintptr(et.size, uintptr(len))
if overflow || mem > -uintptr(ptr) {
if ptr == nil {
panic(errorString("unsafe.Slice: ptr is nil and len is not zero"))
}
panicunsafeslicelen()
}
}
$GOROOT/test/unsafebuiltins.go
// sliced memory overflows address space
last := (*byte)(unsafe.Pointer(^uintptr(0)))
_ = unsafe.Slice(last, 1)
mustPanic(func() { _ = unsafe.Slice(last, 2) })
enhancement
implement runtime func
runtime.Caller
runtime.FuncForPC
runtime.Callers
(*runtime.Frames).Next
(*runtime.Func).FileLine
(reflect.Value).Pointer
runtime.Stack
runtime/debug.Stack
runtime/debug.PrintStack
*runtime.Stack(bug []uint8, all bool) always = runtime.Stack(buf, false)
ssa method wrapper
func$bound T(0).f -> runtime main.T.f-fm
type T int
func (T) f() int
func (*T) g()
var (
// thunks
a = T.f
b = T.f
c = (struct{ T }).f
d = (struct{ T }).f
e = (*T).g
f = (*T).g
g = (struct{ *T }).g
h = (struct{ *T }).g
// bounds
i = T(0).f
j = T(0).f
k = new(T).g
l = new(T).g
}
.go file //go:build sep // +build sep igop export -addtags sep -outdir pkg packagepath
errors: undeclared name: SetVersion Menu not declared by package call undeclared name: xxxxx
enhancementhttps://github.com/golang/go/blob/master/test/typeparam/nested.go
typeparam func
TODO
$GOROOT/test/chan/select5
bug: golang.org/x/tools/go/ssa build order fp, fc
package main
var c = make(chan int, 1)
var nilch chan int
var n = 1
var x int
var i interface{}
var dummy = make(chan int)
var m = make(map[int]int)
var order = 0
// check order of operations by ensuring that
// successive calls to checkorder have increasing o values.
func checkorder(o int) {
if o <= order {
println("invalid order", o, "after", order)
panic("order")
}
order = o
}
func fc(c chan int, o int) chan int {
checkorder(o)
return c
}
func fp(p *int, o int) *int {
checkorder(o)
return p
}
func init() {
order = 0
c <- n
select {
case *fp(&x, 100) = <-fc(c, 1):
}
if x != n {
die(x)
}
n++
}
func die(x int) {
println("have", x, "want", n)
panic("chan")
}
func main() {
}
func init#1():
0: entry P:0 S:2
*order = 0:int
t0 = *c chan int
t1 = *n int
send t0 <- t1
t2 = fp(x, 100:int) *int
t3 = *c chan int
t4 = fc(t3, 1:int) chan int
t5 = <-t4 int
*t2 = t5
t6 = *x int
t7 = *n int
t8 = t6 != t7 bool
if t8 goto 1 else 2
1: if.then P:1 S:1
t9 = *x int
t10 = die(t9) ()
jump 2
2: if.done P:2 S:0
t11 = *n int
t12 = t11 + 1:int int
*n = t12
return
package main
import (
"fmt"
)
func main() {
type P struct{ i int }
var m = map[int]int{}
var p *P
defer func() {
recover()
check(1, len(m))
check(3, m[2])
}()
m[2], p.i = 3, 2
}
func check(want, got int) {
if want != got {
panic(fmt.Sprintf("wanted %d, but got %d", want, got))
}
}
https://github.com/goplus/igop/blob/main/cmd/igoptest/main.go
func init() {
if runtime.GOARCH == "386" {
gorootTestSkips["printbig.go"] = "load failed"
gorootTestSkips["peano.go"] = "stack overflow"
}
gorootTestSkips["closure.go"] = "runtime.ReadMemStats"
gorootTestSkips["divmod.go"] = "slow, 1m18s"
gorootTestSkips["copy.go"] = "slow, 13s"
gorootTestSkips["finprofiled.go"] = "slow, 21s"
gorootTestSkips["gcgort.go"] = "slow, 2s"
gorootTestSkips["nilptr.go"] = "skip drawin"
gorootTestSkips["heapsampling.go"] = "runtime.MemProfileRecord"
gorootTestSkips["makeslice.go"] = "TODO, panic info, allocation size out of range"
gorootTestSkips["stackobj.go"] = "skip gc"
gorootTestSkips["stackobj3.go"] = "skip gc"
gorootTestSkips["nilptr_aix.go"] = "skip"
gorootTestSkips["init1.go"] = "skip gc"
gorootTestSkips["ken/divconst.go"] = "slow, 3.5s"
gorootTestSkips["ken/modconst.go"] = "slow, 3.3s"
gorootTestSkips["fixedbugs/issue24491b.go"] = "timeout"
gorootTestSkips["fixedbugs/issue16249.go"] = "slow, 4.5s"
gorootTestSkips["fixedbugs/issue13169.go"] = "slow, 5.9s"
gorootTestSkips["fixedbugs/issue11656.go"] = "ignore"
gorootTestSkips["fixedbugs/issue15281.go"] = "runtime.ReadMemStats"
gorootTestSkips["fixedbugs/issue18149.go"] = "runtime.Caller macos //line not support c:/foo/bar.go:987"
gorootTestSkips["fixedbugs/issue22662.go"] = "runtime.Caller got $goroot/test/fixedbugs/foo.go:1; want foo.go:1"
gorootTestSkips["fixedbugs/issue27518b.go"] = "BUG, runtime.SetFinalizer"
gorootTestSkips["fixedbugs/issue32477.go"] = "BUG, runtime.SetFinalizer"
gorootTestSkips["fixedbugs/issue41239.go"] = "BUG, reflect.Append: different capacity on append"
gorootTestSkips["fixedbugs/issue32477.go"] = "BUG, runtime.SetFinalizer"
gorootTestSkips["fixedbugs/issue45175.go"] = "BUG, ssa.Phi call order"
gorootTestSkips["fixedbugs/issue4618.go"] = "testing.AllocsPerRun"
gorootTestSkips["fixedbugs/issue4667.go"] = "testing.AllocsPerRun"
gorootTestSkips["fixedbugs/issue8606b.go"] = "BUG, optimization check"
gorootTestSkips["fixedbugs/issue30116u.go"] = "BUG, slice bound check"
gorootTestSkips["chan/select5.go"] = "bug, select case expr call order"
// fixedbugs/issue7740.go
// const ulp = (1.0 + (2.0 / 3.0)) - (5.0 / 3.0)
// Go 1.14 1.15 1.16 ulp = 1.4916681462400413e-154
// Go 1.17 1.18 ulp = 0
ver := runtime.Version()[:6]
switch ver {
case "go1.17", "go1.18", "go1.19":
gorootTestSkips["fixedbugs/issue45045.go"] = "runtime.SetFinalizer"
gorootTestSkips["fixedbugs/issue46725.go"] = "runtime.SetFinalizer"
gorootTestSkips["abi/fibish.go"] = "slow, 34s"
gorootTestSkips["abi/fibish_closure.go"] = "slow, 35s"
gorootTestSkips["abi/uglyfib.go"] = "5m48s"
gorootTestSkips["fixedbugs/issue23017.go"] = "BUG"
gorootTestSkips["typeparam/chans.go"] = "runtime.SetFinalizer"
gorootTestSkips["typeparam/issue376214.go"] = "build SSA package error: variadic parameter must be of unnamed slice type"
gorootTestSkips["typeparam/nested.go"] = "FAIL"
case "go1.16":
gorootTestSkips["fixedbugs/issue7740.go"] = "BUG, const float"
case "go1.15":
gorootTestSkips["fixedbugs/issue15039.go"] = "BUG, uint64 -> string"
gorootTestSkips["fixedbugs/issue9355.go"] = "TODO, chdir"
gorootTestSkips["fixedbugs/issue7740.go"] = "BUG, const float"
case "go1.14":
gorootTestSkips["fixedbugs/issue9355.go"] = "TODO, chdir"
gorootTestSkips["fixedbugs/issue7740.go"] = "BUG, const float"
}
if runtime.GOOS == "windows" {
gorootTestSkips["env.go"] = "skip GOARCH"
gorootTestSkips["fixedbugs/issue15002.go"] = "skip windows"
gorootTestSkips["fixedbugs/issue5493.go"] = "skip windows"
gorootTestSkips["fixedbugs/issue5963.go"] = "skip windows"
skips := make(map[string]string)
for k, v := range gorootTestSkips {
skips[filepath.FromSlash(k)] = v
}
gorootTestSkips = skips
} else if runtime.GOOS == "darwin" {
gorootTestSkips["locklinear.go"] = "skip github"
}
}
support go1.20rc1
update dep for support gopherjs
Source code(tar.gz)igop export
= qexp
implement runtime callers
runtime.Caller
runtime.FuncForPC
runtime.Callers
runtime.CallersFrames
(*runtime.Frames).Next
(*runtime.Func).FileLine
(reflect.Value).Pointer
runtime.Stack
runtime/debug.Stack
runtime/debug.PrintStack
Source code(tar.gz)support Go1.19
Source code(tar.gz)Go+ v1.1.0
Source code(tar.gz)changes:
gossa
to igop
Monkey Language Writing a interpreter to the turing complete Monkey Language in Go. Following the book: Writing an interpreter in Go Examples let add
Infant Lang Interpreter Infant Lang Minimalistic Less Esoteric Programming Langu
Anko Anko is a scriptable interpreter written in Go. (Picture licensed under CC BY-SA 3.0, photo by Ocdp) Usage Example - Embedded package main impor
sh A shell parser, formatter, and interpreter. Supports POSIX Shell, Bash, and mksh. Requires Go 1.14 or later. Quick start To parse shell scripts, in
Anko Anko is a scriptable interpreter written in Go. (Picture licensed under CC BY-SA 3.0, photo by Ocdp) Usage Example - Embedded package main impor
GoAWK: an AWK interpreter written in Go AWK is a fascinating text-processing language, and somehow after reading the delightfully-terse The AWK Progra
05 PRINT "Index" 10 PRINT "GOBASIC!" 20 PRINT "Limitations" Arrays Line Numbers IF Statement DATA / READ Statements Builtin Functions Types 30 PRINT "
golog Prolog interpreter in Go with aspirations to be ISO compatible. See the full package documentation for usage details. Install with go get github
go.vm Installation Build without Go Modules (Go before 1.11) Build with Go Modules (Go 1.11 or higher) Usage Opcodes Notes The compiler The interprete
otto -- import "github.com/robertkrimen/otto" Package otto is a JavaScript parser and interpreter written natively in Go. http://godoc.org/github.com/
Yaegi is Another Elegant Go Interpreter. It powers executable Go scripts and plugins, in embedded interpreters or interactive shells, on top of the Go
sh A shell parser, formatter, and interpreter. Supports POSIX Shell, Bash, and mksh. Requires Go 1.14 or later. Quick start To parse shell scripts, in
GoBook This project is a PoC Don't take it seriously The main point of this project is the use of the library: github.com/brendonmatos/golive Maybe th
golisp Lisp Interpreter Usage $ golisp < foo.lisp Installation $ go get github.com/mattn/golisp/cmd/golisp Features Call Go functions. Print random in
Mini Go Lisp Mini lisp interpreter written in Go. It is implemented with reference to the d-tsuji/SDLisp repository written in Java. Support System Fu
Lisp 1.5 To install: go get robpike.io/lisp. This is an implementation of the language defined, with sublime concision, in the first few pages of the
otto -- import "github.com/robertkrimen/otto" Package otto is a JavaScript parser and interpreter written natively in Go. http://godoc.org/github.com/
gpython gpython is a part re-implementation / part port of the Python 3.4 interpreter to the Go language, "batteries not included". It includes: runti
wagon wagon is a WebAssembly-based interpreter in Go, for Go. As of 2020/05/11 Wagon is in read-only mode, and looking for a maintainer. You may want
Yaegi is Another Elegant Go Interpreter. It powers executable Go scripts and plugins, in embedded interpreters or interactive shells, on top of the Go