github.com/gmemcc/yaegi@v0.12.1-0.20221128122509-aa99124c5d16/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/gmemcc/yaegi/releases)
     6  [![Build Status](https://github.com/gmemcc/yaegi/actions/workflows/main.yml/badge.svg)](https://github.com/gmemcc/yaegi/actions/workflows/main.yml)
     7  [![GoDoc](https://godoc.org/github.com/gmemcc/yaegi?status.svg)](https://pkg.go.dev/mod/github.com/gmemcc/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.16 and Go 1.17 (the latest 2 major releases)
    22  
    23  ## Install
    24  
    25  ### Go package
    26  
    27  ```go
    28  import "github.com/gmemcc/yaegi/interp"
    29  ```
    30  
    31  ### Command-line executable
    32  
    33  ```bash
    34  go get -u github.com/gmemcc/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/gmemcc/yaegi/interp"
    57  	"github.com/gmemcc/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/gmemcc/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/gmemcc/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  ## Contributing
   181  
   182  [Contributing guide](CONTRIBUTING.md).
   183  
   184  ## License
   185  
   186  [Apache 2.0][License].
   187  
   188  [specs]: https://golang.org/ref/spec
   189  [docs]: https://pkg.go.dev/github.com/gmemcc/yaegi
   190  [license]: https://github.com/gmemcc/yaegi/blob/master/LICENSE
   191  [github]: https://github.com/gmemcc/yaegi
   192  [bugs]: https://github.com/gmemcc/yaegi/issues?q=is%3Aissue+is%3Aopen+label%3Abug