Documentation ¶
Overview ¶
Package vm implements virtual-machine for anko.
Example (VmBasicOperators) ¶
package main import ( "fmt" "log" "github.com/mattn/anko/vm" ) func main() { env := vm.NewEnv() err := env.Define("println", fmt.Println) if err != nil { log.Fatalf("Define error: %v\n", err) } script := ` a = nil println(a) a = true println(a) println("") a = 2 + 1 println(a) a = 2 - 1 println(a) a = 2 * 1 println(a) a = 4 / 2 println(a) println("") a = 1 a++ println(a) a-- println(a) println("") a = 1 a += 1 println(a) a -= 1 println(a) a *= 4 println(a) a /= 2 println(a) println("") a = 2 ** 3 println(a) a = 1 & 3 println(a) a = 1 | 2 println(a) println("") a = 2 << 3 println(a) a = 8 >> 2 println(a) a = 7 % 3 println(a) println("") a = 2 - (-2) println(a) a = ^2 println(a) a = "a" * 4 println(a) a = !true println(a) ` _, err = env.Execute(script) if err != nil { log.Fatalf("Execute error: %v\n", err) } }
Output: <nil> true 3 1 2 2 2 1 2 1 4 2 8 1 3 16 2 1 4 -3 aaaa false
Example (VmComparisonOperators) ¶
package main import ( "fmt" "log" "github.com/mattn/anko/vm" ) func main() { env := vm.NewEnv() err := env.Define("println", fmt.Println) if err != nil { log.Fatalf("Define error: %v\n", err) } script := ` a = nil == nil println(a) a = "a" != "a" println(a) a = 1 == 1.0 println(a) a = !true println(a) println("") a = 1 < 2 println(a) a = 1 > 3 println(a) a = 2 <= 2 println(a) a = 2 >= 3 println(a) println("") a = 1 == 2 && 1 == 1 println(a) a = 1 == 2 || 1 == 1 println(a) ` _, err = env.Execute(script) if err != nil { log.Fatalf("Execute error: %v\n", err) } }
Output: true false true false true false true false false true
Example (VmHelloWorld) ¶
package main import ( "fmt" "log" "github.com/mattn/anko/vm" ) func main() { env := vm.NewEnv() err := env.Define("println", fmt.Println) if err != nil { log.Fatalf("Define error: %v\n", err) } script := ` println("Hello World :)") ` _, err = env.Execute(script) if err != nil { log.Fatalf("Execute error: %v\n", err) } }
Output: Hello World :)
Index ¶
- Variables
- func ClearInterrupt(env *Env)
- func Interrupt(env *Env)
- func Run(stmts []ast.Stmt, env *Env) (interface{}, error)
- func RunSingleStmt(stmt ast.Stmt, env *Env) (interface{}, error)
- type Env
- func (e *Env) AddPackage(name string, methods map[string]interface{}, types map[string]interface{}) (*Env, error)
- func (e *Env) Addr(k string) (reflect.Value, error)
- func (e *Env) Define(k string, v interface{}) error
- func (e *Env) DefineGlobal(k string, v interface{}) error
- func (e *Env) DefineGlobalReflectType(k string, t reflect.Type) error
- func (e *Env) DefineGlobalType(k string, t interface{}) error
- func (e *Env) DefineReflectType(k string, t reflect.Type) error
- func (e *Env) DefineType(k string, t interface{}) error
- func (e *Env) Destroy()
- func (e *Env) Dump()
- func (e *Env) Execute(src string) (interface{}, error)
- func (e *Env) Get(k string) (interface{}, error)
- func (e *Env) GetName() string
- func (e *Env) NewEnv() *Env
- func (e *Env) NewModule(n string) *Env
- func (e *Env) NewPackage(n string) *Env
- func (e *Env) Set(k string, v interface{}) error
- func (e *Env) SetExternal(res EnvResolver)
- func (e *Env) SetName(n string)
- func (e *Env) String() string
- func (e *Env) Type(k string) (reflect.Type, error)
- type EnvResolver
- type Error
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // BreakError when there is an unexpected break statement BreakError = errors.New("Unexpected break statement") // ContinueError when there is an unexpected continue statement ContinueError = errors.New("Unexpected continue statement") // ReturnError when there is an unexpected return statement ReturnError = errors.New("Unexpected return statement") // InterruptError when execution has been interrupted InterruptError = errors.New("Execution interrupted") )
Functions ¶
func ClearInterrupt ¶
func ClearInterrupt(env *Env)
ClearInterrupt removes the interrupt flag from specified environment. This includes all parent & child environments.
func Interrupt ¶
func Interrupt(env *Env)
Interrupt interrupts the execution of any running statements in the specified environment. This includes all parent & child environments. Note that the execution is not instantly aborted: after a call to Interrupt, the current running statement will finish, but the next statement will not run, and instead will return a nilValue and an InterruptError.
Example ¶
package main import ( "fmt" "log" "sync" "time" "github.com/mattn/anko/vm" ) func main() { var waitGroup sync.WaitGroup waitGroup.Add(1) waitChan := make(chan struct{}, 1) env := vm.NewEnv() sleepMillisecond := func() { time.Sleep(time.Millisecond) } err := env.Define("println", fmt.Println) if err != nil { log.Fatalf("Define error: %v\n", err) } err = env.Define("sleep", sleepMillisecond) if err != nil { log.Fatalf("Define error: %v\n", err) } script := ` # sleep for 10 seconds for i = 0; i < 10000; i++ { sleep() } # Should interrupt before printing the next line println("this line should not be printed") ` go func() { close(waitChan) v, err := env.Execute(script) fmt.Println(v, err) waitGroup.Done() }() <-waitChan vm.Interrupt(env) waitGroup.Wait() }
Output: <nil> Execution interrupted
Types ¶
type Env ¶
Env provides interface to run VM. This mean function scope and blocked-scope. If stack goes to blocked-scope, it will make new Env.
func (*Env) AddPackage ¶
func (e *Env) AddPackage(name string, methods map[string]interface{}, types map[string]interface{}) (*Env, error)
AddPackage creates a new env with a name that has methods and types in it. Created under the parent env
func (*Env) Addr ¶
Addr returns pointer value which specified symbol. It goes to upper scope until found or returns error.
func (*Env) Define ¶
Define defines symbol in current scope.
Example ¶
package main import ( "fmt" "log" "github.com/mattn/anko/vm" ) func main() { env := vm.NewEnv() env.SetName("myName") err := env.Define("println", fmt.Println) if err != nil { log.Fatalf("Define error: %v\n", err) } err = env.Define("a", true) if err != nil { log.Fatalf("Define error: %v\n", err) } err = env.Define("b", int64(1)) if err != nil { log.Fatalf("Define error: %v\n", err) } err = env.Define("c", float64(1.1)) if err != nil { log.Fatalf("Define error: %v\n", err) } err = env.Define("d", "d") if err != nil { log.Fatalf("Define error: %v\n", err) } err = env.Define("e", []interface{}{true, int64(1), float64(1.1), "d"}) if err != nil { log.Fatalf("Define error: %v\n", err) } err = env.Define("f", map[string]interface{}{"a": true}) if err != nil { log.Fatalf("Define error: %v\n", err) } script := ` println(a) println(b) println(c) println(d) println(e) println(f) ` _, err = env.Execute(script) if err != nil { log.Fatalf("Execute error: %v\n", err) } }
Output: true 1 1.1 d [true 1 1.1 d] map[a:true]
func (*Env) DefineGlobal ¶
DefineGlobal defines symbol in global scope.
func (*Env) DefineGlobalReflectType ¶
DefineGlobalReflectType defines type in global scope.
func (*Env) DefineGlobalType ¶
DefineGlobalType defines type in global scope.
func (*Env) DefineReflectType ¶
DefineReflectType defines type in current scope.
func (*Env) DefineType ¶
DefineType defines type in current scope.
func (*Env) Dump ¶
func (e *Env) Dump()
Dump show symbol values in the scope.
Example ¶
package main import ( "log" "github.com/mattn/anko/vm" ) func main() { env := vm.NewEnv() env.SetName("myName") err := env.Define("a", "a") if err != nil { log.Fatalf("Define error: %v\n", err) } _, err = env.Get("a") if err != nil { log.Fatalf("Get error: %v\n", err) } env.Dump() }
Output: Name: myName Has parent: false a = "a"
func (*Env) Get ¶
Get returns value which specified symbol. It goes to upper scope until found or returns error.
func (*Env) NewPackage ¶
NewPackage creates a new env with a name under the parent env
func (*Env) Set ¶
Set modifies value which specified as symbol. It goes to upper scope until found or returns error.
func (*Env) SetExternal ¶
func (e *Env) SetExternal(res EnvResolver)
SetExternal sets an external resolver