Update README.md
This commit is contained in:
parent
a562964007
commit
ddd9fa89a3
1 changed files with 1 additions and 90 deletions
91
README.md
91
README.md
|
@ -285,96 +285,7 @@ func main() {
|
|||
|
||||
In the example above, a variable `b` is defined by the user before compilation using `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()` function.
|
||||
|
||||
If you need the custom data types (outside Tengo's primitive types), you can define your own `struct` that implements `objects.Object` interface _(and optionally `objects.Callable` if you want to make function-like invokable objects)_.
|
||||
|
||||
```golang
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/d5/tengo/compiler/token"
|
||||
"github.com/d5/tengo/objects"
|
||||
"github.com/d5/tengo/script"
|
||||
)
|
||||
|
||||
type Counter struct {
|
||||
value int64
|
||||
}
|
||||
|
||||
func (o *Counter) TypeName() string {
|
||||
return "counter"
|
||||
}
|
||||
|
||||
func (o *Counter) String() string {
|
||||
return fmt.Sprintf("Counter(%d)", o.value)
|
||||
}
|
||||
|
||||
func (o *Counter) BinaryOp(op token.Token, rhs objects.Object) (objects.Object, error) {
|
||||
switch rhs := rhs.(type) {
|
||||
case *Counter:
|
||||
switch op {
|
||||
case token.Add:
|
||||
return &Counter{value: o.value + rhs.value}, nil
|
||||
case token.Sub:
|
||||
return &Counter{value: o.value - rhs.value}, nil
|
||||
}
|
||||
case *objects.Int:
|
||||
switch op {
|
||||
case token.Add:
|
||||
return &Counter{value: o.value + rhs.Value}, nil
|
||||
case token.Sub:
|
||||
return &Counter{value: o.value - rhs.Value}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New("invalid operator")
|
||||
}
|
||||
|
||||
func (o *Counter) IsFalsy() bool {
|
||||
return o.value == 0
|
||||
}
|
||||
|
||||
func (o *Counter) Equals(t objects.Object) bool {
|
||||
if tc, ok := t.(*Counter); ok {
|
||||
return o.value == tc.value
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (o *Counter) Copy() objects.Object {
|
||||
return &Counter{value: o.value}
|
||||
}
|
||||
|
||||
func (o *Counter) Call(args ...objects.Object) (objects.Object, error) {
|
||||
return &objects.Int{Value: o.value}, nil
|
||||
}
|
||||
|
||||
var code = []byte(`
|
||||
arr := [1, 2, 3, 4]
|
||||
for x in arr {
|
||||
c1 += x
|
||||
}
|
||||
out := c1()`)
|
||||
|
||||
func main() {
|
||||
s := script.New(code)
|
||||
|
||||
// define variable 'c1'
|
||||
_ = s.Add("c1", &Counter{value: 5})
|
||||
|
||||
// compile the source
|
||||
c, err := s.Run()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// retrieve value of 'out'
|
||||
out := c.Get("out")
|
||||
fmt.Println(out.Int()) // prints "15" ( = 5 + (1 + 2 + 3 + 4) )
|
||||
}
|
||||
|
||||
```
|
||||
One can easily use the custom data types by implementing `objects.Object` interface. See [Interoperability](https://github.com/d5/tengo/wiki/Interoperability) for more details.
|
||||
|
||||
As an alternative to using **Script**, you can directly create and interact with the parser, compiler, and, VMs directly. There's no good documentation yet, but, check out Script code if you are interested.
|
||||
|
||||
|
|
Loading…
Reference in a new issue