Skip to content

Commit

Permalink
Merge pull request #72 from d5/compiledset
Browse files Browse the repository at this point in the history
replacing values of the compiled script
  • Loading branch information
d5 authored Feb 1, 2019
2 parents 6420628 + 4f46460 commit 0d99cca
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 1 deletion.
13 changes: 12 additions & 1 deletion docs/interoperability.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,23 @@ func main() {

// retrieve value of 'a'
a := c.Get("a")
fmt.Println(a.Int())
fmt.Println(a.Int()) // prints "30"

// re-run after replacing value of 'b'
if err := c.Set("b", 20); err != nil {
panic(err)
}
if err := c.Run(); err != nil {
panic(err)
}
fmt.Println(c.Get("a").Int()) // prints "40"
}
```

A variable `b` is defined by the user before compilation using [Script.Add](https://godoc.org/github.com/d5/tengo/script#Script.Add) function. Then a compiled bytecode `c` is used to execute the bytecode and get the value of global variables. In this example, the value of global variable `a` is read using [Compiled.Get](https://godoc.org/github.com/d5/tengo/script#Compiled.Get) function. See [documentation](https://godoc.org/github.com/d5/tengo/script#Variable) for the full list of variable value functions.

Value of the global variables can be replaced using [Compiled.Set](https://godoc.org/github.com/d5/tengo/script#Compiled.Set) function. But it will return an error if you try to set the value of un-defined global variables _(e.g. trying to set the value of `x` in the example)_.

### Type Conversion Table

When adding a Variable _([Script.Add](https://godoc.org/github.com/d5/tengo/script#Script.Add))_, Script converts Go values into Tengo values based on the following conversion table.
Expand Down
9 changes: 9 additions & 0 deletions runtime/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ func (v *VM) Abort() {

// Run starts the execution.
func (v *VM) Run() error {
// reset VM states
v.sp = 0
v.curFrame = &(v.frames[0])
v.curInsts = v.curFrame.fn.Instructions
v.curIPLimit = len(v.curInsts) - 1
v.framesIndex = 1
v.ip = -1
atomic.StoreInt64(&v.aborting, 0)

for v.ip < v.curIPLimit && (atomic.LoadInt64(&v.aborting) == 0) {
v.ip++

Expand Down
19 changes: 19 additions & 0 deletions script/compiled.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package script

import (
"context"
"fmt"

"github.com/d5/tengo/compiler"
"github.com/d5/tengo/objects"
Expand Down Expand Up @@ -92,3 +93,21 @@ func (c *Compiled) GetAll() []*Variable {

return vars
}

// Set replaces the value of a global variable identified by the name.
// An error will be returned if the name was not defined during compilation.
func (c *Compiled) Set(name string, value interface{}) error {
obj, err := objects.FromInterface(value)
if err != nil {
return err
}

symbol, _, ok := c.symbolTable.Resolve(name)
if !ok || symbol.Scope != compiler.ScopeGlobal {
return fmt.Errorf("'%s' is not defined", name)
}

c.machine.Globals()[symbol.Index] = &obj

return nil
}
30 changes: 30 additions & 0 deletions script/compiled_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,36 @@ func TestCompiled_IsDefined(t *testing.T) {
compiledIsDefined(t, c, "b", false)
}

func TestCompiled_Set(t *testing.T) {
c := compile(t, `a := b`, M{"b": "foo"})
compiledRun(t, c)
compiledGet(t, c, "a", "foo")

// replace value of 'b'
err := c.Set("b", "bar")
assert.NoError(t, err)
compiledRun(t, c)
compiledGet(t, c, "a", "bar")

// try to replace undefined variable
err = c.Set("c", 1984)
assert.Error(t, err) // 'c' is not defined

// case #2
c = compile(t, `
a := func() {
return func() {
return b + 5
}()
}()`, M{"b": 5})
compiledRun(t, c)
compiledGet(t, c, "a", int64(10))
err = c.Set("b", 10)
assert.NoError(t, err)
compiledRun(t, c)
compiledGet(t, c, "a", int64(15))
}

func TestCompiled_RunContext(t *testing.T) {
// machine completes normally
c := compile(t, `a := 5`, nil)
Expand Down

0 comments on commit 0d99cca

Please sign in to comment.