Compare commits

...

9 Commits

Author SHA1 Message Date
Ludovic Fernandez
373e3204b4 chore: revert stdlib improvements 2019-07-26 22:36:03 -07:00
Marc Vertes
5f41fcb8bc doc: add a Limitations section in README 2019-07-26 20:56:03 -07:00
Ludovic Fernandez
43b8594c82 feat: improve stdlib generation. 2019-07-26 17:10:04 -07:00
Marc Vertes
4c877cc348 fix: correct assign to binary interface value (#291) 2019-07-26 10:59:16 -07:00
Marc Vertes
f199520048 doc: first attempt to document goexports command 2019-07-25 23:02:03 -07:00
Taufiq Rahman
4df03252f6 doc: Fixes the title and other formattings 2019-07-25 12:06:03 -07:00
Ludovic Fernandez
2dfede3b90 doc: add playground examples. 2019-07-25 09:08:03 -07:00
Fernandez Ludovic
6191f5d38a chore: add godoc badge. 2019-07-24 22:01:51 -07:00
Ludovic Fernandez
24db786bb6 fix: exclude syslog for windows, nacl, and plan9. 2019-07-24 18:58:04 -07:00
6 changed files with 105 additions and 47 deletions

View File

@@ -4,6 +4,7 @@
[![release](https://img.shields.io/github/tag-date/containous/yaegi.svg?label=alpha)](https://github.com/containous/yaegi/releases)
[![Build Status](https://travis-ci.com/containous/yaegi.svg?branch=master)](https://travis-ci.com/containous/yaegi)
[![GoDoc](https://godoc.org/github.com/containous/yaegi?status.svg)](https://godoc.org/github.com/containous/yaegi)
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.
@@ -11,22 +12,22 @@ It powers executable Go scripts and plugins, in embedded interpreters or interac
## Features
* Complete support of [Go specification][specs]
* In pure Go, using only standard library
* Written in pure Go, using only the standard library
* Simple interpreter API: `New()`, `Eval()`, `Use()`
* works everywhere Go works
* Works everywhere Go works
* All Go & runtime resources accessible from script (with control)
* Security: `unsafe` and `syscall` packages not used or exported by default
* Security: `unsafe` and `syscall` packages neither used nor exported by default
* Support Go 1.11 and Go 1.12 (the latest 2 major releases)
## Install
### As library
### Go package
```go
import "github.com/containous/yaegi/interp"
```
### REPL
### Command-line executable
```bash
go get -u github.com/containous/yaegi/cmd/yaegi
@@ -37,27 +38,6 @@ and alias the `yaegi` command in `alias yaegi='rlwrap yaegi'` in your `~/.bashrc
## Usage
### As a command line interpreter
The Yaegi command can run an interactive Read-Eval-Print-Loop:
```console
$ yaegi
> 1 + 2
3
> import "fmt"
> fmt.Println("Hello World")
Hello World
>
```
Or interpret Go files:
```console
$ yaegi cmd/yaegi/yaegi.go
>
```
### As an embedded interpreter
Create an interpreter with `New()`, run Go code with `Eval()`:
@@ -80,13 +60,15 @@ func main() {
panic(err)
}
_, err = i.Eval(`fmt.Println("hello")`)
_, err = i.Eval(`fmt.Println("Hello Yaegi")`)
if err != nil {
panic(err)
}
}
```
[Go Playground](https://play.golang.org/p/zzvw4VlerLP)
### As a dynamic extension framework
The following program is compiled ahead of time, except `bar()` which is interpreted, with the following steps:
@@ -123,10 +105,43 @@ func main() {
}
```
[Go Playground](https://play.golang.org/p/6SEAoaO7n0U)
### As a command-line interpreter
The Yaegi command can run an interactive Read-Eval-Print-Loop:
```console
$ yaegi
> 1 + 2
3
> import "fmt"
> fmt.Println("Hello World")
Hello World
>
```
Or interpret Go files:
```console
$ yaegi cmd/yaegi/yaegi.go
>
```
## Documentation
Documentation about Yaegi commands and libraries can be found at usual [godoc.org][docs].
## Limitations
Beside the known [bugs] which are supposed to be fixed in the short term, there are some limitations not planned to be addressed soon:
- assembly files (`.s`) are not supported
- calling C code is not supported (no virtual "C" package)
- interfaces to be used from the pre-compiled code can not be added dynamically, as it is required to pre-compile interface wrappers
- representation of types by `reflect` and printing values using %T may give different results between compiled mode and interpreted mode
- interpreting computation intensive code is likely to remain significantly slower than in compiled mode
## Contributing
Yaegi is an open source project, and your feedback and contributions are needed and always welcome.
@@ -143,3 +158,4 @@ Yaegi is an open source project, and your feedback and contributions are needed
[github]: https://github.com/containous/yaegi
[Issues]: https://github.com/containous/yaegi/issues
[pull requests]: https://github.com/containous/yaegi/issues
[bugs]: https://github.com/containous/yaegi/issues?q=is%3Aissue+is%3Aopen+label%3Abug

18
_test/interface9.go Normal file
View File

@@ -0,0 +1,18 @@
package main
import "fmt"
type Int int
func (I Int) String() string {
return "foo"
}
func main() {
var i Int
var st fmt.Stringer = i
fmt.Println(st.String())
}
// Output:
// foo

View File

@@ -1,8 +1,21 @@
//go:generate go build
// This program generates code to register binary program symbols to the interpreter.
// See stdlib.go for usage
/*
Goexports generates wrappers of package exported symbols
Output files are written in the current directory, and prefixed with the go version.
Usage:
goexports package...
Example:
goexports github.com/containous/yaegi/interp
The same goexport program is used for all target operating systems and architectures.
The GOOS and GOARCH environment variables set the desired target.
*/
package main
import (
@@ -22,8 +35,8 @@ import (
"text/template"
)
const model = `// +build {{.CurrentGoVersion}},!{{.NextGoVersion}}
const model = `// +build {{.BuildTags}}
package {{.Dest}}
// Code generated by 'goexports {{.PkgName}}'. DO NOT EDIT.
@@ -120,6 +133,7 @@ func genContent(dest, pkgName string) ([]byte, error) {
if !o.Exported() {
continue
}
pname := path.Base(pkgName) + "." + name
switch o := o.(type) {
case *types.Const:
@@ -137,11 +151,12 @@ func genContent(dest, pkgName string) ([]byte, error) {
if !f.Exported() {
continue
}
sig := f.Type().(*types.Signature)
args := make([]string, sig.Params().Len())
sign := f.Type().(*types.Signature)
args := make([]string, sign.Params().Len())
params := make([]string, len(args))
for j := range args {
v := sig.Params().At(j)
v := sign.Params().At(j)
if args[j] = v.Name(); args[j] == "" {
args[j] = fmt.Sprintf("a%d", j)
}
@@ -149,16 +164,19 @@ func genContent(dest, pkgName string) ([]byte, error) {
}
arg := "(" + strings.Join(args, ", ") + ")"
param := "(" + strings.Join(params, ", ") + ")"
results := make([]string, sig.Results().Len())
results := make([]string, sign.Results().Len())
for j := range results {
v := sig.Results().At(j)
v := sign.Results().At(j)
results[j] = v.Name() + " " + types.TypeString(v.Type(), qualify)
}
result := "(" + strings.Join(results, ", ") + ")"
ret := ""
if sig.Results().Len() > 0 {
if sign.Results().Len() > 0 {
ret = "return"
}
methods = append(methods, Method{f.Name(), param, result, arg, ret})
}
wrap[name] = Wrap{prefix + name, methods}
@@ -181,16 +199,20 @@ func genContent(dest, pkgName string) ([]byte, error) {
return nil, fmt.Errorf("template parsing error: %v", err)
}
buildTags := currentGoVersion + ",!" + nextGoVersion
if pkgName == "log/syslog" {
buildTags += ",!windows,!nacl,!plan9"
}
b := &bytes.Buffer{}
data := map[string]interface{}{
"Dest": dest,
"Imports": imports,
"PkgName": pkgName,
"Val": val,
"Typ": typ,
"Wrap": wrap,
"CurrentGoVersion": currentGoVersion,
"NextGoVersion": nextGoVersion,
"Dest": dest,
"Imports": imports,
"PkgName": pkgName,
"Val": val,
"Typ": typ,
"Wrap": wrap,
"BuildTags": buildTags,
}
err = parse.Execute(b, data)
if err != nil {

View File

@@ -223,6 +223,8 @@ func assign(n *node) {
switch {
case dest.typ.cat == interfaceT:
svalue[i] = genValueInterface(src)
case dest.typ.cat == valueT && dest.typ.rtype.Kind() == reflect.Interface:
svalue[i] = genInterfaceWrapper(src, dest.typ.rtype)
case dest.typ.cat == valueT && src.typ.cat == funcT:
svalue[i] = genFunctionWrapper(src)
case src.kind == basicLit && src.val == nil:

View File

@@ -1,4 +1,4 @@
// +build go1.11,!go1.12
// +build go1.11,!go1.12,!windows,!nacl,!plan9
package stdlib

View File

@@ -1,4 +1,4 @@
// +build go1.12,!go1.13
// +build go1.12,!go1.13,!windows,!nacl,!plan9
package stdlib