Skip to content

Latest commit

 

History

History
145 lines (102 loc) · 3.4 KB

README.md

File metadata and controls

145 lines (102 loc) · 3.4 KB

Yaegi

release Build Status

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

Features

  • Complete support of Go specification
  • In pure Go, using only standard library
  • Simple interpreter API: New(), Eval(), Use()
  • works everywhere Go works
  • All Go & runtime resources accessible from script (with control)
  • Security: unsafe and syscall packages not used or exported by default
  • Support Go 1.11 and Go 1.12 (the latest 2 major releases)

Install

As library

import "github.com/containous/yaegi/interp"

REPL

go get -u github.com/containous/yaegi/cmd/yaegi

Note that you can use rlwrap (install with your favorite package manager), and alias the yaegi command in alias yaegi='rlwrap yaegi' in your ~/.bashrc, to have history and command line edition.

Usage

As a command line interpreter

The Yaegi command can run an interactive Read-Eval-Print-Loop:

$ yaegi
> 1 + 2
3
> import "fmt"
> fmt.Println("Hello World")
Hello World
>

Or interpret Go files:

$ yaegi cmd/yaegi/yaegi.go
>

As an embedded interpreter

Create an interpreter with New(), run Go code with Eval():

package main

import (
	"github.com/containous/yaegi/interp"
	"github.com/containous/yaegi/stdlib"
)

func main() {
	i := interp.New(interp.Options{})

	i.Use(stdlib.Symbols)

	_, err := i.Eval(`import "fmt"`)
	if err != nil {
		panic(err)
	}

	_, err = i.Eval(`fmt.Println("hello")`)
	if err != nil {
		panic(err)
	}
}

As a dynamic extension framework

The following program is compiled ahead of time, except bar() which is interpreted, with the following steps:

  1. use of i.Eval(src) to evaluate the script in the context of interpreter
  2. use of v, err := i.Eval("foo.Bar") to get the symbol from the interpreter context, as a reflect.Value
  3. application of Interface() method and type assertion to convert v into bar, as if it was compiled
package main

import "github.com/containous/yaegi/interp"

const src = `package foo
func Bar(s string) string { return s + "-Foo" }`

func main() {
	i := interp.New(interp.Options{})

	_, err := i.Eval(src)
	if err != nil {
		panic(err)
	}

	v, err := i.Eval("foo.Bar")
	if err != nil {
		panic(err)
	}

	bar := v.Interface().(func(string) string)

	r := bar("Kung")
	println(r)
}

Documentation

Documentation about Yaegi commands and libraries can be found at usual godoc.org.

Contributing

Yaegi is an open source project, and your feedback and contributions are needed and always welcome.

Issues and pull requests are opened at https://github.com/containous/yaegi

License

Apache 2.0.