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