github.com/traefik/yaegi@v0.15.1/README.md (about)

     1  <p align="center">
     2  <img width="400" src="doc/images/yaegi.png" alt="Yaegi" title="Yaegi" />
     3  </p>
     4  
     5  [![release](https://img.shields.io/github/tag-date/traefik/yaegi.svg?label=alpha)](https://github.com/traefik/yaegi/releases)
     6  [![Build Status](https://github.com/traefik/yaegi/actions/workflows/main.yml/badge.svg)](https://github.com/traefik/yaegi/actions/workflows/main.yml)
     7  [![GoDoc](https://godoc.org/github.com/traefik/yaegi?status.svg)](https://pkg.go.dev/mod/github.com/traefik/yaegi)
     8  [![Discourse status](https://img.shields.io/discourse/https/community.traefik.io/status?label=Community&style=social)](https://community.traefik.io/c/yaegi)
     9  
    10  Yaegi is Another Elegant Go Interpreter.
    11  It powers executable Go scripts and plugins, in embedded interpreters or interactive shells, on top of the Go runtime.
    12  
    13  ## Features
    14  
    15  * Complete support of [Go specification][specs]
    16  * Written in pure Go, using only the standard library
    17  * Simple interpreter API: `New()`, `Eval()`, `Use()`
    18  * Works everywhere Go works
    19  * All Go & runtime resources accessible from script (with control)
    20  * Security: `unsafe` and `syscall` packages neither used nor exported by default
    21  * Support Go 1.18 and Go 1.19 (the latest 2 major releases)
    22  
    23  ## Install
    24  
    25  ### Go package
    26  
    27  ```go
    28  import "github.com/traefik/yaegi/interp"
    29  ```
    30  
    31  ### Command-line executable
    32  
    33  ```bash
    34  go get -u github.com/traefik/yaegi/cmd/yaegi
    35  ```
    36  
    37  Note that you can use [rlwrap](https://github.com/hanslub42/rlwrap) (install with your favorite package manager),
    38  and alias the `yaegi` command in `alias yaegi='rlwrap yaegi'` in your `~/.bashrc`, to have history and command line edition.
    39  
    40  ### CI Integration
    41  
    42  ```bash
    43  curl -sfL https://raw.githubusercontent.com/traefik/yaegi/master/install.sh | bash -s -- -b $GOPATH/bin v0.9.0
    44  ```
    45  
    46  ## Usage
    47  
    48  ### As an embedded interpreter
    49  
    50  Create an interpreter with `New()`, run Go code with `Eval()`:
    51  
    52  ```go
    53  package main
    54  
    55  import (
    56  	"github.com/traefik/yaegi/interp"
    57  	"github.com/traefik/yaegi/stdlib"
    58  )
    59  
    60  func main() {
    61  	i := interp.New(interp.Options{})
    62  
    63  	i.Use(stdlib.Symbols)
    64  
    65  	_, err := i.Eval(`import "fmt"`)
    66  	if err != nil {
    67  		panic(err)
    68  	}
    69  
    70  	_, err = i.Eval(`fmt.Println("Hello Yaegi")`)
    71  	if err != nil {
    72  		panic(err)
    73  	}
    74  }
    75  ```
    76  
    77  [Go Playground](https://play.golang.org/p/2n-EpZbMYI9)
    78  
    79  ### As a dynamic extension framework
    80  
    81  The following program is compiled ahead of time, except `bar()` which is interpreted, with the following steps:
    82  
    83  1. use of `i.Eval(src)` to evaluate the script in the context of interpreter
    84  2. use of `v, err := i.Eval("foo.Bar")` to get the symbol from the interpreter context,  as a `reflect.Value`
    85  3. application of `Interface()` method and type assertion to convert `v` into `bar`, as if it was compiled
    86  
    87  ```go
    88  package main
    89  
    90  import "github.com/traefik/yaegi/interp"
    91  
    92  const src = `package foo
    93  func Bar(s string) string { return s + "-Foo" }`
    94  
    95  func main() {
    96  	i := interp.New(interp.Options{})
    97  
    98  	_, err := i.Eval(src)
    99  	if err != nil {
   100  		panic(err)
   101  	}
   102  
   103  	v, err := i.Eval("foo.Bar")
   104  	if err != nil {
   105  		panic(err)
   106  	}
   107  
   108  	bar := v.Interface().(func(string) string)
   109  
   110  	r := bar("Kung")
   111  	println(r)
   112  }
   113  ```
   114  
   115  [Go Playground](https://play.golang.org/p/WvwH4JqrU-p)
   116  
   117  ### As a command-line interpreter
   118  
   119  The Yaegi command can run an interactive Read-Eval-Print-Loop:
   120  
   121  ```console
   122  $ yaegi
   123  > 1 + 2
   124  3
   125  > import "fmt"
   126  > fmt.Println("Hello World")
   127  Hello World
   128  >
   129  ```
   130  
   131  Note that in interactive mode, all stdlib package are pre-imported,
   132  you can use them directly:
   133  
   134  ```console
   135  $ yaegi
   136  > reflect.TypeOf(time.Date)
   137  : func(int, time.Month, int, int, int, int, int, *time.Location) time.Time
   138  >
   139  ```
   140  
   141  Or interpret Go packages, directories or files, including itself:
   142  
   143  ```console
   144  $ yaegi -syscall -unsafe -unrestricted github.com/traefik/yaegi/cmd/yaegi
   145  >
   146  ```
   147  
   148  Or for Go scripting in the shebang line:
   149  
   150  ```console
   151  $ cat /tmp/test
   152  #!/usr/bin/env yaegi
   153  package main
   154  
   155  import "fmt"
   156  
   157  func main() {
   158  	fmt.Println("test")
   159  }
   160  $ ls -la /tmp/test
   161  -rwxr-xr-x 1 dow184 dow184 93 Jan  6 13:38 /tmp/test
   162  $ /tmp/test
   163  test
   164  ```
   165  
   166  ## Documentation
   167  
   168  Documentation about Yaegi commands and libraries can be found at usual [godoc.org][docs].
   169  
   170  ## Limitations
   171  
   172  Beside the known [bugs] which are supposed to be fixed in the short term, there are some limitations not planned to be addressed soon:
   173  
   174  - Assembly files (`.s`) are not supported.
   175  - Calling C code is not supported (no virtual "C" package).
   176  - Interfaces to be used from the pre-compiled code can not be added dynamically, as it is required to pre-compile interface wrappers.
   177  - Representation of types by `reflect` and printing values using %T may give different results between compiled mode and interpreted mode.
   178  - Interpreting computation intensive code is likely to remain significantly slower than in compiled mode.
   179  
   180  Go modules are not supported yet. Until that, it is necessary to install the source into `$GOPATH/src/github.com/traefik/yaegi` to pass all the tests.
   181  
   182  ## Contributing
   183  
   184  [Contributing guide](CONTRIBUTING.md).
   185  
   186  ## License
   187  
   188  [Apache 2.0][License].
   189  
   190  [specs]: https://golang.org/ref/spec
   191  [docs]: https://pkg.go.dev/github.com/traefik/yaegi
   192  [license]: https://github.com/traefik/yaegi/blob/master/LICENSE
   193  [github]: https://github.com/traefik/yaegi
   194  [bugs]: https://github.com/traefik/yaegi/issues?q=is%3Aissue+is%3Aopen+label%3Abug