fix markdownlint warnings (#255)
This commit is contained in:
parent
73b5e6256e
commit
a053476c0b
18 changed files with 272 additions and 273 deletions
|
@ -146,14 +146,13 @@ for more details on type conversion.
|
|||
x := string(123) // x == "123"
|
||||
```
|
||||
|
||||
|
||||
Optionally it can take the second argument, which will be returned if the first
|
||||
argument cannot be converted to string. Note that the second argument does not
|
||||
have to be string.
|
||||
|
||||
```golang
|
||||
v = string(undefined, "foo") // v == "foo"
|
||||
v = string(undefined, false) // v == false
|
||||
v = string(undefined, false) // v == false
|
||||
```
|
||||
|
||||
## int
|
||||
|
@ -172,7 +171,7 @@ to be int.
|
|||
|
||||
```golang
|
||||
v = int(undefined, 10) // v == 10
|
||||
v = int(undefined, false) // v == false
|
||||
v = int(undefined, false) // v == false
|
||||
```
|
||||
|
||||
## bool
|
||||
|
@ -201,7 +200,7 @@ have to be float.
|
|||
|
||||
```golang
|
||||
v = float(undefined, 19.84) // v == 19.84
|
||||
v = float(undefined, false) // v == false
|
||||
v = float(undefined, false) // v == false
|
||||
```
|
||||
|
||||
## char
|
||||
|
@ -220,7 +219,7 @@ have to be float.
|
|||
|
||||
```golang
|
||||
v = char(undefined, 'X') // v == 'X'
|
||||
v = char(undefined, false) // v == false
|
||||
v = char(undefined, false) // v == false
|
||||
```
|
||||
|
||||
## bytes
|
||||
|
@ -239,7 +238,7 @@ have to be float.
|
|||
|
||||
```golang
|
||||
v = bytes(undefined, bytes("foo")) // v == bytes("foo")
|
||||
v = bytes(undefined, false) // v == false
|
||||
v = bytes(undefined, false) // v == false
|
||||
```
|
||||
|
||||
If you pass an int to `bytes()` function, it will create a new byte object with
|
||||
|
@ -293,7 +292,7 @@ Returns `true` if the object's type is undefined. Or it returns `false`.
|
|||
|
||||
Returns `true` if the object's type is function or closure. Or it returns
|
||||
`false`. Note that `is_function` returns `false` for builtin functions and
|
||||
user-provided callable objects.
|
||||
user-provided callable objects.
|
||||
|
||||
## is_callable
|
||||
|
||||
|
|
|
@ -2,21 +2,24 @@
|
|||
|
||||
The format 'verbs' are derived from Go's but are simpler.
|
||||
|
||||
## The verbs:
|
||||
## The verbs
|
||||
|
||||
## General
|
||||
|
||||
## General:
|
||||
```
|
||||
%v the value in a default format
|
||||
%T a Go-syntax representation of the type of the value
|
||||
%% a literal percent sign; consumes no value
|
||||
```
|
||||
|
||||
## Boolean:
|
||||
## Boolean
|
||||
|
||||
```
|
||||
%t the word true or false
|
||||
```
|
||||
|
||||
## Integer:
|
||||
## Integer
|
||||
|
||||
```
|
||||
%b base 2
|
||||
%c the character represented by the corresponding Unicode code point
|
||||
|
@ -29,7 +32,8 @@ The format 'verbs' are derived from Go's but are simpler.
|
|||
%U Unicode format: U+1234; same as "U+%04X"
|
||||
```
|
||||
|
||||
## Float:
|
||||
## Float
|
||||
|
||||
```
|
||||
%b decimalless scientific notation with exponent a power of two,
|
||||
in the manner of Go's strconv.FormatFloat with the 'b' format,
|
||||
|
@ -44,7 +48,8 @@ e.g. -123456p-78
|
|||
%X upper-case hexadecimal notation, e.g. -0X1.23ABCP+20
|
||||
```
|
||||
|
||||
## String and Bytes:
|
||||
## String and Bytes
|
||||
|
||||
```
|
||||
%s the uninterpreted bytes of the string or slice
|
||||
%q a double-quoted string safely escaped with Go syntax
|
||||
|
@ -52,7 +57,8 @@ e.g. -123456p-78
|
|||
%X base 16, upper-case, two characters per byte
|
||||
```
|
||||
|
||||
## Default format for %v:
|
||||
## Default format for %v
|
||||
|
||||
```
|
||||
Bool: %t
|
||||
Int: %d
|
||||
|
@ -60,14 +66,14 @@ Float: %g
|
|||
String: %s
|
||||
```
|
||||
|
||||
## Compound Objects:
|
||||
## Compound Objects
|
||||
|
||||
```
|
||||
Array: [elem0 elem1 ...]
|
||||
Maps: {key1:value1 key2:value2 ...}
|
||||
```
|
||||
|
||||
|
||||
## Width and Precision:
|
||||
## Width and Precision
|
||||
|
||||
Width is specified by an optional decimal number immediately preceding the verb.
|
||||
If absent, the width is whatever is necessary to represent the value.
|
||||
|
@ -111,7 +117,8 @@ For complex numbers, the width and precision apply to the two components
|
|||
independently and the result is parenthesized, so %f applied to 1.2+3.4i
|
||||
produces (1.200000+3.400000i).
|
||||
|
||||
## Other flags:
|
||||
## Other flags
|
||||
|
||||
```
|
||||
+ always print a sign for numeric values;
|
||||
guarantee ASCII-only output for %q (%+q)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Interoperability
|
||||
|
||||
## Table of Contents
|
||||
## Table of Contents
|
||||
|
||||
- [Using Scripts](#using-scripts)
|
||||
- [Type Conversion Table](#type-conversion-table)
|
||||
|
@ -52,41 +52,41 @@ output variable is accessed through
|
|||
|
||||
```golang
|
||||
import (
|
||||
"fmt"
|
||||
"fmt"
|
||||
|
||||
"github.com/d5/tengo/v2"
|
||||
"github.com/d5/tengo/v2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := tengo.NewScript([]byte(`a := b + 20`))
|
||||
s := tengo.NewScript([]byte(`a := b + 20`))
|
||||
|
||||
// define variable 'b'
|
||||
_ = s.Add("b", 10)
|
||||
// define variable 'b'
|
||||
_ = s.Add("b", 10)
|
||||
|
||||
// compile the source
|
||||
c, err := s.Compile()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// compile the source
|
||||
c, err := s.Compile()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// run the compiled bytecode
|
||||
// a compiled bytecode 'c' can be executed multiple times without re-compiling it
|
||||
if err := c.Run(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// run the compiled bytecode
|
||||
// a compiled bytecode 'c' can be executed multiple times without re-compiling it
|
||||
if err := c.Run(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// retrieve value of 'a'
|
||||
a := c.Get("a")
|
||||
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"
|
||||
// retrieve value of 'a'
|
||||
a := c.Get("a")
|
||||
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"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -129,7 +129,6 @@ converts Go values into Tengo values based on the following conversion table.
|
|||
|`[]interface{}`|`Array`|individual elements converted to Tengo objects|
|
||||
|`Object`|`Object`|_(no type conversion performed)_|
|
||||
|
||||
|
||||
### User Types
|
||||
|
||||
Users can add and use a custom user type in Tengo code by implementing
|
||||
|
@ -144,7 +143,7 @@ more details.
|
|||
To securely compile and execute _potentially_ unsafe script code, you can use
|
||||
the following Script functions.
|
||||
|
||||
#### Script.SetImports(modules *objects.ModuleMap)
|
||||
### Script.SetImports(modules *objects.ModuleMap)
|
||||
|
||||
SetImports sets the import modules with corresponding names. Script **does not**
|
||||
include any modules by default. You can use this function to include the
|
||||
|
@ -169,25 +168,24 @@ mods.AddSourceModule("double", []byte(`export func(x) { return x * 2 }`))
|
|||
s.SetImports(mods)
|
||||
```
|
||||
|
||||
|
||||
#### Script.SetMaxAllocs(n int64)
|
||||
### Script.SetMaxAllocs(n int64)
|
||||
|
||||
SetMaxAllocs sets the maximum number of object allocations. Note this is a
|
||||
cumulative metric that tracks only the object creations. Set this to a negative
|
||||
number (e.g. `-1`) if you don't need to limit the number of allocations.
|
||||
|
||||
#### Script.EnableFileImport(enable bool)
|
||||
|
||||
### Script.EnableFileImport(enable bool)
|
||||
|
||||
EnableFileImport enables or disables module loading from the local files. It's
|
||||
disabled by default.
|
||||
disabled by default.
|
||||
|
||||
#### tengo.MaxStringLen
|
||||
### tengo.MaxStringLen
|
||||
|
||||
Sets the maximum byte-length of string values. This limit applies to all
|
||||
running VM instances in the process. Also it's not recommended to set or update
|
||||
this value while any VM is executing.
|
||||
this value while any VM is executing.
|
||||
|
||||
#### tengo.MaxBytesLen
|
||||
### tengo.MaxBytesLen
|
||||
|
||||
Sets the maximum length of bytes values. This limit applies to all running VM
|
||||
instances in the process. Also it's not recommended to set or update this value
|
||||
|
@ -200,7 +198,7 @@ times by a goroutine. If you want to run the compiled script by multiple
|
|||
goroutine, you should use `Compiled.Clone` function to make a copy of Compiled
|
||||
instances.
|
||||
|
||||
#### Compiled.Clone()
|
||||
### Compiled.Clone()
|
||||
|
||||
Clone creates a new copy of Compiled instance. Cloned copies are safe for
|
||||
concurrent use by multiple goroutines.
|
||||
|
@ -212,17 +210,17 @@ for i := 0; i < concurrency; i++ {
|
|||
_ = compiled.Set("a", rand.Intn(10))
|
||||
_ = compiled.Set("b", rand.Intn(10))
|
||||
_ = compiled.Set("c", rand.Intn(10))
|
||||
|
||||
|
||||
if err := compiled.Run(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
|
||||
// outputs
|
||||
d = compiled.Get("d").Int()
|
||||
e = compiled.Get("e").Int()
|
||||
}(compiled.Clone()) // Pass the cloned copy of Compiled
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
## Compiler and VM
|
||||
|
||||
|
|
192
docs/objects.md
192
docs/objects.md
|
@ -25,6 +25,7 @@ generally a good idea to keep it short but distinguishable from other types.
|
|||
```golang
|
||||
String() string
|
||||
```
|
||||
|
||||
String method should return a string representation of the underlying value.
|
||||
The value returned by String method will be used whenever string formatting for
|
||||
the value is required, most commonly when being converted into String value.
|
||||
|
@ -46,13 +47,13 @@ If BinaryOp method returns an error `err` (the second return value), it will be
|
|||
treated as a run-time error, which will halt the execution (`VM.Run() error`)
|
||||
and will return the error to the user. All runtime type implementations, for
|
||||
example, will return an `ErrInvalidOperator` error when the given operator is
|
||||
not supported by the type.
|
||||
not supported by the type.
|
||||
|
||||
Alternatively the method can return an `Error` value as its result `res`
|
||||
(the first return value), which will not halt the runtime and will be treated
|
||||
like any other values. As a dynamically typed language, the receiver (another
|
||||
expression or statement) can determine how to translate `Error` value returned
|
||||
from binary operator expression.
|
||||
from binary operator expression.
|
||||
|
||||
```golang
|
||||
IsFalsy() bool
|
||||
|
@ -222,7 +223,6 @@ See
|
|||
[Runtime Types](https://github.com/d5/tengo/blob/master/docs/runtime-types.md)
|
||||
for more details on these runtime types.
|
||||
|
||||
|
||||
## User Object Types
|
||||
|
||||
Users can easily extend and add their own types by implementing the same
|
||||
|
@ -234,58 +234,58 @@ Here's an example user type implementation, `StringArray`:
|
|||
|
||||
```golang
|
||||
type StringArray struct {
|
||||
tengo.ObjectImpl
|
||||
Value []string
|
||||
tengo.ObjectImpl
|
||||
Value []string
|
||||
}
|
||||
|
||||
func (o *StringArray) String() string {
|
||||
return strings.Join(o.Value, ", ")
|
||||
return strings.Join(o.Value, ", ")
|
||||
}
|
||||
|
||||
func (o *StringArray) BinaryOp(op token.Token, rhs tengo.Object) (tengo.Object, error) {
|
||||
if rhs, ok := rhs.(*StringArray); ok {
|
||||
switch op {
|
||||
case token.Add:
|
||||
if len(rhs.Value) == 0 {
|
||||
return o, nil
|
||||
}
|
||||
return &StringArray{Value: append(o.Value, rhs.Value...)}, nil
|
||||
}
|
||||
}
|
||||
if rhs, ok := rhs.(*StringArray); ok {
|
||||
switch op {
|
||||
case token.Add:
|
||||
if len(rhs.Value) == 0 {
|
||||
return o, nil
|
||||
}
|
||||
return &StringArray{Value: append(o.Value, rhs.Value...)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, tengo.ErrInvalidOperator
|
||||
return nil, tengo.ErrInvalidOperator
|
||||
}
|
||||
|
||||
func (o *StringArray) IsFalsy() bool {
|
||||
return len(o.Value) == 0
|
||||
return len(o.Value) == 0
|
||||
}
|
||||
|
||||
func (o *StringArray) Equals(x tengo.Object) bool {
|
||||
if x, ok := x.(*StringArray); ok {
|
||||
if len(o.Value) != len(x.Value) {
|
||||
return false
|
||||
}
|
||||
if x, ok := x.(*StringArray); ok {
|
||||
if len(o.Value) != len(x.Value) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i, v := range o.Value {
|
||||
if v != x.Value[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
for i, v := range o.Value {
|
||||
if v != x.Value[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
return false
|
||||
}
|
||||
|
||||
func (o *StringArray) Copy() tengo.Object {
|
||||
return &StringArray{
|
||||
Value: append([]string{}, o.Value...),
|
||||
}
|
||||
return &StringArray{
|
||||
Value: append([]string{}, o.Value...),
|
||||
}
|
||||
}
|
||||
|
||||
func (o *StringArray) TypeName() string {
|
||||
return "string-array"
|
||||
return "string-array"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -297,7 +297,7 @@ to add `StringArray` to the script:
|
|||
```golang
|
||||
// script that uses 'my_list'
|
||||
s := tengo.NewScript([]byte(`
|
||||
print(my_list + "three")
|
||||
print(my_list + "three")
|
||||
`))
|
||||
|
||||
myList := &StringArray{Value: []string{"one", "two"}}
|
||||
|
@ -309,46 +309,46 @@ It can also implement `IndexGet` and `IndexSet`:
|
|||
|
||||
```golang
|
||||
func (o *StringArray) IndexGet(index tengo.Object) (tengo.Object, error) {
|
||||
intIdx, ok := index.(*tengo.Int)
|
||||
if ok {
|
||||
if intIdx.Value >= 0 && intIdx.Value < int64(len(o.Value)) {
|
||||
return &tengo.String{Value: o.Value[intIdx.Value]}, nil
|
||||
}
|
||||
intIdx, ok := index.(*tengo.Int)
|
||||
if ok {
|
||||
if intIdx.Value >= 0 && intIdx.Value < int64(len(o.Value)) {
|
||||
return &tengo.String{Value: o.Value[intIdx.Value]}, nil
|
||||
}
|
||||
|
||||
return nil, tengo.ErrIndexOutOfBounds
|
||||
}
|
||||
return nil, tengo.ErrIndexOutOfBounds
|
||||
}
|
||||
|
||||
strIdx, ok := index.(*tengo.String)
|
||||
if ok {
|
||||
for vidx, str := range o.Value {
|
||||
if strIdx.Value == str {
|
||||
return &tengo.Int{Value: int64(vidx)}, nil
|
||||
}
|
||||
}
|
||||
strIdx, ok := index.(*tengo.String)
|
||||
if ok {
|
||||
for vidx, str := range o.Value {
|
||||
if strIdx.Value == str {
|
||||
return &tengo.Int{Value: int64(vidx)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return tengo.UndefinedValue, nil
|
||||
}
|
||||
return tengo.UndefinedValue, nil
|
||||
}
|
||||
|
||||
return nil, tengo.ErrInvalidIndexType
|
||||
return nil, tengo.ErrInvalidIndexType
|
||||
}
|
||||
|
||||
func (o *StringArray) IndexSet(index, value tengo.Object) error {
|
||||
strVal, ok := tengo.ToString(value)
|
||||
if !ok {
|
||||
return tengo.ErrInvalidIndexValueType
|
||||
}
|
||||
strVal, ok := tengo.ToString(value)
|
||||
if !ok {
|
||||
return tengo.ErrInvalidIndexValueType
|
||||
}
|
||||
|
||||
intIdx, ok := index.(*tengo.Int)
|
||||
if ok {
|
||||
if intIdx.Value >= 0 && intIdx.Value < int64(len(o.Value)) {
|
||||
o.Value[intIdx.Value] = strVal
|
||||
return nil
|
||||
}
|
||||
intIdx, ok := index.(*tengo.Int)
|
||||
if ok {
|
||||
if intIdx.Value >= 0 && intIdx.Value < int64(len(o.Value)) {
|
||||
o.Value[intIdx.Value] = strVal
|
||||
return nil
|
||||
}
|
||||
|
||||
return tengo.ErrIndexOutOfBounds
|
||||
}
|
||||
return tengo.ErrIndexOutOfBounds
|
||||
}
|
||||
|
||||
return tengo.ErrInvalidIndexType
|
||||
return tengo.ErrInvalidIndexType
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -356,30 +356,30 @@ If we implement `CamCall` and `Call`:
|
|||
|
||||
```golang
|
||||
func (o *StringArray) CanCall() bool {
|
||||
return true
|
||||
return true
|
||||
}
|
||||
|
||||
func (o *StringArray) Call(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
if len(args) != 1 {
|
||||
return nil, tengo.ErrWrongNumArguments
|
||||
}
|
||||
|
||||
s1, ok := tengo.ToString(args[0])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "string",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
s1, ok := tengo.ToString(args[0])
|
||||
if !ok {
|
||||
return nil, tengo.ErrInvalidArgumentType{
|
||||
Name: "first",
|
||||
Expected: "string",
|
||||
Found: args[0].TypeName(),
|
||||
}
|
||||
}
|
||||
|
||||
for i, v := range o.Value {
|
||||
if v == s1 {
|
||||
return &tengo.Int{Value: int64(i)}, nil
|
||||
}
|
||||
}
|
||||
for i, v := range o.Value {
|
||||
if v == s1 {
|
||||
return &tengo.Int{Value: int64(i)}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return tengo.UndefinedValue, nil
|
||||
return tengo.UndefinedValue, nil
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -387,7 +387,7 @@ Then it can be "invoked":
|
|||
|
||||
```golang
|
||||
s := tengo.NewScript([]byte(`
|
||||
print(my_list("two"))
|
||||
print(my_list("two"))
|
||||
`))
|
||||
|
||||
myList := &StringArray{Value: []string{"one", "two", "three"}}
|
||||
|
@ -399,36 +399,36 @@ We can also make `StringArray` iterable:
|
|||
|
||||
```golang
|
||||
func (o *StringArray) CanIterate() bool {
|
||||
return true
|
||||
return true
|
||||
}
|
||||
|
||||
func (o *StringArray) Iterate() tengo.Iterator {
|
||||
return &StringArrayIterator{
|
||||
strArr: o,
|
||||
}
|
||||
return &StringArrayIterator{
|
||||
strArr: o,
|
||||
}
|
||||
}
|
||||
|
||||
type StringArrayIterator struct {
|
||||
tengo.ObjectImpl
|
||||
strArr *StringArray
|
||||
idx int
|
||||
tengo.ObjectImpl
|
||||
strArr *StringArray
|
||||
idx int
|
||||
}
|
||||
|
||||
func (i *StringArrayIterator) TypeName() string {
|
||||
return "string-array-iterator"
|
||||
return "string-array-iterator"
|
||||
}
|
||||
|
||||
func (i *StringArrayIterator) Next() bool {
|
||||
i.idx++
|
||||
return i.idx <= len(i.strArr.Value)
|
||||
i.idx++
|
||||
return i.idx <= len(i.strArr.Value)
|
||||
}
|
||||
|
||||
func (i *StringArrayIterator) Key() tengo.Object {
|
||||
return &tengo.Int{Value: int64(i.idx - 1)}
|
||||
return &tengo.Int{Value: int64(i.idx - 1)}
|
||||
}
|
||||
|
||||
func (i *StringArrayIterator) Value() tengo.Object {
|
||||
return &tengo.String{Value: i.strArr.Value[i.idx-1]}
|
||||
return &tengo.String{Value: i.strArr.Value[i.idx-1]}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -438,5 +438,3 @@ ObjectImpl represents a default Object Implementation. To defined a new value
|
|||
type, one can embed ObjectImpl in their type declarations to avoid implementing
|
||||
all non-significant methods. TypeName() and String() methods still need to be
|
||||
implemented.
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
- `(int) == (int) = (bool)`: equality
|
||||
- `(int) != (int) = (bool)`: inequality
|
||||
|
||||
### Arithmetic Operators
|
||||
### Arithmetic Operators
|
||||
|
||||
- `(int) + (int) = (int)`: sum
|
||||
- `(int) - (int) = (int)`: difference
|
||||
|
@ -52,8 +52,8 @@
|
|||
- `(float) == (float) = (bool)`: equality
|
||||
- `(float) != (float) = (bool)`: inequality
|
||||
|
||||
### Arithmetic Operators
|
||||
|
||||
### Arithmetic Operators
|
||||
|
||||
- `(float) + (float) = (float)`: sum
|
||||
- `(float) - (float) = (float)`: difference
|
||||
- `(float) * (float) = (float)`: product
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
- **Undefined**: undefined
|
||||
|
||||
## Type Conversion/Coercion Table
|
||||
|
||||
|src\dst |Int |String |Float |Bool |Char |Bytes |Array |Map |Time |Error |Undefined|
|
||||
| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
|
||||
|Int | - |_strconv_ |float64(v)|!IsFalsy()| rune(v)|**X**|**X**|**X**|_time.Unix()_|**X**|**X**|
|
||||
|
@ -34,7 +35,7 @@ _* **X**: No conversion; Typed value functions for `Variable` will
|
|||
return zero values._
|
||||
_* strconv: converted using Go's conversion functions from `strconv` package._
|
||||
_* IsFalsy(): use [Object.IsFalsy()](#objectisfalsy) function_
|
||||
_* String(): use `Object.String()` function_
|
||||
_* String(): use `Object.String()` function_
|
||||
_* time.Unix(): use `time.Unix(v, 0)` to convert to Time_
|
||||
|
||||
## Object.IsFalsy()
|
||||
|
@ -86,4 +87,4 @@ the full list of builtin functions.
|
|||
- `is_error(x)`: returns `true` if `x` is error; `false` otherwise
|
||||
- `is_undefined(x)`: returns `true` if `x` is undefined; `false` otherwise
|
||||
- See [Builtins](https://github.com/d5/tengo/blob/master/docs/builtins.md) for
|
||||
the full list of builtin functions.
|
||||
the full list of builtin functions.
|
||||
|
|
|
@ -16,4 +16,4 @@ fmt := import("base64")
|
|||
- `raw_url_encode(src)`: returns the url-base64 encoding of src but omits the
|
||||
padding.
|
||||
- `raw_url_decode(s)`: returns the bytes represented by the url-base64 string
|
||||
s which omits the padding.
|
||||
s which omits the padding.
|
||||
|
|
|
@ -39,4 +39,4 @@ enum := import("enum")
|
|||
`key` is an int index if `x` is array. `key` is a string key if `x` is map.
|
||||
It returns undefined if `x` is not enumerable.
|
||||
- `key(k, _) => object`: returns the first argument.
|
||||
- `value(_, v) => object`: returns the second argument.
|
||||
- `value(_, v) => object`: returns the second argument.
|
||||
|
|
|
@ -7,4 +7,4 @@ fmt := import("hex")
|
|||
## Functions
|
||||
|
||||
- `encode(src)`: returns the hexadecimal encoding of src.
|
||||
- `decode(s)`: returns the bytes represented by the hexadecimal string s.
|
||||
- `decode(s)`: returns the bytes represented by the hexadecimal string s.
|
||||
|
|
|
@ -16,7 +16,6 @@ json := import("json")
|
|||
- `html_escape(b string/bytes) => bytes`: Return an HTML-safe form of input
|
||||
JSON bytes string.
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
```golang
|
||||
|
@ -26,5 +25,5 @@ encoded := json.encode({a: 1, b: [2, 3, 4]}) // JSON-encoded bytes string
|
|||
indentded := json.indent(encoded) // indented form
|
||||
html_safe := json.html_escape(encoded) // HTML escaped form
|
||||
|
||||
decoded := json.decode(encoded) // {a: 1, b: [2, 3, 4]}
|
||||
```
|
||||
decoded := json.decode(encoded) // {a: 1, b: [2, 3, 4]}
|
||||
```
|
||||
|
|
|
@ -33,8 +33,8 @@ math := import("math")
|
|||
- `ceil(x float) => float`: returns the least integer value greater than or
|
||||
equal to x.
|
||||
- `copysign(x float, y float) => float`: returns a value with the magnitude of
|
||||
x and the sign of y.
|
||||
- `cos(x float) => float`: returns the cosine of the radian argument x.
|
||||
x and the sign of y.
|
||||
- `cos(x float) => float`: returns the cosine of the radian argument x.
|
||||
- `cosh(x float) => float`: returns the hyperbolic cosine of x.
|
||||
- `dim(x float, y float) => float`: returns the maximum of x-y or 0.
|
||||
- `erf(x float) => float`: returns the error function of x.
|
||||
|
@ -42,11 +42,11 @@ math := import("math")
|
|||
- `exp(x float) => float`: returns e**x, the base-e exponential of x.
|
||||
- `exp2(x float) => float`: returns 2**x, the base-2 exponential of x.
|
||||
- `expm1(x float) => float`: returns e**x - 1, the base-e exponential of x
|
||||
minus 1. It is more accurate than Exp(x) - 1 when x is near zero.
|
||||
minus 1. It is more accurate than Exp(x) - 1 when x is near zero.
|
||||
- `floor(x float) => float`: returns the greatest integer value less than or
|
||||
equal to x.
|
||||
- `gamma(x float) => float`: returns the Gamma function of x.
|
||||
- `hypot(p float, q float) => float`: returns Sqrt(p * p + q * q), taking care
|
||||
- `hypot(p float, q float) => float`: returns `Sqrt(p * p + q * q)`, taking care
|
||||
to avoid unnecessary overflow and underflow.
|
||||
- `ilogb(x float) => float`: returns the binary exponent of x as an integer.
|
||||
- `inf(sign int) => float`: returns positive infinity if sign >= 0, negative
|
||||
|
@ -93,4 +93,4 @@ math := import("math")
|
|||
- `y1(x float) => float`: returns the order-one Bessel function of the second
|
||||
kind.
|
||||
- `yn(n int, x float) => float`: returns the order-n Bessel function of the
|
||||
second kind.
|
||||
second kind.
|
||||
|
|
|
@ -36,70 +36,69 @@ os := import("os")
|
|||
- `path_list_separator`
|
||||
- `dev_null`
|
||||
|
||||
|
||||
## Functions
|
||||
|
||||
- `args() => [string]`: returns command-line arguments, starting with the
|
||||
program name.
|
||||
- `chdir(dir string) => error`: changes the current working directory to the
|
||||
named directory.
|
||||
- `chmod(name string, mode int) => error `: changes the mode of the named file
|
||||
- `chmod(name string, mode int) => error`: changes the mode of the named file
|
||||
to mode.
|
||||
- `chown(name string, uid int, gid int) => error `: changes the numeric uid and
|
||||
- `chown(name string, uid int, gid int) => error`: changes the numeric uid and
|
||||
gid of the named file.
|
||||
- `clearenv()`: deletes all environment variables.
|
||||
- `environ() => [string] `: returns a copy of strings representing the
|
||||
- `environ() => [string]`: returns a copy of strings representing the
|
||||
environment.
|
||||
- `exit(code int) `: causes the current program to exit with the given status
|
||||
- `exit(code int)`: causes the current program to exit with the given status
|
||||
code.
|
||||
- `expand_env(s string) => string `: replaces ${var} or $var in the string
|
||||
- `expand_env(s string) => string`: replaces ${var} or $var in the string
|
||||
according to the values of the current environment variables.
|
||||
- `getegid() => int `: returns the numeric effective group id of the caller.
|
||||
- `getenv(key string) => string `: retrieves the value of the environment
|
||||
- `getegid() => int`: returns the numeric effective group id of the caller.
|
||||
- `getenv(key string) => string`: retrieves the value of the environment
|
||||
variable named by the key.
|
||||
- `geteuid() => int `: returns the numeric effective user id of the caller.
|
||||
- `getgid() => int `: returns the numeric group id of the caller.
|
||||
- `getgroups() => [int]/error `: returns a list of the numeric ids of groups
|
||||
- `geteuid() => int`: returns the numeric effective user id of the caller.
|
||||
- `getgid() => int`: returns the numeric group id of the caller.
|
||||
- `getgroups() => [int]/error`: returns a list of the numeric ids of groups
|
||||
that the caller belongs to.
|
||||
- `getpagesize() => int `: returns the underlying system's memory page size.
|
||||
- `getpid() => int `: returns the process id of the caller.
|
||||
- `getppid() => int `: returns the process id of the caller's parent.
|
||||
- `getuid() => int `: returns the numeric user id of the caller.
|
||||
- `getwd() => string/error `: returns a rooted path name corresponding to the
|
||||
- `getpagesize() => int`: returns the underlying system's memory page size.
|
||||
- `getpid() => int`: returns the process id of the caller.
|
||||
- `getppid() => int`: returns the process id of the caller's parent.
|
||||
- `getuid() => int`: returns the numeric user id of the caller.
|
||||
- `getwd() => string/error`: returns a rooted path name corresponding to the
|
||||
current directory.
|
||||
- `hostname() => string/error `: returns the host name reported by the kernel.
|
||||
- `lchown(name string, uid int, gid int) => error `: changes the numeric uid
|
||||
- `hostname() => string/error`: returns the host name reported by the kernel.
|
||||
- `lchown(name string, uid int, gid int) => error`: changes the numeric uid
|
||||
and gid of the named file.
|
||||
- `link(oldname string, newname string) => error `: creates newname as a hard
|
||||
- `link(oldname string, newname string) => error`: creates newname as a hard
|
||||
link to the oldname file.
|
||||
- `lookup_env(key string) => string/false`: retrieves the value of the
|
||||
environment variable named by the key.
|
||||
- `mkdir(name string, perm int) => error `: creates a new directory with the
|
||||
- `mkdir(name string, perm int) => error`: creates a new directory with the
|
||||
specified name and permission bits (before umask).
|
||||
- `mkdir_all(name string, perm int) => error `: creates a directory named path,
|
||||
- `mkdir_all(name string, perm int) => error`: creates a directory named path,
|
||||
along with any necessary parents, and returns nil, or else returns an error.
|
||||
- `read_file(name string) => bytes/error `: reads the contents of a file into
|
||||
- `read_file(name string) => bytes/error`: reads the contents of a file into
|
||||
a byte array
|
||||
- `readlink(name string) => string/error `: returns the destination of the
|
||||
- `readlink(name string) => string/error`: returns the destination of the
|
||||
named symbolic link.
|
||||
- `remove(name string) => error `: removes the named file or (empty) directory.
|
||||
- `remove_all(name string) => error `: removes path and any children it
|
||||
- `remove(name string) => error`: removes the named file or (empty) directory.
|
||||
- `remove_all(name string) => error`: removes path and any children it
|
||||
contains.
|
||||
- `rename(oldpath string, newpath string) => error `: renames (moves) oldpath
|
||||
- `rename(oldpath string, newpath string) => error`: renames (moves) oldpath
|
||||
to newpath.
|
||||
- `setenv(key string, value string) => error `: sets the value of the
|
||||
- `setenv(key string, value string) => error`: sets the value of the
|
||||
environment variable named by the key.
|
||||
- `stat(filename string) => FileInfo/error`: returns a file info structure
|
||||
describing the file
|
||||
- `symlink(oldname string newname string) => error `: creates newname as a
|
||||
- `symlink(oldname string newname string) => error`: creates newname as a
|
||||
symbolic link to oldname.
|
||||
- `temp_dir() => string `: returns the default directory to use for temporary
|
||||
- `temp_dir() => string`: returns the default directory to use for temporary
|
||||
files.
|
||||
- `truncate(name string, size int) => error `: changes the size of the named
|
||||
- `truncate(name string, size int) => error`: changes the size of the named
|
||||
file.
|
||||
- `unsetenv(key string) => error `: unsets a single environment variable.
|
||||
- `unsetenv(key string) => error`: unsets a single environment variable.
|
||||
- `create(name string) => File/error`: creates the named file with mode 0666
|
||||
(before umask), truncating it if it already exists.
|
||||
(before umask), truncating it if it already exists.
|
||||
- `open(name string) => File/error`: opens the named file for reading. If
|
||||
successful, methods on the returned file can be used for reading; the
|
||||
associated file descriptor has mode O_RDONLY.
|
||||
|
@ -118,7 +117,6 @@ os := import("os")
|
|||
- `exec(name string, args...) => Command/error`: returns the Command to execute
|
||||
the named program with the given arguments.
|
||||
|
||||
|
||||
## File
|
||||
|
||||
```golang
|
||||
|
@ -153,7 +151,7 @@ proc := start_process("app", ["arg1", "arg2"], "dir", [])
|
|||
proc.wait()
|
||||
```
|
||||
|
||||
- `kill() => error`: causes the Process to exit immediately.
|
||||
- `kill() => error`: causes the Process to exit immediately.
|
||||
- `release() => error`: releases any resources associated with the process,
|
||||
rendering it unusable in the future.
|
||||
- `signal(signal int) => error`: sends a signal to the Process.
|
||||
|
@ -200,4 +198,4 @@ output := cmd.output()
|
|||
- `set_path(path string)`: sets the path of the command to run.
|
||||
- `set_dir(dir string)`: sets the working directory of the process.
|
||||
- `set_env(env [string])`: sets the environment of the process.
|
||||
- `process() => Process`: returns the underlying process, once started.
|
||||
- `process() => Process`: returns the underlying process, once started.
|
||||
|
|
|
@ -47,4 +47,4 @@ rand := import("rand")
|
|||
- `perm(n int) => [int]`: returns, as a slice of n ints, a pseudo-random
|
||||
permutation of the integers [0,n) from the default Source.
|
||||
- `read(p bytes) => int/error`: generates len(p) random bytes from the default
|
||||
Source and writes them into p. It always returns len(p) and a nil error.
|
||||
Source and writes them into p. It always returns len(p) and a nil error.
|
||||
|
|
|
@ -13,7 +13,7 @@ text := import("text")
|
|||
that contains matching text, begin and end (exclusive) index.
|
||||
- `re_replace(pattern string, text string, repl string) => string/error`:
|
||||
returns a copy of src, replacing matches of the pattern with the replacement
|
||||
string repl.
|
||||
string repl.
|
||||
- `re_split(pattern string, text string, count int) => [string]/error`: slices
|
||||
s into substrings separated by the expression and returns a slice of the
|
||||
substrings between those expression matches.
|
||||
|
@ -103,7 +103,7 @@ text := import("text")
|
|||
value of b.
|
||||
- `format_float(f float, fmt string, prec int, bits int) => string`: converts
|
||||
the floating-point number f to a string, according to the format fmt and
|
||||
precision prec.
|
||||
precision prec.
|
||||
- `format_int(i int, base int) => string`: returns the string representation of
|
||||
i in the given base, for 2 <= base <= 36. The result uses the lower-case
|
||||
letters 'a' to 'z' for digit values >= 10.
|
||||
|
|
|
@ -22,28 +22,28 @@ times := import("times")
|
|||
- `format_stamp_micro`: time format "Jan _2 15:04:05.000000"
|
||||
- `format_stamp_nano`: time format "Jan _2 15:04:05.000000000"
|
||||
- `nanosecond`
|
||||
- `microsecond`
|
||||
- `millisecond`
|
||||
- `microsecond`
|
||||
- `millisecond`
|
||||
- `second`
|
||||
- `minute`
|
||||
- `minute`
|
||||
- `hour`
|
||||
- `january`
|
||||
- `february`
|
||||
- `january`
|
||||
- `february`
|
||||
- `march`
|
||||
- `april`
|
||||
- `april`
|
||||
- `may`
|
||||
- `june`
|
||||
- `july`
|
||||
- `august`
|
||||
- `september`
|
||||
- `june`
|
||||
- `july`
|
||||
- `august`
|
||||
- `september`
|
||||
- `october`
|
||||
- `november`
|
||||
- `december`
|
||||
- `november`
|
||||
- `december`
|
||||
|
||||
## Functions
|
||||
|
||||
- `sleep(duration int)`: pauses the current goroutine for at least the duration
|
||||
d. A negative or zero duration causes Sleep to return immediately.
|
||||
d. A negative or zero duration causes Sleep to return immediately.
|
||||
- `parse_duration(s string) => int`: parses a duration string. A duration
|
||||
string is a possibly signed sequence of decimal numbers, each with optional
|
||||
fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time
|
||||
|
@ -51,7 +51,7 @@ times := import("times")
|
|||
- `since(t time) => int`: returns the time elapsed since t.
|
||||
- `until(t time) => int`: returns the duration until t.
|
||||
- `duration_hours(duration int) => float`: returns the duration as a floating
|
||||
point number of hours.
|
||||
point number of hours.
|
||||
- `duration_minutes(duration int) => float`: returns the duration as a floating
|
||||
point number of minutes.
|
||||
- `duration_nanoseconds(duration int) => int`: returns the duration as an
|
||||
|
@ -64,7 +64,7 @@ times := import("times")
|
|||
("January", "February", ...).
|
||||
- `date(year int, month int, day int, hour int, min int, sec int, nsec int) => time`:
|
||||
returns the Time corresponding to "yyyy-mm-dd hh:mm:ss + nsec nanoseconds".
|
||||
Current location is used.
|
||||
Current location is used.
|
||||
- `now() => time`: returns the current local time.
|
||||
- `parse(format string, s string) => time`: parses a formatted string and
|
||||
returns the time value it represents. The layout defines the format by
|
||||
|
@ -79,7 +79,7 @@ times := import("times")
|
|||
- `add_date(t time, years int, months int, days int) => time`: returns the time
|
||||
corresponding to adding the given number of years, months, and days to t. For
|
||||
example, AddDate(-1, 2, 3) applied to January 1, 2011 returns March 4, 2010.
|
||||
- `sub(t time, u time) => int`: returns the duration t-u.
|
||||
- `sub(t time, u time) => int`: returns the duration t-u.
|
||||
- `after(t time, u time) => bool`: reports whether the time instant t is after
|
||||
u.
|
||||
- `before(t time, u time) => bool`: reports whether the time instant t is
|
||||
|
@ -117,4 +117,4 @@ times := import("times")
|
|||
- `is_zero(t time) => bool`: reports whether t represents the zero time
|
||||
instant, January 1, year 1, 00:00:00 UTC.
|
||||
- `to_local(t time) => time`: returns t with the location set to local time.
|
||||
- `to_utc(t time) => time`: returns t with the location set to UTC.
|
||||
- `to_utc(t time) => time`: returns t with the location set to UTC.
|
||||
|
|
|
@ -19,4 +19,4 @@
|
|||
- [hex](https://github.com/d5/tengo/blob/master/docs/stdlib-hex.md): hex
|
||||
encoding and decoding functions
|
||||
- [base64](https://github.com/d5/tengo/blob/master/docs/stdlib-base64.md):
|
||||
base64 encoding and decoding functions
|
||||
base64 encoding and decoding functions
|
||||
|
|
|
@ -12,7 +12,7 @@ go get github.com/d5/tengo/cmd/tengo
|
|||
```
|
||||
|
||||
Or, you can download the precompiled binaries from
|
||||
[here](https://github.com/d5/tengo/releases/latest).
|
||||
[here](https://github.com/d5/tengo/releases/latest).
|
||||
|
||||
## Compiling and Executing Tengo Code
|
||||
|
||||
|
@ -27,7 +27,7 @@ Or, you can compile the code into a binary file and execute it later.
|
|||
|
||||
```bash
|
||||
tengo -o myapp myapp.tengo # compile 'myapp.tengo' into binary file 'myapp'
|
||||
tengo myapp # execute the compiled binary `myapp`
|
||||
tengo myapp # execute the compiled binary `myapp`
|
||||
```
|
||||
|
||||
## Tengo REPL
|
||||
|
@ -37,4 +37,4 @@ if you run `tengo` with no arguments.
|
|||
|
||||
```bash
|
||||
tengo
|
||||
```
|
||||
```
|
||||
|
|
|
@ -28,7 +28,7 @@ Here's a list of all available value types in Tengo.
|
|||
| float | 64-bit floating point value | `float64` |
|
||||
| bool | boolean value | `bool` |
|
||||
| char | unicode character | `rune` |
|
||||
| string | unicode string | `string` |
|
||||
| string | unicode string | `string` |
|
||||
| bytes | byte array | `[]byte` |
|
||||
| error | [error](#error-values) value | - |
|
||||
| time | time value | `time.Time` |
|
||||
|
@ -40,39 +40,39 @@ Here's a list of all available value types in Tengo.
|
|||
| function | [function](#function-values) value | - |
|
||||
| _user-defined_ | value of [user-defined types](https://github.com/d5/tengo/blob/master/docs/objects.md) | - |
|
||||
|
||||
#### Error Values
|
||||
### Error Values
|
||||
|
||||
In Tengo, an error can be represented using "error" typed values. An error
|
||||
value is created using `error` expression, and, it must have an underlying
|
||||
value. The underlying value of an error value can be access using `.value`
|
||||
selector.
|
||||
|
||||
|
||||
```golang
|
||||
err1 := error("oops") // error with string value
|
||||
err2 := error(1+2+3) // error with int value
|
||||
if is_error(err1) { // 'is_error' builtin function
|
||||
err_val := err1.value // get underlying value
|
||||
err_val := err1.value // get underlying value
|
||||
}
|
||||
```
|
||||
|
||||
#### Immutable Values
|
||||
### Immutable Values
|
||||
|
||||
In Tengo, basically all values (except for array and map) are immutable.
|
||||
|
||||
```golang
|
||||
s := "12345"
|
||||
s[1] = 'b' // illegal: String is immutable
|
||||
s[1] = 'b' // illegal: String is immutable
|
||||
|
||||
a := [1, 2, 3]
|
||||
a[1] = "two" // ok: a is now [1, "two", 3]
|
||||
```
|
||||
```
|
||||
|
||||
An array or map value can be made immutable using `immutable` expression.
|
||||
|
||||
```golang
|
||||
b := immutable([1, 2, 3])
|
||||
b[1] = "foo" // illegal: 'b' references to an immutable array.
|
||||
```
|
||||
```
|
||||
|
||||
Note that re-assigning a new value to the variable has nothing to do with the
|
||||
value immutability.
|
||||
|
@ -94,17 +94,17 @@ a := immutable({b: 4, c: [1, 2, 3]})
|
|||
a.b = 5 // illegal
|
||||
a.c[1] = 5 // ok: because 'a.c' is not immutable
|
||||
|
||||
a = immutable({b: 4, c: immutable([1, 2, 3])})
|
||||
a = immutable({b: 4, c: immutable([1, 2, 3])})
|
||||
a.c[1] = 5 // illegal
|
||||
```
|
||||
|
||||
#### Undefined Values
|
||||
|
||||
### Undefined Values
|
||||
|
||||
In Tengo, an "undefined" value can be used to represent an unexpected or
|
||||
non-existing value:
|
||||
|
||||
- A function that does not return a value explicitly considered to return
|
||||
`undefined` value.
|
||||
`undefined` value.
|
||||
- Indexer or selector on composite value types may return `undefined` if the
|
||||
key or index does not exist.
|
||||
- Type conversion builtin functions without a default value will return
|
||||
|
@ -117,7 +117,7 @@ c := {a: "foo"}["b"] // c == undefined
|
|||
d := int("foo") // d == undefined
|
||||
```
|
||||
|
||||
#### Array Values
|
||||
### Array Values
|
||||
|
||||
In Tengo, array is an ordered list of values of any types. Elements of an array
|
||||
can be accessed using indexer `[]`.
|
||||
|
@ -127,10 +127,10 @@ can be accessed using indexer `[]`.
|
|||
[1, 2, 3][2] // == 3
|
||||
[1, 2, 3][3] // == undefined
|
||||
|
||||
["foo", "bar", [1, 2, 3] // ok: array with an array element
|
||||
```
|
||||
["foo", "bar", [1, 2, 3]] // ok: array with an array element
|
||||
```
|
||||
|
||||
#### Map Values
|
||||
### Map Values
|
||||
|
||||
In Tengo, map is a set of key-value pairs where key is string and the value is
|
||||
of any value types. Value of a map can be accessed using indexer `[]` or
|
||||
|
@ -145,11 +145,11 @@ m.x // == undefined
|
|||
{a: [1,2,3], b: {c: "foo", d: "bar"}} // ok: map with an array element and a map element
|
||||
```
|
||||
|
||||
#### Function Values
|
||||
### Function Values
|
||||
|
||||
In Tengo, function is a callable value with a number of function arguments and
|
||||
a return value. Just like any other values, functions can be passed into or
|
||||
returned from another function.
|
||||
returned from another function.
|
||||
|
||||
```golang
|
||||
my_func := func(arg1, arg2) {
|
||||
|
@ -162,7 +162,7 @@ adder := func(base) {
|
|||
add5 := adder(5)
|
||||
nine := add5(4) // == 9
|
||||
```
|
||||
|
||||
|
||||
Unlike Go, Tengo does not have declarations. So the following code is illegal:
|
||||
|
||||
```golang
|
||||
|
@ -199,10 +199,10 @@ illegal := func(a..., b) { /*... */ }
|
|||
A value can be assigned to a variable using assignment operator `:=` and `=`.
|
||||
|
||||
- `:=` operator defines a new variable in the scope and assigns a value.
|
||||
- `=` operator assigns a new value to an existing variable in the scope.
|
||||
- `=` operator assigns a new value to an existing variable in the scope.
|
||||
|
||||
Variables are defined either in global scope (defined outside function) or in
|
||||
local scope (defined inside function).
|
||||
local scope (defined inside function).
|
||||
|
||||
```golang
|
||||
a := "foo" // define 'a' in global scope
|
||||
|
@ -212,11 +212,11 @@ func() { // function scope A
|
|||
|
||||
func() { // function scope B
|
||||
c := 19.84 // define 'c' in function scope B
|
||||
|
||||
a = "bee" // ok: assign new value to 'a' from global scope
|
||||
|
||||
a = "bee" // ok: assign new value to 'a' from global scope
|
||||
b = 20 // ok: assign new value to 'b' from function scope A
|
||||
|
||||
b := true // ok: define new 'b' in function scope B
|
||||
|
||||
b := true // ok: define new 'b' in function scope B
|
||||
// (shadowing 'b' from function scope A)
|
||||
}
|
||||
|
||||
|
@ -246,7 +246,7 @@ a = [1, 2, 3] // re-assigned 'array'
|
|||
Although the type is not directly specified in Tengo, one can use type
|
||||
conversion
|
||||
[builtin functions](https://github.com/d5/tengo/blob/master/docs/builtins.md)
|
||||
to convert between value types.
|
||||
to convert between value types.
|
||||
|
||||
```golang
|
||||
s1 := string(1984) // "1984"
|
||||
|
@ -346,7 +346,7 @@ comparison operators, `&&` (logical AND), and finally `||` (logical OR):
|
|||
| 1 | `\|\|` |
|
||||
|
||||
Like Go, `++` and `--` operators form statements, not expressions, they fall
|
||||
outside the operator hierarchy.
|
||||
outside the operator hierarchy.
|
||||
|
||||
### Selector and Indexer
|
||||
|
||||
|
@ -368,7 +368,7 @@ m.x = 5 // add 'x' to map 'm'
|
|||
m["b"][5] // == undefined
|
||||
m["b"][5].d // == undefined
|
||||
m.b[5] = 0 // == undefined
|
||||
m.x.y.z // == undefined
|
||||
m.x.y.z // == undefined
|
||||
```
|
||||
|
||||
Like Go, one can use slice operator `[:]` for sequence value types such as
|
||||
|
@ -382,16 +382,15 @@ d := "hello world"[2:10] // == "llo worl"
|
|||
c := [1, 2, 3, 4, 5][-1:10] // == [1, 2, 3, 4, 5]
|
||||
```
|
||||
|
||||
|
||||
## Statements
|
||||
|
||||
### If Statement
|
||||
|
||||
"If" statement is very similar to Go.
|
||||
"If" statement is very similar to Go.
|
||||
|
||||
```golang
|
||||
if a < 0 {
|
||||
// execute if 'a' is negative
|
||||
// execute if 'a' is negative
|
||||
} else if a == 0 {
|
||||
// execute if 'a' is zero
|
||||
} else {
|
||||
|
@ -400,7 +399,7 @@ if a < 0 {
|
|||
```
|
||||
|
||||
Like Go, the condition expression may be preceded by a simple statement,
|
||||
which executes before the expression is evaluated.
|
||||
which executes before the expression is evaluated.
|
||||
|
||||
```golang
|
||||
if a := foo(); a < 0 {
|
||||
|
@ -410,7 +409,7 @@ if a := foo(); a < 0 {
|
|||
|
||||
### For Statement
|
||||
|
||||
"For" statement is very similar to Go.
|
||||
"For" statement is very similar to Go.
|
||||
|
||||
```golang
|
||||
// for (init); (condition); (post) {}
|
||||
|
@ -442,7 +441,7 @@ for v in [1, 2, 3] { // array: element
|
|||
for i, v in [1, 2, 3] { // array: index and element
|
||||
// 'i' is index
|
||||
// 'v' is value
|
||||
}
|
||||
}
|
||||
for k, v in {k1: 1, k2: 2} { // map: key and value
|
||||
// 'k' is key
|
||||
// 'v' is value
|
||||
|
@ -452,13 +451,13 @@ for k, v in {k1: 1, k2: 2} { // map: key and value
|
|||
## Modules
|
||||
|
||||
Module is the basic compilation unit in Tengo. A module can import another
|
||||
module using `import` expression.
|
||||
module using `import` expression.
|
||||
|
||||
Main module:
|
||||
|
||||
```golang
|
||||
sum := import("./sum") // load module from a local file
|
||||
fmt.print(sum(10)) // module function
|
||||
fmt.print(sum(10)) // module function
|
||||
```
|
||||
|
||||
Another module in `sum.tengo` file:
|
||||
|
@ -473,7 +472,7 @@ export func(x) {
|
|||
|
||||
In Tengo, modules are very similar to functions.
|
||||
|
||||
- `import` expression loads the module code and execute it like a function.
|
||||
- `import` expression loads the module code and execute it like a function.
|
||||
- Module should return a value using `export` statement.
|
||||
- Module can return `export` a value of any types: int, map, function, etc.
|
||||
- `export` in a module is like `return` in a function: it stops execution and
|
||||
|
@ -492,15 +491,15 @@ well.
|
|||
math := import("math")
|
||||
a := math.abs(-19.84) // == 19.84
|
||||
```
|
||||
|
||||
|
||||
## Comments
|
||||
|
||||
Like Go, Tengo supports line comments (`//...`) and block comments
|
||||
(`/* ... */`).
|
||||
|
||||
```golang
|
||||
/*
|
||||
multi-line block comments
|
||||
/*
|
||||
multi-line block comments
|
||||
*/
|
||||
|
||||
a := 5 // line comments
|
||||
|
@ -521,5 +520,5 @@ Unlike Go, Tengo does not have the following:
|
|||
- Switch statement
|
||||
- Goto statement
|
||||
- Defer statement
|
||||
- Panic
|
||||
- Panic
|
||||
- Type assertion
|
||||
|
|
Loading…
Reference in a new issue