igop - The Go+ interpreter

igop - The Go+ interpreter (still in beta version)

Go Report Card GitHub release Playground VSCode GoDoc

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
Owner
GoPlus
The GoPlus (Go+) Programming Language
GoPlus
Comments
  • 0.9.1 version cannot be compiled

    0.9.1 version cannot be compiled

    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)
    
  • how to execute with custom environment variables

    how to execute with custom environment variables

    like exec/cmd cmd := exec.CommandContext(...) cmd.Env = ....

    env := map[string]string{"X": "Y"}
    
    ctx := igop.NewContext(0)
    ctx.Env = env
    ctx.Run(....)
    
  • what's package name of subfolder that import it

    what's package name of subfolder that import it

    - io_extra/
      - file.go
    - main.go
    

    how to import io_extra/file.go in main.go?

    import "io_extra"
    

    panic:

    could not import io_extra (not found provider for types.Importer)

  • pkg: default remove net/rpc net/rpc/jsonrpc

    pkg: default remove net/rpc net/rpc/jsonrpc

    igop default load net/rpc and net/rpc/jsonrpc from source

    igop hook reflect api

    • reflect.Type.Method => reflectx.MethodByIndex
    • reflect.Type.MethodByName => reflectx.MethodByName
  • qexp: fast export

    qexp: fast export

    fix https://github.com/goplus/igop/issues/153

    • remove ssa builder
    • fast export multiple pkgs
    • support pkg/...
    • support empty exported pkg. eg time/tzdata
    • igop: add sub cmd export
  • check unsafe.Slice len out of range

    check unsafe.Slice len out of range

    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()
    	}
    }
    
  • unsafe.Slice for go1.18

    unsafe.Slice for go1.18

    $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) })
    
  • implement runtime callers

    implement runtime callers

    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 func$thunk T.f -> runtime main.T.f func$thunk (struct{ T }).f -> runtime go.struct { main.T }.main.f 1

    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
    }
    
  • "-addtags custom tags" does not support build tags?

    .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

  • support nested type-parameterized declarations

    support nested type-parameterized declarations

    https://github.com/golang/go/blob/master/test/typeparam/nested.go

    typeparam func

    • named sig: pkgpath.name[farg1,frag2;targ1,targ2]

    TODO

    • types.Type->reflect.Type: use types scope
  • bug: ssa select case call expr order

    bug: ssa select case call expr order

    $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
    
  • bug: golang fixedbugs/issue23017.go

    bug: golang fixedbugs/issue23017.go

    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))
    	}
    }
    
  • TODO: $GOROOT/test/fixedbugs

    TODO: $GOROOT/test/fixedbugs

    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"
    	}
    }
    
Related tags
Writing an interpreter in Go!

Monkey Language Writing a interpreter to the turing complete Monkey Language in Go. Following the book: Writing an interpreter in Go Examples let add

Feb 10, 2022
Interpreter - The Official Interpreter for the Infant Lang written in Go

Infant Lang Interpreter Infant Lang Minimalistic Less Esoteric Programming Langu

Jan 10, 2022
Scriptable interpreter written in golang
Scriptable interpreter written in golang

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

Jan 1, 2023
A shell parser, formatter, and interpreter with bash support; includes shfmt

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

Dec 29, 2022
Scriptable interpreter written in golang
Scriptable interpreter written in golang

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

Dec 23, 2022
A POSIX-compliant AWK interpreter written in Go

GoAWK: an AWK interpreter written in Go AWK is a fascinating text-processing language, and somehow after reading the delightfully-terse The AWK Progra

Dec 31, 2022
A BASIC interpreter written in golang.
A BASIC interpreter written in golang.

05 PRINT "Index" 10 PRINT "GOBASIC!" 20 PRINT "Limitations" Arrays Line Numbers IF Statement DATA / READ Statements Builtin Functions Types 30 PRINT "

Dec 24, 2022
Prolog interpreter in Go

golog Prolog interpreter in Go with aspirations to be ISO compatible. See the full package documentation for usage details. Install with go get github

Nov 12, 2022
A simple virtual machine - compiler & interpreter - written in golang

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

Dec 17, 2022
A JavaScript interpreter in Go (golang)

otto -- import "github.com/robertkrimen/otto" Package otto is a JavaScript parser and interpreter written natively in Go. http://godoc.org/github.com/

Jan 2, 2023
Yaegi is Another Elegant Go Interpreter
Yaegi is Another Elegant Go Interpreter

Yaegi is Another Elegant Go Interpreter. It powers executable Go scripts and plugins, in embedded interpreters or interactive shells, on top of the Go

Dec 30, 2022
A shell parser, formatter, and interpreter with bash support; includes shfmt

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

Jan 8, 2023
Simple in Pure Go in Browser Interactive Interpreter
Simple in Pure Go in Browser Interactive Interpreter

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

Feb 22, 2022
Lisp Interpreter

golisp Lisp Interpreter Usage $ golisp < foo.lisp Installation $ go get github.com/mattn/golisp/cmd/golisp Features Call Go functions. Print random in

Dec 15, 2022
Mini lisp interpreter written in Go.

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

Nov 25, 2022
Toy Lisp 1.5 interpreter

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

Jan 1, 2023
A JavaScript interpreter in Go (golang)

otto -- import "github.com/robertkrimen/otto" Package otto is a JavaScript parser and interpreter written natively in Go. http://godoc.org/github.com/

Jan 2, 2023
gpython is a python interpreter written in go "batteries not included"

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

Dec 28, 2022
wagon, a WebAssembly-based Go interpreter, for Go.

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

Dec 6, 2022
Yaegi is Another Elegant Go Interpreter
Yaegi is Another Elegant Go Interpreter

Yaegi is Another Elegant Go Interpreter. It powers executable Go scripts and plugins, in embedded interpreters or interactive shells, on top of the Go

Jan 5, 2023