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 [](https://github.com/switchupcb/yaegi/releases) 6 [](https://github.com/switchupcb/yaegi/actions/workflows/main.yml) 7 [](https://pkg.go.dev/mod/github.com/switchupcb/yaegi) 8 [](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