forking.
This commit is contained in:
parent
c461a7fe60
commit
3afc180451
97 changed files with 2853 additions and 1917 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
||||||
|
/bin
|
||||||
|
/xgo
|
||||||
dist/
|
dist/
|
||||||
|
.idea
|
||||||
.idea
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package tengo
|
package xgo
|
||||||
|
|
||||||
var builtinFuncs = []*BuiltinFunction{
|
var builtinFuncs = []*BuiltinFunction{
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package tengo_test
|
package xgo_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_builtinDelete(t *testing.T) {
|
func Test_builtinDelete(t *testing.T) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package tengo
|
package xgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
|
@ -6,7 +6,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2/parser"
|
"surdeus.su/core/xgo/v2/parser"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Bytecode is a compiled instructions and constants.
|
// Bytecode is a compiled instructions and constants.
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package tengo_test
|
package xgo_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
"github.com/d5/tengo/v2/parser"
|
"surdeus.su/core/xgo/v2/parser"
|
||||||
"github.com/d5/tengo/v2/require"
|
"surdeus.su/core/xgo/v2/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
type srcfile struct {
|
type srcfile struct {
|
||||||
|
|
|
@ -4,8 +4,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
"github.com/d5/tengo/v2/parser"
|
"surdeus.su/core/xgo/v2/parser"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -6,18 +6,17 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
"github.com/d5/tengo/v2/parser"
|
"surdeus.su/core/xgo/v2/parser"
|
||||||
"github.com/d5/tengo/v2/stdlib"
|
"surdeus.su/core/xgo/v2/stdlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
sourceFileExt = ".tengo"
|
sourceFileExt = ".xgo"
|
||||||
replPrompt = ">> "
|
replPrompt = ">> "
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -55,7 +54,7 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
inputData, err := ioutil.ReadFile(inputFile)
|
inputData, err := os.ReadFile(inputFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_, _ = fmt.Fprintf(os.Stderr,
|
_, _ = fmt.Fprintf(os.Stderr,
|
||||||
"Error reading input file: %s\n", err.Error())
|
"Error reading input file: %s\n", err.Error())
|
||||||
|
@ -96,7 +95,7 @@ func main() {
|
||||||
// CompileOnly compiles the source code and writes the compiled binary into
|
// CompileOnly compiles the source code and writes the compiled binary into
|
||||||
// outputFile.
|
// outputFile.
|
||||||
func CompileOnly(
|
func CompileOnly(
|
||||||
modules *tengo.ModuleMap,
|
modules *xgo.ModuleMap,
|
||||||
data []byte,
|
data []byte,
|
||||||
inputFile, outputFile string,
|
inputFile, outputFile string,
|
||||||
) (err error) {
|
) (err error) {
|
||||||
|
@ -131,7 +130,7 @@ func CompileOnly(
|
||||||
|
|
||||||
// CompileAndRun compiles the source code and executes it.
|
// CompileAndRun compiles the source code and executes it.
|
||||||
func CompileAndRun(
|
func CompileAndRun(
|
||||||
modules *tengo.ModuleMap,
|
modules *xgo.ModuleMap,
|
||||||
data []byte,
|
data []byte,
|
||||||
inputFile string,
|
inputFile string,
|
||||||
) (err error) {
|
) (err error) {
|
||||||
|
@ -140,45 +139,45 @@ func CompileAndRun(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
machine := tengo.NewVM(bytecode, nil, -1)
|
machine := xgo.NewVM(bytecode, nil, -1)
|
||||||
err = machine.Run()
|
err = machine.Run()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunCompiled reads the compiled binary from file and executes it.
|
// RunCompiled reads the compiled binary from file and executes it.
|
||||||
func RunCompiled(modules *tengo.ModuleMap, data []byte) (err error) {
|
func RunCompiled(modules *xgo.ModuleMap, data []byte) (err error) {
|
||||||
bytecode := &tengo.Bytecode{}
|
bytecode := &xgo.Bytecode{}
|
||||||
err = bytecode.Decode(bytes.NewReader(data), modules)
|
err = bytecode.Decode(bytes.NewReader(data), modules)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
machine := tengo.NewVM(bytecode, nil, -1)
|
machine := xgo.NewVM(bytecode, nil, -1)
|
||||||
err = machine.Run()
|
err = machine.Run()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunREPL starts REPL.
|
// RunREPL starts REPL.
|
||||||
func RunREPL(modules *tengo.ModuleMap, in io.Reader, out io.Writer) {
|
func RunREPL(modules *xgo.ModuleMap, in io.Reader, out io.Writer) {
|
||||||
stdin := bufio.NewScanner(in)
|
stdin := bufio.NewScanner(in)
|
||||||
fileSet := parser.NewFileSet()
|
fileSet := parser.NewFileSet()
|
||||||
globals := make([]tengo.Object, tengo.GlobalsSize)
|
globals := make([]xgo.Object, xgo.GlobalsSize)
|
||||||
symbolTable := tengo.NewSymbolTable()
|
symbolTable := xgo.NewSymbolTable()
|
||||||
for idx, fn := range tengo.GetAllBuiltinFunctions() {
|
for idx, fn := range xgo.GetAllBuiltinFunctions() {
|
||||||
symbolTable.DefineBuiltin(idx, fn.Name)
|
symbolTable.DefineBuiltin(idx, fn.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// embed println function
|
// embed println function
|
||||||
symbol := symbolTable.Define("__repl_println__")
|
symbol := symbolTable.Define("__repl_println__")
|
||||||
globals[symbol.Index] = &tengo.UserFunction{
|
globals[symbol.Index] = &xgo.UserFunction{
|
||||||
Name: "println",
|
Name: "println",
|
||||||
Value: func(args ...tengo.Object) (ret tengo.Object, err error) {
|
Value: func(args ...xgo.Object) (ret xgo.Object, err error) {
|
||||||
var printArgs []interface{}
|
var printArgs []interface{}
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
if _, isUndefined := arg.(*tengo.Undefined); isUndefined {
|
if _, isUndefined := arg.(*xgo.Undefined); isUndefined {
|
||||||
printArgs = append(printArgs, "<undefined>")
|
printArgs = append(printArgs, "<undefined>")
|
||||||
} else {
|
} else {
|
||||||
s, _ := tengo.ToString(arg)
|
s, _ := xgo.ToString(arg)
|
||||||
printArgs = append(printArgs, s)
|
printArgs = append(printArgs, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,7 +187,7 @@ func RunREPL(modules *tengo.ModuleMap, in io.Reader, out io.Writer) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var constants []tengo.Object
|
var constants []xgo.Object
|
||||||
for {
|
for {
|
||||||
_, _ = fmt.Fprint(out, replPrompt)
|
_, _ = fmt.Fprint(out, replPrompt)
|
||||||
scanned := stdin.Scan()
|
scanned := stdin.Scan()
|
||||||
|
@ -206,14 +205,14 @@ func RunREPL(modules *tengo.ModuleMap, in io.Reader, out io.Writer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
file = addPrints(file)
|
file = addPrints(file)
|
||||||
c := tengo.NewCompiler(srcFile, symbolTable, constants, modules, nil)
|
c := xgo.NewCompiler(srcFile, symbolTable, constants, modules, nil)
|
||||||
if err := c.Compile(file); err != nil {
|
if err := c.Compile(file); err != nil {
|
||||||
_, _ = fmt.Fprintln(out, err.Error())
|
_, _ = fmt.Fprintln(out, err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
bytecode := c.Bytecode()
|
bytecode := c.Bytecode()
|
||||||
machine := tengo.NewVM(bytecode, globals, -1)
|
machine := xgo.NewVM(bytecode, globals, -1)
|
||||||
if err := machine.Run(); err != nil {
|
if err := machine.Run(); err != nil {
|
||||||
_, _ = fmt.Fprintln(out, err.Error())
|
_, _ = fmt.Fprintln(out, err.Error())
|
||||||
continue
|
continue
|
||||||
|
@ -223,10 +222,10 @@ func RunREPL(modules *tengo.ModuleMap, in io.Reader, out io.Writer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func compileSrc(
|
func compileSrc(
|
||||||
modules *tengo.ModuleMap,
|
modules *xgo.ModuleMap,
|
||||||
src []byte,
|
src []byte,
|
||||||
inputFile string,
|
inputFile string,
|
||||||
) (*tengo.Bytecode, error) {
|
) (*xgo.Bytecode, error) {
|
||||||
fileSet := parser.NewFileSet()
|
fileSet := parser.NewFileSet()
|
||||||
srcFile := fileSet.AddFile(filepath.Base(inputFile), -1, len(src))
|
srcFile := fileSet.AddFile(filepath.Base(inputFile), -1, len(src))
|
||||||
|
|
||||||
|
@ -236,7 +235,7 @@ func compileSrc(
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c := tengo.NewCompiler(srcFile, nil, nil, modules, nil)
|
c := xgo.NewCompiler(srcFile, nil, nil, modules, nil)
|
||||||
c.EnableFileImport(true)
|
c.EnableFileImport(true)
|
||||||
if resolvePath {
|
if resolvePath {
|
||||||
c.SetImportDir(filepath.Dir(inputFile))
|
c.SetImportDir(filepath.Dir(inputFile))
|
||||||
|
@ -254,7 +253,7 @@ func compileSrc(
|
||||||
func doHelp() {
|
func doHelp() {
|
||||||
fmt.Println("Usage:")
|
fmt.Println("Usage:")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println(" tengo [flags] {input-file}")
|
fmt.Println(" xgo [flags] {input-file}")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("Flags:")
|
fmt.Println("Flags:")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
@ -263,20 +262,20 @@ func doHelp() {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("Examples:")
|
fmt.Println("Examples:")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println(" tengo")
|
fmt.Println(" xgo")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println(" Start Tengo REPL")
|
fmt.Println(" Start Tengo REPL")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println(" tengo myapp.tengo")
|
fmt.Println(" xgo myapp.xgo")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println(" Compile and run source file (myapp.tengo)")
|
fmt.Println(" Compile and run source file (myapp.xgo)")
|
||||||
fmt.Println(" Source file must have .tengo extension")
|
fmt.Println(" Source file must have .xgo extension")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println(" tengo -o myapp myapp.tengo")
|
fmt.Println(" xgo -o myapp myapp.xgo")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println(" Compile source file (myapp.tengo) into bytecode file (myapp)")
|
fmt.Println(" Compile source file (myapp.xgo) into bytecode file (myapp)")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println(" tengo myapp")
|
fmt.Println(" xgo myapp")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println(" Run bytecode file (myapp)")
|
fmt.Println(" Run bytecode file (myapp)")
|
||||||
fmt.Println()
|
fmt.Println()
|
10
compiler.go
10
compiler.go
|
@ -1,4 +1,4 @@
|
||||||
package tengo
|
package xgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -10,8 +10,8 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2/parser"
|
"surdeus.su/core/xgo/v2/parser"
|
||||||
"github.com/d5/tengo/v2/token"
|
"surdeus.su/core/xgo/v2/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
// compilationScope represents a compiled instructions and the last two
|
// compilationScope represents a compiled instructions and the last two
|
||||||
|
@ -631,8 +631,8 @@ func (c *Compiler) SetImportDir(dir string) {
|
||||||
//
|
//
|
||||||
// Use this method if you want other source file extension than ".tengo".
|
// Use this method if you want other source file extension than ".tengo".
|
||||||
//
|
//
|
||||||
// // this will search for *.tengo, *.foo, *.bar
|
// // this will search for *.tengo, *.foo, *.bar
|
||||||
// err := c.SetImportFileExt(".tengo", ".foo", ".bar")
|
// err := c.SetImportFileExt(".tengo", ".foo", ".bar")
|
||||||
//
|
//
|
||||||
// This function requires at least one argument, since it will replace the
|
// This function requires at least one argument, since it will replace the
|
||||||
// current list of extension name.
|
// current list of extension name.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package tengo_test
|
package xgo_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -7,10 +7,10 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
"github.com/d5/tengo/v2/parser"
|
"surdeus.su/core/xgo/v2/parser"
|
||||||
"github.com/d5/tengo/v2/require"
|
"surdeus.su/core/xgo/v2/require"
|
||||||
"github.com/d5/tengo/v2/stdlib"
|
"surdeus.su/core/xgo/v2/stdlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCompiler_Compile(t *testing.T) {
|
func TestCompiler_Compile(t *testing.T) {
|
||||||
|
|
2
doc.go
2
doc.go
|
@ -1,3 +1,3 @@
|
||||||
// tengo is a small, dynamic, fast, secure script language for Go.
|
// tengo is a small, dynamic, fast, secure script language for Go.
|
||||||
|
|
||||||
package tengo
|
package xgo
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package tengo
|
package xgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
2
eval.go
2
eval.go
|
@ -1,4 +1,4 @@
|
||||||
package tengo
|
package xgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package tengo_test
|
package xgo_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
"github.com/d5/tengo/v2/require"
|
"surdeus.su/core/xgo/v2/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestEval(t *testing.T) {
|
func TestEval(t *testing.T) {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package tengo_test
|
package xgo_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Example() {
|
func Example() {
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CallArgs holds function name to be executed and its required parameters with
|
// CallArgs holds function name to be executed and its required parameters with
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package tengo
|
package xgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
4
go.mod
4
go.mod
|
@ -1,3 +1,3 @@
|
||||||
module github.com/d5/tengo/v2
|
module surdeus.su/core/xgo/v2
|
||||||
|
|
||||||
go 1.13
|
go 1.18
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package tengo
|
package xgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2/parser"
|
"surdeus.su/core/xgo/v2/parser"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MakeInstruction returns a bytecode for an opcode and the operands.
|
// MakeInstruction returns a bytecode for an opcode and the operands.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package tengo
|
package xgo
|
||||||
|
|
||||||
// Iterator represents an iterator for underlying data type.
|
// Iterator represents an iterator for underlying data type.
|
||||||
type Iterator interface {
|
type Iterator interface {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package tengo
|
package xgo
|
||||||
|
|
||||||
// Importable interface represents importable module instance.
|
// Importable interface represents importable module instance.
|
||||||
type Importable interface {
|
type Importable interface {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package tengo
|
package xgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -8,8 +8,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2/parser"
|
"surdeus.su/core/xgo/v2/parser"
|
||||||
"github.com/d5/tengo/v2/token"
|
"surdeus.su/core/xgo/v2/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package tengo_test
|
package xgo_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
"github.com/d5/tengo/v2/require"
|
"surdeus.su/core/xgo/v2/require"
|
||||||
"github.com/d5/tengo/v2/token"
|
"surdeus.su/core/xgo/v2/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestObject_TypeName(t *testing.T) {
|
func TestObject_TypeName(t *testing.T) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package parser_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2/parser"
|
"surdeus.su/core/xgo/v2/parser"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestIdentListString(t *testing.T) {
|
func TestIdentListString(t *testing.T) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package parser
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2/token"
|
"surdeus.su/core/xgo/v2/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Expr represents an expression node in the AST.
|
// Expr represents an expression node in the AST.
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2/token"
|
"surdeus.su/core/xgo/v2/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
type bailout struct{}
|
type bailout struct{}
|
||||||
|
|
|
@ -8,9 +8,9 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
. "github.com/d5/tengo/v2/parser"
|
. "surdeus.su/core/xgo/v2/parser"
|
||||||
"github.com/d5/tengo/v2/require"
|
"surdeus.su/core/xgo/v2/require"
|
||||||
"github.com/d5/tengo/v2/token"
|
"surdeus.su/core/xgo/v2/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestParserError(t *testing.T) {
|
func TestParserError(t *testing.T) {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2/token"
|
"surdeus.su/core/xgo/v2/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
// byte order mark
|
// byte order mark
|
||||||
|
|
|
@ -7,9 +7,9 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2/parser"
|
"surdeus.su/core/xgo/v2/parser"
|
||||||
"github.com/d5/tengo/v2/require"
|
"surdeus.su/core/xgo/v2/require"
|
||||||
"github.com/d5/tengo/v2/token"
|
"surdeus.su/core/xgo/v2/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
var testFileSet = parser.NewFileSet()
|
var testFileSet = parser.NewFileSet()
|
||||||
|
|
|
@ -3,7 +3,7 @@ package parser
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2/token"
|
"surdeus.su/core/xgo/v2/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Stmt represents a statement in the AST.
|
// Stmt represents a statement in the AST.
|
||||||
|
|
|
@ -10,9 +10,9 @@ import (
|
||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
"github.com/d5/tengo/v2/parser"
|
"surdeus.su/core/xgo/v2/parser"
|
||||||
"github.com/d5/tengo/v2/token"
|
"surdeus.su/core/xgo/v2/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NoError asserts err is not an error.
|
// NoError asserts err is not an error.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package tengo
|
package xgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
@ -6,7 +6,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2/parser"
|
"surdeus.su/core/xgo/v2/parser"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Script can simplify compilation and execution of embedded scripts.
|
// Script can simplify compilation and execution of embedded scripts.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package tengo_test
|
package xgo_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
@ -11,10 +11,10 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
"github.com/d5/tengo/v2/require"
|
"surdeus.su/core/xgo/v2/require"
|
||||||
"github.com/d5/tengo/v2/stdlib"
|
"surdeus.su/core/xgo/v2/stdlib"
|
||||||
"github.com/d5/tengo/v2/token"
|
"surdeus.su/core/xgo/v2/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestScript_Add(t *testing.T) {
|
func TestScript_Add(t *testing.T) {
|
||||||
|
|
|
@ -3,32 +3,32 @@ package stdlib
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var base64Module = map[string]tengo.Object{
|
var base64Module = map[string]xgo.Object{
|
||||||
"encode": &tengo.UserFunction{
|
"encode": &xgo.UserFunction{
|
||||||
Value: FuncAYRS(base64.StdEncoding.EncodeToString),
|
Value: FuncAYRS(base64.StdEncoding.EncodeToString),
|
||||||
},
|
},
|
||||||
"decode": &tengo.UserFunction{
|
"decode": &xgo.UserFunction{
|
||||||
Value: FuncASRYE(base64.StdEncoding.DecodeString),
|
Value: FuncASRYE(base64.StdEncoding.DecodeString),
|
||||||
},
|
},
|
||||||
"raw_encode": &tengo.UserFunction{
|
"raw_encode": &xgo.UserFunction{
|
||||||
Value: FuncAYRS(base64.RawStdEncoding.EncodeToString),
|
Value: FuncAYRS(base64.RawStdEncoding.EncodeToString),
|
||||||
},
|
},
|
||||||
"raw_decode": &tengo.UserFunction{
|
"raw_decode": &xgo.UserFunction{
|
||||||
Value: FuncASRYE(base64.RawStdEncoding.DecodeString),
|
Value: FuncASRYE(base64.RawStdEncoding.DecodeString),
|
||||||
},
|
},
|
||||||
"url_encode": &tengo.UserFunction{
|
"url_encode": &xgo.UserFunction{
|
||||||
Value: FuncAYRS(base64.URLEncoding.EncodeToString),
|
Value: FuncAYRS(base64.URLEncoding.EncodeToString),
|
||||||
},
|
},
|
||||||
"url_decode": &tengo.UserFunction{
|
"url_decode": &xgo.UserFunction{
|
||||||
Value: FuncASRYE(base64.URLEncoding.DecodeString),
|
Value: FuncASRYE(base64.URLEncoding.DecodeString),
|
||||||
},
|
},
|
||||||
"raw_url_encode": &tengo.UserFunction{
|
"raw_url_encode": &xgo.UserFunction{
|
||||||
Value: FuncAYRS(base64.RawURLEncoding.EncodeToString),
|
Value: FuncAYRS(base64.RawURLEncoding.EncodeToString),
|
||||||
},
|
},
|
||||||
"raw_url_decode": &tengo.UserFunction{
|
"raw_url_decode": &xgo.UserFunction{
|
||||||
Value: FuncASRYE(base64.RawURLEncoding.DecodeString),
|
Value: FuncASRYE(base64.RawURLEncoding.DecodeString),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
package stdlib
|
package stdlib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
|
"surdeus.su/core/xgo/v2/stdlib/http"
|
||||||
|
"surdeus.su/core/xgo/v2/stdlib/paths"
|
||||||
|
"surdeus.su/core/xgo/v2/stdlib/html"
|
||||||
|
"surdeus.su/core/xgo/v2/stdlib/log"
|
||||||
|
"surdeus.su/core/xgo/v2/stdlib/cjson"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BuiltinModules are builtin type standard library modules.
|
// BuiltinModules are builtin type standard library modules.
|
||||||
var BuiltinModules = map[string]map[string]tengo.Object{
|
var BuiltinModules = map[string]map[string]xgo.Object{
|
||||||
"math": mathModule,
|
"math": mathModule,
|
||||||
"os": osModule,
|
"os": osModule,
|
||||||
"text": textModule,
|
"text": textModule,
|
||||||
|
@ -15,4 +20,11 @@ var BuiltinModules = map[string]map[string]tengo.Object{
|
||||||
"json": jsonModule,
|
"json": jsonModule,
|
||||||
"base64": base64Module,
|
"base64": base64Module,
|
||||||
"hex": hexModule,
|
"hex": hexModule,
|
||||||
|
// Implement later.
|
||||||
|
"url": nil,
|
||||||
|
"http": http.Module,
|
||||||
|
"paths": paths.Module,
|
||||||
|
"html": html.Module,
|
||||||
|
"log": log.Module,
|
||||||
|
"cjson": cjson.Module,
|
||||||
}
|
}
|
||||||
|
|
108
stdlib/cjson/dec.go
Normal file
108
stdlib/cjson/dec.go
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
package cjson
|
||||||
|
|
||||||
|
import "surdeus.su/core/xgo/v2"
|
||||||
|
import tjson "surdeus.su/core/xgo/v2/stdlib/json"
|
||||||
|
|
||||||
|
import "encoding/json"
|
||||||
|
import "io"
|
||||||
|
import "errors"
|
||||||
|
import "os"
|
||||||
|
|
||||||
|
type Decoder struct {
|
||||||
|
xgo.ObjectImpl
|
||||||
|
dec *json.Decoder
|
||||||
|
end bool
|
||||||
|
inputName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Decoder) TypeName() string {
|
||||||
|
return "cjson.Decoder"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Decoder) String() string {
|
||||||
|
return "cjson.Decoder{...}"
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDecoder(args ...xgo.Object) (xgo.Object, error) {
|
||||||
|
var inputName string
|
||||||
|
if len(args) == 0 {
|
||||||
|
inputName = StrStdin
|
||||||
|
} else if len(args) > 1 {
|
||||||
|
return nil, xgo.ErrWrongNumArguments
|
||||||
|
} else {
|
||||||
|
var ok bool
|
||||||
|
inputObject := args[0]
|
||||||
|
inputName, ok = xgo.ToString(inputObject)
|
||||||
|
if !ok {
|
||||||
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
|
Name: "first",
|
||||||
|
Expected: "stringer",
|
||||||
|
Found: inputObject.TypeName(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var reader io.Reader
|
||||||
|
var err error
|
||||||
|
switch {
|
||||||
|
case inputName == StrStdin:
|
||||||
|
reader = os.Stdin
|
||||||
|
default:
|
||||||
|
reader, err = os.Open(inputName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := &Decoder{}
|
||||||
|
ret.dec = json.NewDecoder(reader)
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Decoder) IndexGet(
|
||||||
|
index xgo.Object,
|
||||||
|
) (xgo.Object, error) {
|
||||||
|
key, ok := xgo.ToString(index)
|
||||||
|
if !ok {
|
||||||
|
return nil, xgo.ErrInvalidIndexValueType
|
||||||
|
}
|
||||||
|
|
||||||
|
switch key {
|
||||||
|
case "decode":
|
||||||
|
return &xgo.UserFunction{
|
||||||
|
Name: "decode",
|
||||||
|
Value: d.Decode,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nothing found.
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Decoder) Decode(
|
||||||
|
args ...xgo.Object,
|
||||||
|
) (xgo.Object, error) {
|
||||||
|
if len(args) > 0 {
|
||||||
|
return nil, xgo.ErrWrongNumArguments
|
||||||
|
}
|
||||||
|
if d.end {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var v any
|
||||||
|
err := d.dec.Decode(&v)
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, io.EOF) {
|
||||||
|
d.end = true
|
||||||
|
} else {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bts, err := json.Marshal(v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return tjson.Decode(bts)
|
||||||
|
}
|
23
stdlib/cjson/main.go
Normal file
23
stdlib/cjson/main.go
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
package cjson
|
||||||
|
|
||||||
|
import "surdeus.su/core/xgo/v2"
|
||||||
|
import "io"
|
||||||
|
import "encoding/json"
|
||||||
|
|
||||||
|
//import "github.com/d5/xgo/v2/stdlib"
|
||||||
|
|
||||||
|
const (
|
||||||
|
StrStdin = "<stdin>"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Module = map[string]xgo.Object{
|
||||||
|
"Decoder": &xgo.BuiltinFunction{
|
||||||
|
Name: "Decoder",
|
||||||
|
Value: NewDecoder,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
type Encoder struct {
|
||||||
|
enc *json.Encoder
|
||||||
|
output io.Writer
|
||||||
|
}
|
|
@ -1,12 +1,12 @@
|
||||||
package stdlib
|
package stdlib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func wrapError(err error) tengo.Object {
|
func wrapError(err error) xgo.Object {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return tengo.TrueValue
|
return xgo.TrueValue
|
||||||
}
|
}
|
||||||
return &tengo.Error{Value: &tengo.String{Value: err.Error()}}
|
return &xgo.Error{Value: &xgo.String{Value: err.Error()}}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,17 +3,17 @@ package stdlib
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var fmtModule = map[string]tengo.Object{
|
var fmtModule = map[string]xgo.Object{
|
||||||
"print": &tengo.UserFunction{Name: "print", Value: fmtPrint},
|
"print": &xgo.UserFunction{Name: "print", Value: fmtPrint},
|
||||||
"printf": &tengo.UserFunction{Name: "printf", Value: fmtPrintf},
|
"printf": &xgo.UserFunction{Name: "printf", Value: fmtPrintf},
|
||||||
"println": &tengo.UserFunction{Name: "println", Value: fmtPrintln},
|
"println": &xgo.UserFunction{Name: "println", Value: fmtPrintln},
|
||||||
"sprintf": &tengo.UserFunction{Name: "sprintf", Value: fmtSprintf},
|
"sprintf": &xgo.UserFunction{Name: "sprintf", Value: fmtSprintf},
|
||||||
}
|
}
|
||||||
|
|
||||||
func fmtPrint(args ...tengo.Object) (ret tengo.Object, err error) {
|
func fmtPrint(args ...xgo.Object) (ret xgo.Object, err error) {
|
||||||
printArgs, err := getPrintArgs(args...)
|
printArgs, err := getPrintArgs(args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -22,15 +22,15 @@ func fmtPrint(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func fmtPrintf(args ...tengo.Object) (ret tengo.Object, err error) {
|
func fmtPrintf(args ...xgo.Object) (ret xgo.Object, err error) {
|
||||||
numArgs := len(args)
|
numArgs := len(args)
|
||||||
if numArgs == 0 {
|
if numArgs == 0 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
format, ok := args[0].(*tengo.String)
|
format, ok := args[0].(*xgo.String)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "format",
|
Name: "format",
|
||||||
Expected: "string",
|
Expected: "string",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -41,7 +41,7 @@ func fmtPrintf(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := tengo.Format(format.Value, args[1:]...)
|
s, err := xgo.Format(format.Value, args[1:]...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ func fmtPrintf(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func fmtPrintln(args ...tengo.Object) (ret tengo.Object, err error) {
|
func fmtPrintln(args ...xgo.Object) (ret xgo.Object, err error) {
|
||||||
printArgs, err := getPrintArgs(args...)
|
printArgs, err := getPrintArgs(args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -59,15 +59,15 @@ func fmtPrintln(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func fmtSprintf(args ...tengo.Object) (ret tengo.Object, err error) {
|
func fmtSprintf(args ...xgo.Object) (ret xgo.Object, err error) {
|
||||||
numArgs := len(args)
|
numArgs := len(args)
|
||||||
if numArgs == 0 {
|
if numArgs == 0 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
format, ok := args[0].(*tengo.String)
|
format, ok := args[0].(*xgo.String)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "format",
|
Name: "format",
|
||||||
Expected: "string",
|
Expected: "string",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -77,22 +77,22 @@ func fmtSprintf(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||||
// okay to return 'format' directly as String is immutable
|
// okay to return 'format' directly as String is immutable
|
||||||
return format, nil
|
return format, nil
|
||||||
}
|
}
|
||||||
s, err := tengo.Format(format.Value, args[1:]...)
|
s, err := xgo.Format(format.Value, args[1:]...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &tengo.String{Value: s}, nil
|
return &xgo.String{Value: s}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPrintArgs(args ...tengo.Object) ([]interface{}, error) {
|
func getPrintArgs(args ...xgo.Object) ([]interface{}, error) {
|
||||||
var printArgs []interface{}
|
var printArgs []interface{}
|
||||||
l := 0
|
l := 0
|
||||||
for _, arg := range args {
|
for _, arg := range args {
|
||||||
s, _ := tengo.ToString(arg)
|
s, _ := xgo.ToString(arg)
|
||||||
slen := len(s)
|
slen := len(s)
|
||||||
// make sure length does not exceed the limit
|
// make sure length does not exceed the limit
|
||||||
if l+slen > tengo.MaxStringLen {
|
if l+slen > xgo.MaxStringLen {
|
||||||
return nil, tengo.ErrStringLimit
|
return nil, xgo.ErrStringLimit
|
||||||
}
|
}
|
||||||
l += slen
|
l += slen
|
||||||
printArgs = append(printArgs, s)
|
printArgs = append(printArgs, s)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -6,51 +6,51 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
"github.com/d5/tengo/v2/require"
|
"surdeus.su/core/xgo/v2/require"
|
||||||
"github.com/d5/tengo/v2/stdlib"
|
"surdeus.su/core/xgo/v2/stdlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestFuncAIR(t *testing.T) {
|
func TestFuncAIR(t *testing.T) {
|
||||||
uf := stdlib.FuncAIR(func(int) {})
|
uf := stdlib.FuncAIR(func(int) {})
|
||||||
ret, err := funcCall(uf, &tengo.Int{Value: 10})
|
ret, err := funcCall(uf, &xgo.Int{Value: 10})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tengo.UndefinedValue, ret)
|
require.Equal(t, xgo.UndefinedValue, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncAR(t *testing.T) {
|
func TestFuncAR(t *testing.T) {
|
||||||
uf := stdlib.FuncAR(func() {})
|
uf := stdlib.FuncAR(func() {})
|
||||||
ret, err := funcCall(uf)
|
ret, err := funcCall(uf)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tengo.UndefinedValue, ret)
|
require.Equal(t, xgo.UndefinedValue, ret)
|
||||||
_, err = funcCall(uf, tengo.TrueValue)
|
_, err = funcCall(uf, xgo.TrueValue)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncARI(t *testing.T) {
|
func TestFuncARI(t *testing.T) {
|
||||||
uf := stdlib.FuncARI(func() int { return 10 })
|
uf := stdlib.FuncARI(func() int { return 10 })
|
||||||
ret, err := funcCall(uf)
|
ret, err := funcCall(uf)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.Int{Value: 10}, ret)
|
require.Equal(t, &xgo.Int{Value: 10}, ret)
|
||||||
_, err = funcCall(uf, tengo.TrueValue)
|
_, err = funcCall(uf, xgo.TrueValue)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncARE(t *testing.T) {
|
func TestFuncARE(t *testing.T) {
|
||||||
uf := stdlib.FuncARE(func() error { return nil })
|
uf := stdlib.FuncARE(func() error { return nil })
|
||||||
ret, err := funcCall(uf)
|
ret, err := funcCall(uf)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tengo.TrueValue, ret)
|
require.Equal(t, xgo.TrueValue, ret)
|
||||||
uf = stdlib.FuncARE(func() error { return errors.New("some error") })
|
uf = stdlib.FuncARE(func() error { return errors.New("some error") })
|
||||||
ret, err = funcCall(uf)
|
ret, err = funcCall(uf)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.Error{
|
require.Equal(t, &xgo.Error{
|
||||||
Value: &tengo.String{Value: "some error"},
|
Value: &xgo.String{Value: "some error"},
|
||||||
}, ret)
|
}, ret)
|
||||||
_, err = funcCall(uf, tengo.TrueValue)
|
_, err = funcCall(uf, xgo.TrueValue)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncARIsE(t *testing.T) {
|
func TestFuncARIsE(t *testing.T) {
|
||||||
|
@ -59,364 +59,364 @@ func TestFuncARIsE(t *testing.T) {
|
||||||
})
|
})
|
||||||
ret, err := funcCall(uf)
|
ret, err := funcCall(uf)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, array(&tengo.Int{Value: 1},
|
require.Equal(t, array(&xgo.Int{Value: 1},
|
||||||
&tengo.Int{Value: 2}, &tengo.Int{Value: 3}), ret)
|
&xgo.Int{Value: 2}, &xgo.Int{Value: 3}), ret)
|
||||||
uf = stdlib.FuncARIsE(func() ([]int, error) {
|
uf = stdlib.FuncARIsE(func() ([]int, error) {
|
||||||
return nil, errors.New("some error")
|
return nil, errors.New("some error")
|
||||||
})
|
})
|
||||||
ret, err = funcCall(uf)
|
ret, err = funcCall(uf)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.Error{
|
require.Equal(t, &xgo.Error{
|
||||||
Value: &tengo.String{Value: "some error"},
|
Value: &xgo.String{Value: "some error"},
|
||||||
}, ret)
|
}, ret)
|
||||||
_, err = funcCall(uf, tengo.TrueValue)
|
_, err = funcCall(uf, xgo.TrueValue)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncARS(t *testing.T) {
|
func TestFuncARS(t *testing.T) {
|
||||||
uf := stdlib.FuncARS(func() string { return "foo" })
|
uf := stdlib.FuncARS(func() string { return "foo" })
|
||||||
ret, err := funcCall(uf)
|
ret, err := funcCall(uf)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.String{Value: "foo"}, ret)
|
require.Equal(t, &xgo.String{Value: "foo"}, ret)
|
||||||
_, err = funcCall(uf, tengo.TrueValue)
|
_, err = funcCall(uf, xgo.TrueValue)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncARSE(t *testing.T) {
|
func TestFuncARSE(t *testing.T) {
|
||||||
uf := stdlib.FuncARSE(func() (string, error) { return "foo", nil })
|
uf := stdlib.FuncARSE(func() (string, error) { return "foo", nil })
|
||||||
ret, err := funcCall(uf)
|
ret, err := funcCall(uf)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.String{Value: "foo"}, ret)
|
require.Equal(t, &xgo.String{Value: "foo"}, ret)
|
||||||
uf = stdlib.FuncARSE(func() (string, error) {
|
uf = stdlib.FuncARSE(func() (string, error) {
|
||||||
return "", errors.New("some error")
|
return "", errors.New("some error")
|
||||||
})
|
})
|
||||||
ret, err = funcCall(uf)
|
ret, err = funcCall(uf)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.Error{
|
require.Equal(t, &xgo.Error{
|
||||||
Value: &tengo.String{Value: "some error"},
|
Value: &xgo.String{Value: "some error"},
|
||||||
}, ret)
|
}, ret)
|
||||||
_, err = funcCall(uf, tengo.TrueValue)
|
_, err = funcCall(uf, xgo.TrueValue)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncARSs(t *testing.T) {
|
func TestFuncARSs(t *testing.T) {
|
||||||
uf := stdlib.FuncARSs(func() []string { return []string{"foo", "bar"} })
|
uf := stdlib.FuncARSs(func() []string { return []string{"foo", "bar"} })
|
||||||
ret, err := funcCall(uf)
|
ret, err := funcCall(uf)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, array(&tengo.String{Value: "foo"},
|
require.Equal(t, array(&xgo.String{Value: "foo"},
|
||||||
&tengo.String{Value: "bar"}), ret)
|
&xgo.String{Value: "bar"}), ret)
|
||||||
_, err = funcCall(uf, tengo.TrueValue)
|
_, err = funcCall(uf, xgo.TrueValue)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncASRE(t *testing.T) {
|
func TestFuncASRE(t *testing.T) {
|
||||||
uf := stdlib.FuncASRE(func(a string) error { return nil })
|
uf := stdlib.FuncASRE(func(a string) error { return nil })
|
||||||
ret, err := funcCall(uf, &tengo.String{Value: "foo"})
|
ret, err := funcCall(uf, &xgo.String{Value: "foo"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tengo.TrueValue, ret)
|
require.Equal(t, xgo.TrueValue, ret)
|
||||||
uf = stdlib.FuncASRE(func(a string) error {
|
uf = stdlib.FuncASRE(func(a string) error {
|
||||||
return errors.New("some error")
|
return errors.New("some error")
|
||||||
})
|
})
|
||||||
ret, err = funcCall(uf, &tengo.String{Value: "foo"})
|
ret, err = funcCall(uf, &xgo.String{Value: "foo"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.Error{
|
require.Equal(t, &xgo.Error{
|
||||||
Value: &tengo.String{Value: "some error"},
|
Value: &xgo.String{Value: "some error"},
|
||||||
}, ret)
|
}, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncASRS(t *testing.T) {
|
func TestFuncASRS(t *testing.T) {
|
||||||
uf := stdlib.FuncASRS(func(a string) string { return a })
|
uf := stdlib.FuncASRS(func(a string) string { return a })
|
||||||
ret, err := funcCall(uf, &tengo.String{Value: "foo"})
|
ret, err := funcCall(uf, &xgo.String{Value: "foo"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.String{Value: "foo"}, ret)
|
require.Equal(t, &xgo.String{Value: "foo"}, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncASRSs(t *testing.T) {
|
func TestFuncASRSs(t *testing.T) {
|
||||||
uf := stdlib.FuncASRSs(func(a string) []string { return []string{a} })
|
uf := stdlib.FuncASRSs(func(a string) []string { return []string{a} })
|
||||||
ret, err := funcCall(uf, &tengo.String{Value: "foo"})
|
ret, err := funcCall(uf, &xgo.String{Value: "foo"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, array(&tengo.String{Value: "foo"}), ret)
|
require.Equal(t, array(&xgo.String{Value: "foo"}), ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncASI64RE(t *testing.T) {
|
func TestFuncASI64RE(t *testing.T) {
|
||||||
uf := stdlib.FuncASI64RE(func(a string, b int64) error { return nil })
|
uf := stdlib.FuncASI64RE(func(a string, b int64) error { return nil })
|
||||||
ret, err := funcCall(uf, &tengo.String{Value: "foo"}, &tengo.Int{Value: 5})
|
ret, err := funcCall(uf, &xgo.String{Value: "foo"}, &xgo.Int{Value: 5})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tengo.TrueValue, ret)
|
require.Equal(t, xgo.TrueValue, ret)
|
||||||
uf = stdlib.FuncASI64RE(func(a string, b int64) error {
|
uf = stdlib.FuncASI64RE(func(a string, b int64) error {
|
||||||
return errors.New("some error")
|
return errors.New("some error")
|
||||||
})
|
})
|
||||||
ret, err = funcCall(uf, &tengo.String{Value: "foo"}, &tengo.Int{Value: 5})
|
ret, err = funcCall(uf, &xgo.String{Value: "foo"}, &xgo.Int{Value: 5})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t,
|
require.Equal(t,
|
||||||
&tengo.Error{Value: &tengo.String{Value: "some error"}}, ret)
|
&xgo.Error{Value: &xgo.String{Value: "some error"}}, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncAIIRE(t *testing.T) {
|
func TestFuncAIIRE(t *testing.T) {
|
||||||
uf := stdlib.FuncAIIRE(func(a, b int) error { return nil })
|
uf := stdlib.FuncAIIRE(func(a, b int) error { return nil })
|
||||||
ret, err := funcCall(uf, &tengo.Int{Value: 5}, &tengo.Int{Value: 7})
|
ret, err := funcCall(uf, &xgo.Int{Value: 5}, &xgo.Int{Value: 7})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tengo.TrueValue, ret)
|
require.Equal(t, xgo.TrueValue, ret)
|
||||||
uf = stdlib.FuncAIIRE(func(a, b int) error {
|
uf = stdlib.FuncAIIRE(func(a, b int) error {
|
||||||
return errors.New("some error")
|
return errors.New("some error")
|
||||||
})
|
})
|
||||||
ret, err = funcCall(uf, &tengo.Int{Value: 5}, &tengo.Int{Value: 7})
|
ret, err = funcCall(uf, &xgo.Int{Value: 5}, &xgo.Int{Value: 7})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t,
|
require.Equal(t,
|
||||||
&tengo.Error{Value: &tengo.String{Value: "some error"}}, ret)
|
&xgo.Error{Value: &xgo.String{Value: "some error"}}, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncASIIRE(t *testing.T) {
|
func TestFuncASIIRE(t *testing.T) {
|
||||||
uf := stdlib.FuncASIIRE(func(a string, b, c int) error { return nil })
|
uf := stdlib.FuncASIIRE(func(a string, b, c int) error { return nil })
|
||||||
ret, err := funcCall(uf, &tengo.String{Value: "foo"}, &tengo.Int{Value: 5},
|
ret, err := funcCall(uf, &xgo.String{Value: "foo"}, &xgo.Int{Value: 5},
|
||||||
&tengo.Int{Value: 7})
|
&xgo.Int{Value: 7})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tengo.TrueValue, ret)
|
require.Equal(t, xgo.TrueValue, ret)
|
||||||
uf = stdlib.FuncASIIRE(func(a string, b, c int) error {
|
uf = stdlib.FuncASIIRE(func(a string, b, c int) error {
|
||||||
return errors.New("some error")
|
return errors.New("some error")
|
||||||
})
|
})
|
||||||
ret, err = funcCall(uf, &tengo.String{Value: "foo"}, &tengo.Int{Value: 5},
|
ret, err = funcCall(uf, &xgo.String{Value: "foo"}, &xgo.Int{Value: 5},
|
||||||
&tengo.Int{Value: 7})
|
&xgo.Int{Value: 7})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t,
|
require.Equal(t,
|
||||||
&tengo.Error{Value: &tengo.String{Value: "some error"}}, ret)
|
&xgo.Error{Value: &xgo.String{Value: "some error"}}, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncASRSE(t *testing.T) {
|
func TestFuncASRSE(t *testing.T) {
|
||||||
uf := stdlib.FuncASRSE(func(a string) (string, error) { return a, nil })
|
uf := stdlib.FuncASRSE(func(a string) (string, error) { return a, nil })
|
||||||
ret, err := funcCall(uf, &tengo.String{Value: "foo"})
|
ret, err := funcCall(uf, &xgo.String{Value: "foo"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.String{Value: "foo"}, ret)
|
require.Equal(t, &xgo.String{Value: "foo"}, ret)
|
||||||
uf = stdlib.FuncASRSE(func(a string) (string, error) {
|
uf = stdlib.FuncASRSE(func(a string) (string, error) {
|
||||||
return a, errors.New("some error")
|
return a, errors.New("some error")
|
||||||
})
|
})
|
||||||
ret, err = funcCall(uf, &tengo.String{Value: "foo"})
|
ret, err = funcCall(uf, &xgo.String{Value: "foo"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t,
|
require.Equal(t,
|
||||||
&tengo.Error{Value: &tengo.String{Value: "some error"}}, ret)
|
&xgo.Error{Value: &xgo.String{Value: "some error"}}, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncASSRE(t *testing.T) {
|
func TestFuncASSRE(t *testing.T) {
|
||||||
uf := stdlib.FuncASSRE(func(a, b string) error { return nil })
|
uf := stdlib.FuncASSRE(func(a, b string) error { return nil })
|
||||||
ret, err := funcCall(uf, &tengo.String{Value: "foo"},
|
ret, err := funcCall(uf, &xgo.String{Value: "foo"},
|
||||||
&tengo.String{Value: "bar"})
|
&xgo.String{Value: "bar"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tengo.TrueValue, ret)
|
require.Equal(t, xgo.TrueValue, ret)
|
||||||
uf = stdlib.FuncASSRE(func(a, b string) error {
|
uf = stdlib.FuncASSRE(func(a, b string) error {
|
||||||
return errors.New("some error")
|
return errors.New("some error")
|
||||||
})
|
})
|
||||||
ret, err = funcCall(uf, &tengo.String{Value: "foo"},
|
ret, err = funcCall(uf, &xgo.String{Value: "foo"},
|
||||||
&tengo.String{Value: "bar"})
|
&xgo.String{Value: "bar"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t,
|
require.Equal(t,
|
||||||
&tengo.Error{Value: &tengo.String{Value: "some error"}}, ret)
|
&xgo.Error{Value: &xgo.String{Value: "some error"}}, ret)
|
||||||
_, err = funcCall(uf, &tengo.String{Value: "foo"})
|
_, err = funcCall(uf, &xgo.String{Value: "foo"})
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncASsRS(t *testing.T) {
|
func TestFuncASsRS(t *testing.T) {
|
||||||
uf := stdlib.FuncASsSRS(func(a []string, b string) string {
|
uf := stdlib.FuncASsSRS(func(a []string, b string) string {
|
||||||
return strings.Join(a, b)
|
return strings.Join(a, b)
|
||||||
})
|
})
|
||||||
ret, err := funcCall(uf, array(&tengo.String{Value: "foo"},
|
ret, err := funcCall(uf, array(&xgo.String{Value: "foo"},
|
||||||
&tengo.String{Value: "bar"}), &tengo.String{Value: " "})
|
&xgo.String{Value: "bar"}), &xgo.String{Value: " "})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.String{Value: "foo bar"}, ret)
|
require.Equal(t, &xgo.String{Value: "foo bar"}, ret)
|
||||||
_, err = funcCall(uf, &tengo.String{Value: "foo"})
|
_, err = funcCall(uf, &xgo.String{Value: "foo"})
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncARF(t *testing.T) {
|
func TestFuncARF(t *testing.T) {
|
||||||
uf := stdlib.FuncARF(func() float64 { return 10.0 })
|
uf := stdlib.FuncARF(func() float64 { return 10.0 })
|
||||||
ret, err := funcCall(uf)
|
ret, err := funcCall(uf)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.Float{Value: 10.0}, ret)
|
require.Equal(t, &xgo.Float{Value: 10.0}, ret)
|
||||||
_, err = funcCall(uf, tengo.TrueValue)
|
_, err = funcCall(uf, xgo.TrueValue)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncAFRF(t *testing.T) {
|
func TestFuncAFRF(t *testing.T) {
|
||||||
uf := stdlib.FuncAFRF(func(a float64) float64 { return a })
|
uf := stdlib.FuncAFRF(func(a float64) float64 { return a })
|
||||||
ret, err := funcCall(uf, &tengo.Float{Value: 10.0})
|
ret, err := funcCall(uf, &xgo.Float{Value: 10.0})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.Float{Value: 10.0}, ret)
|
require.Equal(t, &xgo.Float{Value: 10.0}, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
_, err = funcCall(uf, tengo.TrueValue, tengo.TrueValue)
|
_, err = funcCall(uf, xgo.TrueValue, xgo.TrueValue)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncAIRF(t *testing.T) {
|
func TestFuncAIRF(t *testing.T) {
|
||||||
uf := stdlib.FuncAIRF(func(a int) float64 {
|
uf := stdlib.FuncAIRF(func(a int) float64 {
|
||||||
return float64(a)
|
return float64(a)
|
||||||
})
|
})
|
||||||
ret, err := funcCall(uf, &tengo.Int{Value: 10.0})
|
ret, err := funcCall(uf, &xgo.Int{Value: 10.0})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.Float{Value: 10.0}, ret)
|
require.Equal(t, &xgo.Float{Value: 10.0}, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
_, err = funcCall(uf, tengo.TrueValue, tengo.TrueValue)
|
_, err = funcCall(uf, xgo.TrueValue, xgo.TrueValue)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncAFRI(t *testing.T) {
|
func TestFuncAFRI(t *testing.T) {
|
||||||
uf := stdlib.FuncAFRI(func(a float64) int {
|
uf := stdlib.FuncAFRI(func(a float64) int {
|
||||||
return int(a)
|
return int(a)
|
||||||
})
|
})
|
||||||
ret, err := funcCall(uf, &tengo.Float{Value: 10.5})
|
ret, err := funcCall(uf, &xgo.Float{Value: 10.5})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.Int{Value: 10}, ret)
|
require.Equal(t, &xgo.Int{Value: 10}, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
_, err = funcCall(uf, tengo.TrueValue, tengo.TrueValue)
|
_, err = funcCall(uf, xgo.TrueValue, xgo.TrueValue)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncAFRB(t *testing.T) {
|
func TestFuncAFRB(t *testing.T) {
|
||||||
uf := stdlib.FuncAFRB(func(a float64) bool {
|
uf := stdlib.FuncAFRB(func(a float64) bool {
|
||||||
return a > 0.0
|
return a > 0.0
|
||||||
})
|
})
|
||||||
ret, err := funcCall(uf, &tengo.Float{Value: 0.1})
|
ret, err := funcCall(uf, &xgo.Float{Value: 0.1})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tengo.TrueValue, ret)
|
require.Equal(t, xgo.TrueValue, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
_, err = funcCall(uf, tengo.TrueValue, tengo.TrueValue)
|
_, err = funcCall(uf, xgo.TrueValue, xgo.TrueValue)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncAFFRF(t *testing.T) {
|
func TestFuncAFFRF(t *testing.T) {
|
||||||
uf := stdlib.FuncAFFRF(func(a, b float64) float64 {
|
uf := stdlib.FuncAFFRF(func(a, b float64) float64 {
|
||||||
return a + b
|
return a + b
|
||||||
})
|
})
|
||||||
ret, err := funcCall(uf, &tengo.Float{Value: 10.0},
|
ret, err := funcCall(uf, &xgo.Float{Value: 10.0},
|
||||||
&tengo.Float{Value: 20.0})
|
&xgo.Float{Value: 20.0})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.Float{Value: 30.0}, ret)
|
require.Equal(t, &xgo.Float{Value: 30.0}, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
_, err = funcCall(uf, tengo.TrueValue)
|
_, err = funcCall(uf, xgo.TrueValue)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncASIRS(t *testing.T) {
|
func TestFuncASIRS(t *testing.T) {
|
||||||
uf := stdlib.FuncASIRS(func(a string, b int) string {
|
uf := stdlib.FuncASIRS(func(a string, b int) string {
|
||||||
return strings.Repeat(a, b)
|
return strings.Repeat(a, b)
|
||||||
})
|
})
|
||||||
ret, err := funcCall(uf, &tengo.String{Value: "ab"}, &tengo.Int{Value: 2})
|
ret, err := funcCall(uf, &xgo.String{Value: "ab"}, &xgo.Int{Value: 2})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.String{Value: "abab"}, ret)
|
require.Equal(t, &xgo.String{Value: "abab"}, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
_, err = funcCall(uf, tengo.TrueValue)
|
_, err = funcCall(uf, xgo.TrueValue)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncAIFRF(t *testing.T) {
|
func TestFuncAIFRF(t *testing.T) {
|
||||||
uf := stdlib.FuncAIFRF(func(a int, b float64) float64 {
|
uf := stdlib.FuncAIFRF(func(a int, b float64) float64 {
|
||||||
return float64(a) + b
|
return float64(a) + b
|
||||||
})
|
})
|
||||||
ret, err := funcCall(uf, &tengo.Int{Value: 10}, &tengo.Float{Value: 20.0})
|
ret, err := funcCall(uf, &xgo.Int{Value: 10}, &xgo.Float{Value: 20.0})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.Float{Value: 30.0}, ret)
|
require.Equal(t, &xgo.Float{Value: 30.0}, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
_, err = funcCall(uf, tengo.TrueValue)
|
_, err = funcCall(uf, xgo.TrueValue)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncAFIRF(t *testing.T) {
|
func TestFuncAFIRF(t *testing.T) {
|
||||||
uf := stdlib.FuncAFIRF(func(a float64, b int) float64 {
|
uf := stdlib.FuncAFIRF(func(a float64, b int) float64 {
|
||||||
return a + float64(b)
|
return a + float64(b)
|
||||||
})
|
})
|
||||||
ret, err := funcCall(uf, &tengo.Float{Value: 10.0}, &tengo.Int{Value: 20})
|
ret, err := funcCall(uf, &xgo.Float{Value: 10.0}, &xgo.Int{Value: 20})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.Float{Value: 30.0}, ret)
|
require.Equal(t, &xgo.Float{Value: 30.0}, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
_, err = funcCall(uf, tengo.TrueValue)
|
_, err = funcCall(uf, xgo.TrueValue)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncAFIRB(t *testing.T) {
|
func TestFuncAFIRB(t *testing.T) {
|
||||||
uf := stdlib.FuncAFIRB(func(a float64, b int) bool {
|
uf := stdlib.FuncAFIRB(func(a float64, b int) bool {
|
||||||
return a < float64(b)
|
return a < float64(b)
|
||||||
})
|
})
|
||||||
ret, err := funcCall(uf, &tengo.Float{Value: 10.0}, &tengo.Int{Value: 20})
|
ret, err := funcCall(uf, &xgo.Float{Value: 10.0}, &xgo.Int{Value: 20})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tengo.TrueValue, ret)
|
require.Equal(t, xgo.TrueValue, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
_, err = funcCall(uf, tengo.TrueValue)
|
_, err = funcCall(uf, xgo.TrueValue)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncAIRSsE(t *testing.T) {
|
func TestFuncAIRSsE(t *testing.T) {
|
||||||
uf := stdlib.FuncAIRSsE(func(a int) ([]string, error) {
|
uf := stdlib.FuncAIRSsE(func(a int) ([]string, error) {
|
||||||
return []string{"foo", "bar"}, nil
|
return []string{"foo", "bar"}, nil
|
||||||
})
|
})
|
||||||
ret, err := funcCall(uf, &tengo.Int{Value: 10})
|
ret, err := funcCall(uf, &xgo.Int{Value: 10})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, array(&tengo.String{Value: "foo"},
|
require.Equal(t, array(&xgo.String{Value: "foo"},
|
||||||
&tengo.String{Value: "bar"}), ret)
|
&xgo.String{Value: "bar"}), ret)
|
||||||
uf = stdlib.FuncAIRSsE(func(a int) ([]string, error) {
|
uf = stdlib.FuncAIRSsE(func(a int) ([]string, error) {
|
||||||
return nil, errors.New("some error")
|
return nil, errors.New("some error")
|
||||||
})
|
})
|
||||||
ret, err = funcCall(uf, &tengo.Int{Value: 10})
|
ret, err = funcCall(uf, &xgo.Int{Value: 10})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t,
|
require.Equal(t,
|
||||||
&tengo.Error{Value: &tengo.String{Value: "some error"}}, ret)
|
&xgo.Error{Value: &xgo.String{Value: "some error"}}, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncASSRSs(t *testing.T) {
|
func TestFuncASSRSs(t *testing.T) {
|
||||||
uf := stdlib.FuncASSRSs(func(a, b string) []string {
|
uf := stdlib.FuncASSRSs(func(a, b string) []string {
|
||||||
return []string{a, b}
|
return []string{a, b}
|
||||||
})
|
})
|
||||||
ret, err := funcCall(uf, &tengo.String{Value: "foo"},
|
ret, err := funcCall(uf, &xgo.String{Value: "foo"},
|
||||||
&tengo.String{Value: "bar"})
|
&xgo.String{Value: "bar"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, array(&tengo.String{Value: "foo"},
|
require.Equal(t, array(&xgo.String{Value: "foo"},
|
||||||
&tengo.String{Value: "bar"}), ret)
|
&xgo.String{Value: "bar"}), ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncASSIRSs(t *testing.T) {
|
func TestFuncASSIRSs(t *testing.T) {
|
||||||
uf := stdlib.FuncASSIRSs(func(a, b string, c int) []string {
|
uf := stdlib.FuncASSIRSs(func(a, b string, c int) []string {
|
||||||
return []string{a, b, strconv.Itoa(c)}
|
return []string{a, b, strconv.Itoa(c)}
|
||||||
})
|
})
|
||||||
ret, err := funcCall(uf, &tengo.String{Value: "foo"},
|
ret, err := funcCall(uf, &xgo.String{Value: "foo"},
|
||||||
&tengo.String{Value: "bar"}, &tengo.Int{Value: 5})
|
&xgo.String{Value: "bar"}, &xgo.Int{Value: 5})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, array(&tengo.String{Value: "foo"},
|
require.Equal(t, array(&xgo.String{Value: "foo"},
|
||||||
&tengo.String{Value: "bar"}, &tengo.String{Value: "5"}), ret)
|
&xgo.String{Value: "bar"}, &xgo.String{Value: "5"}), ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncARB(t *testing.T) {
|
func TestFuncARB(t *testing.T) {
|
||||||
uf := stdlib.FuncARB(func() bool { return true })
|
uf := stdlib.FuncARB(func() bool { return true })
|
||||||
ret, err := funcCall(uf)
|
ret, err := funcCall(uf)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tengo.TrueValue, ret)
|
require.Equal(t, xgo.TrueValue, ret)
|
||||||
_, err = funcCall(uf, tengo.TrueValue)
|
_, err = funcCall(uf, xgo.TrueValue)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncARYE(t *testing.T) {
|
func TestFuncARYE(t *testing.T) {
|
||||||
|
@ -425,114 +425,114 @@ func TestFuncARYE(t *testing.T) {
|
||||||
})
|
})
|
||||||
ret, err := funcCall(uf)
|
ret, err := funcCall(uf)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.Bytes{Value: []byte("foo bar")}, ret)
|
require.Equal(t, &xgo.Bytes{Value: []byte("foo bar")}, ret)
|
||||||
uf = stdlib.FuncARYE(func() ([]byte, error) {
|
uf = stdlib.FuncARYE(func() ([]byte, error) {
|
||||||
return nil, errors.New("some error")
|
return nil, errors.New("some error")
|
||||||
})
|
})
|
||||||
ret, err = funcCall(uf)
|
ret, err = funcCall(uf)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t,
|
require.Equal(t,
|
||||||
&tengo.Error{Value: &tengo.String{Value: "some error"}}, ret)
|
&xgo.Error{Value: &xgo.String{Value: "some error"}}, ret)
|
||||||
_, err = funcCall(uf, tengo.TrueValue)
|
_, err = funcCall(uf, xgo.TrueValue)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncASRIE(t *testing.T) {
|
func TestFuncASRIE(t *testing.T) {
|
||||||
uf := stdlib.FuncASRIE(func(a string) (int, error) { return 5, nil })
|
uf := stdlib.FuncASRIE(func(a string) (int, error) { return 5, nil })
|
||||||
ret, err := funcCall(uf, &tengo.String{Value: "foo"})
|
ret, err := funcCall(uf, &xgo.String{Value: "foo"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.Int{Value: 5}, ret)
|
require.Equal(t, &xgo.Int{Value: 5}, ret)
|
||||||
uf = stdlib.FuncASRIE(func(a string) (int, error) {
|
uf = stdlib.FuncASRIE(func(a string) (int, error) {
|
||||||
return 0, errors.New("some error")
|
return 0, errors.New("some error")
|
||||||
})
|
})
|
||||||
ret, err = funcCall(uf, &tengo.String{Value: "foo"})
|
ret, err = funcCall(uf, &xgo.String{Value: "foo"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t,
|
require.Equal(t,
|
||||||
&tengo.Error{Value: &tengo.String{Value: "some error"}}, ret)
|
&xgo.Error{Value: &xgo.String{Value: "some error"}}, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncAYRIE(t *testing.T) {
|
func TestFuncAYRIE(t *testing.T) {
|
||||||
uf := stdlib.FuncAYRIE(func(a []byte) (int, error) { return 5, nil })
|
uf := stdlib.FuncAYRIE(func(a []byte) (int, error) { return 5, nil })
|
||||||
ret, err := funcCall(uf, &tengo.Bytes{Value: []byte("foo")})
|
ret, err := funcCall(uf, &xgo.Bytes{Value: []byte("foo")})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.Int{Value: 5}, ret)
|
require.Equal(t, &xgo.Int{Value: 5}, ret)
|
||||||
uf = stdlib.FuncAYRIE(func(a []byte) (int, error) {
|
uf = stdlib.FuncAYRIE(func(a []byte) (int, error) {
|
||||||
return 0, errors.New("some error")
|
return 0, errors.New("some error")
|
||||||
})
|
})
|
||||||
ret, err = funcCall(uf, &tengo.Bytes{Value: []byte("foo")})
|
ret, err = funcCall(uf, &xgo.Bytes{Value: []byte("foo")})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t,
|
require.Equal(t,
|
||||||
&tengo.Error{Value: &tengo.String{Value: "some error"}}, ret)
|
&xgo.Error{Value: &xgo.String{Value: "some error"}}, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncASSRI(t *testing.T) {
|
func TestFuncASSRI(t *testing.T) {
|
||||||
uf := stdlib.FuncASSRI(func(a, b string) int { return len(a) + len(b) })
|
uf := stdlib.FuncASSRI(func(a, b string) int { return len(a) + len(b) })
|
||||||
ret, err := funcCall(uf,
|
ret, err := funcCall(uf,
|
||||||
&tengo.String{Value: "foo"}, &tengo.String{Value: "bar"})
|
&xgo.String{Value: "foo"}, &xgo.String{Value: "bar"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.Int{Value: 6}, ret)
|
require.Equal(t, &xgo.Int{Value: 6}, ret)
|
||||||
_, err = funcCall(uf, &tengo.String{Value: "foo"})
|
_, err = funcCall(uf, &xgo.String{Value: "foo"})
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncASSRS(t *testing.T) {
|
func TestFuncASSRS(t *testing.T) {
|
||||||
uf := stdlib.FuncASSRS(func(a, b string) string { return a + b })
|
uf := stdlib.FuncASSRS(func(a, b string) string { return a + b })
|
||||||
ret, err := funcCall(uf,
|
ret, err := funcCall(uf,
|
||||||
&tengo.String{Value: "foo"}, &tengo.String{Value: "bar"})
|
&xgo.String{Value: "foo"}, &xgo.String{Value: "bar"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.String{Value: "foobar"}, ret)
|
require.Equal(t, &xgo.String{Value: "foobar"}, ret)
|
||||||
_, err = funcCall(uf, &tengo.String{Value: "foo"})
|
_, err = funcCall(uf, &xgo.String{Value: "foo"})
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncASSRB(t *testing.T) {
|
func TestFuncASSRB(t *testing.T) {
|
||||||
uf := stdlib.FuncASSRB(func(a, b string) bool { return len(a) > len(b) })
|
uf := stdlib.FuncASSRB(func(a, b string) bool { return len(a) > len(b) })
|
||||||
ret, err := funcCall(uf,
|
ret, err := funcCall(uf,
|
||||||
&tengo.String{Value: "123"}, &tengo.String{Value: "12"})
|
&xgo.String{Value: "123"}, &xgo.String{Value: "12"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tengo.TrueValue, ret)
|
require.Equal(t, xgo.TrueValue, ret)
|
||||||
_, err = funcCall(uf, &tengo.String{Value: "foo"})
|
_, err = funcCall(uf, &xgo.String{Value: "foo"})
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncAIRS(t *testing.T) {
|
func TestFuncAIRS(t *testing.T) {
|
||||||
uf := stdlib.FuncAIRS(func(a int) string { return strconv.Itoa(a) })
|
uf := stdlib.FuncAIRS(func(a int) string { return strconv.Itoa(a) })
|
||||||
ret, err := funcCall(uf, &tengo.Int{Value: 55})
|
ret, err := funcCall(uf, &xgo.Int{Value: 55})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.String{Value: "55"}, ret)
|
require.Equal(t, &xgo.String{Value: "55"}, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncAIRIs(t *testing.T) {
|
func TestFuncAIRIs(t *testing.T) {
|
||||||
uf := stdlib.FuncAIRIs(func(a int) []int { return []int{a, a} })
|
uf := stdlib.FuncAIRIs(func(a int) []int { return []int{a, a} })
|
||||||
ret, err := funcCall(uf, &tengo.Int{Value: 55})
|
ret, err := funcCall(uf, &xgo.Int{Value: 55})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, array(&tengo.Int{Value: 55}, &tengo.Int{Value: 55}), ret)
|
require.Equal(t, array(&xgo.Int{Value: 55}, &xgo.Int{Value: 55}), ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncAI64R(t *testing.T) {
|
func TestFuncAI64R(t *testing.T) {
|
||||||
uf := stdlib.FuncAIR(func(a int) {})
|
uf := stdlib.FuncAIR(func(a int) {})
|
||||||
ret, err := funcCall(uf, &tengo.Int{Value: 55})
|
ret, err := funcCall(uf, &xgo.Int{Value: 55})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, tengo.UndefinedValue, ret)
|
require.Equal(t, xgo.UndefinedValue, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncARI64(t *testing.T) {
|
func TestFuncARI64(t *testing.T) {
|
||||||
uf := stdlib.FuncARI64(func() int64 { return 55 })
|
uf := stdlib.FuncARI64(func() int64 { return 55 })
|
||||||
ret, err := funcCall(uf)
|
ret, err := funcCall(uf)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.Int{Value: 55}, ret)
|
require.Equal(t, &xgo.Int{Value: 55}, ret)
|
||||||
_, err = funcCall(uf, &tengo.Int{Value: 55})
|
_, err = funcCall(uf, &xgo.Int{Value: 55})
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncASsSRS(t *testing.T) {
|
func TestFuncASsSRS(t *testing.T) {
|
||||||
|
@ -540,31 +540,31 @@ func TestFuncASsSRS(t *testing.T) {
|
||||||
return strings.Join(a, b)
|
return strings.Join(a, b)
|
||||||
})
|
})
|
||||||
ret, err := funcCall(uf,
|
ret, err := funcCall(uf,
|
||||||
array(&tengo.String{Value: "abc"}, &tengo.String{Value: "def"}),
|
array(&xgo.String{Value: "abc"}, &xgo.String{Value: "def"}),
|
||||||
&tengo.String{Value: "-"})
|
&xgo.String{Value: "-"})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.String{Value: "abc-def"}, ret)
|
require.Equal(t, &xgo.String{Value: "abc-def"}, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFuncAI64RI64(t *testing.T) {
|
func TestFuncAI64RI64(t *testing.T) {
|
||||||
uf := stdlib.FuncAI64RI64(func(a int64) int64 { return a * 2 })
|
uf := stdlib.FuncAI64RI64(func(a int64) int64 { return a * 2 })
|
||||||
ret, err := funcCall(uf, &tengo.Int{Value: 55})
|
ret, err := funcCall(uf, &xgo.Int{Value: 55})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, &tengo.Int{Value: 110}, ret)
|
require.Equal(t, &xgo.Int{Value: 110}, ret)
|
||||||
_, err = funcCall(uf)
|
_, err = funcCall(uf)
|
||||||
require.Equal(t, tengo.ErrWrongNumArguments, err)
|
require.Equal(t, xgo.ErrWrongNumArguments, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func funcCall(
|
func funcCall(
|
||||||
fn tengo.CallableFunc,
|
fn xgo.CallableFunc,
|
||||||
args ...tengo.Object,
|
args ...xgo.Object,
|
||||||
) (tengo.Object, error) {
|
) (xgo.Object, error) {
|
||||||
userFunc := &tengo.UserFunction{Value: fn}
|
userFunc := &xgo.UserFunction{Value: fn}
|
||||||
return userFunc.Call(args...)
|
return userFunc.Call(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func array(elements ...tengo.Object) *tengo.Array {
|
func array(elements ...xgo.Object) *xgo.Array {
|
||||||
return &tengo.Array{Value: elements}
|
return &xgo.Array{Value: elements}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
var tengoModFileRE = regexp.MustCompile(`^srcmod_(\w+).tengo$`)
|
var xgoModFileRE = regexp.MustCompile(`^srcmod_(\w+).xgo$`)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
modules := make(map[string]string)
|
modules := make(map[string]string)
|
||||||
|
@ -21,7 +21,7 @@ func main() {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
m := tengoModFileRE.FindStringSubmatch(file.Name())
|
m := xgoModFileRE.FindStringSubmatch(file.Name())
|
||||||
if m != nil {
|
if m != nil {
|
||||||
modName := m[1]
|
modName := m[1]
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,10 @@ package stdlib
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var hexModule = map[string]tengo.Object{
|
var hexModule = map[string]xgo.Object{
|
||||||
"encode": &tengo.UserFunction{Value: FuncAYRS(hex.EncodeToString)},
|
"encode": &xgo.UserFunction{Value: FuncAYRS(hex.EncodeToString)},
|
||||||
"decode": &tengo.UserFunction{Value: FuncASRYE(hex.DecodeString)},
|
"decode": &xgo.UserFunction{Value: FuncASRYE(hex.DecodeString)},
|
||||||
}
|
}
|
||||||
|
|
136
stdlib/html/element.go
Normal file
136
stdlib/html/element.go
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
package html
|
||||||
|
|
||||||
|
import (
|
||||||
|
"surdeus.su/core/xgo/v2"
|
||||||
|
"strings"
|
||||||
|
"html"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
const RawTag = "raw"
|
||||||
|
|
||||||
|
// The type implements basic
|
||||||
|
// way to structrize HTML elements.
|
||||||
|
type Element struct {
|
||||||
|
xgo.ObjectImpl
|
||||||
|
Tag string
|
||||||
|
Attr map[string]string
|
||||||
|
Children []*Element
|
||||||
|
// The value makes sense only if
|
||||||
|
// the tag is the "raw"
|
||||||
|
Content string
|
||||||
|
Final bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (el *Element) TypeName() string {
|
||||||
|
return "*HTMLElement"
|
||||||
|
}
|
||||||
|
|
||||||
|
// The method renders the element to it's
|
||||||
|
// HTML representation.
|
||||||
|
func (el *Element) String() string {
|
||||||
|
if el.Tag == RawTag {
|
||||||
|
return html.EscapeString(el.Content)
|
||||||
|
}
|
||||||
|
|
||||||
|
var b strings.Builder
|
||||||
|
|
||||||
|
fmt.Fprintf(&b, "<%s", el.Tag)
|
||||||
|
for k, v := range el.Attr {
|
||||||
|
fmt.Fprintf(&b, " %s=%q", k, v)
|
||||||
|
}
|
||||||
|
fmt.Fprint(&b, ">")
|
||||||
|
|
||||||
|
if el.Final {
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, child := range el.Children {
|
||||||
|
if child == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fmt.Fprint(&b, child.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(&b, "</%s>", el.Tag)
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeElements(args ...xgo.Object) ([]*Element, error) {
|
||||||
|
s := []*Element{}
|
||||||
|
for _, arg := range args {
|
||||||
|
el, ok := arg.(*Element)
|
||||||
|
if !ok {
|
||||||
|
str, ok := xgo.ToString(arg)
|
||||||
|
if ok {
|
||||||
|
s = append(s, &Element{
|
||||||
|
Tag: RawTag,
|
||||||
|
Content: str,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
s = append(s, el)
|
||||||
|
}
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (el *Element) SetBody(
|
||||||
|
args ...xgo.Object,
|
||||||
|
) (xgo.Object, error) {
|
||||||
|
els, err := MakeElements(args...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
el.Children = els
|
||||||
|
return el, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (el *Element) Add(
|
||||||
|
args ...xgo.Object,
|
||||||
|
) (xgo.Object, error) {
|
||||||
|
s, err := MakeElements(args...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
el.Children = append(el.Children, s...)
|
||||||
|
return el, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (el *Element) SetFinal(
|
||||||
|
args ...xgo.Object,
|
||||||
|
) (xgo.Object, error) {
|
||||||
|
if len(args) > 0 {
|
||||||
|
return nil, xgo.ErrWrongNumArguments
|
||||||
|
}
|
||||||
|
el.Final = true
|
||||||
|
return el, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (el *Element) IndexGet(
|
||||||
|
index xgo.Object,
|
||||||
|
) (xgo.Object, error) {
|
||||||
|
arg, ok := xgo.ToString(index)
|
||||||
|
if !ok {
|
||||||
|
return nil, xgo.ErrInvalidIndexValueType
|
||||||
|
}
|
||||||
|
|
||||||
|
switch arg {
|
||||||
|
case "body":
|
||||||
|
return &xgo.UserFunction{
|
||||||
|
Name: "element.body",
|
||||||
|
Value: el.SetBody,
|
||||||
|
}, nil
|
||||||
|
case "final":
|
||||||
|
return &xgo.UserFunction{
|
||||||
|
Name: "element.final",
|
||||||
|
Value: el.SetFinal,
|
||||||
|
}, nil
|
||||||
|
case "add":
|
||||||
|
return &xgo.UserFunction{
|
||||||
|
Name: "element.add",
|
||||||
|
Value: el.Add,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
101
stdlib/html/html.go
Normal file
101
stdlib/html/html.go
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
package html
|
||||||
|
|
||||||
|
import "surdeus.su/core/xgo/v2"
|
||||||
|
|
||||||
|
var Module = map[string]xgo.Object{
|
||||||
|
"Renderer": &xgo.BuiltinFunction{
|
||||||
|
Name: "Renderer",
|
||||||
|
Value: func(args ...xgo.Object) (xgo.Object, error) {
|
||||||
|
ret := &Renderer{}
|
||||||
|
return ret, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
type Renderer struct {
|
||||||
|
xgo.ObjectImpl
|
||||||
|
}
|
||||||
|
|
||||||
|
func (html *Renderer) TypeName() string {
|
||||||
|
return "html.Renderer"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (html *Renderer) String() string {
|
||||||
|
return "html.Renderer(...)"
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
html.div({
|
||||||
|
id: "some-el-id",
|
||||||
|
value: "shit value"
|
||||||
|
}).body(
|
||||||
|
html.raw("cock "),
|
||||||
|
html.strong("something")
|
||||||
|
)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
func (html *Renderer) IndexGet(
|
||||||
|
index xgo.Object,
|
||||||
|
) (xgo.Object, error) {
|
||||||
|
str, ok := xgo.ToString(index)
|
||||||
|
if !ok {
|
||||||
|
return nil, xgo.ErrInvalidIndexValueType
|
||||||
|
}
|
||||||
|
|
||||||
|
fn := func(args ...xgo.Object) (xgo.Object, error) {
|
||||||
|
if len(args) > 1 {
|
||||||
|
return nil, xgo.ErrWrongNumArguments
|
||||||
|
}
|
||||||
|
var arg xgo.Object
|
||||||
|
if len(args) == 1 {
|
||||||
|
arg = args[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
if arg == nil {
|
||||||
|
return &Element{
|
||||||
|
Tag: str,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if can := arg.CanIterate(); !can {
|
||||||
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
|
Name: "first",
|
||||||
|
Expected: "iterable",
|
||||||
|
Found: arg.TypeName(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
attr := map[string]string{}
|
||||||
|
iter := arg.Iterate()
|
||||||
|
for iter.Next() {
|
||||||
|
key, val := iter.Key(), iter.Value()
|
||||||
|
skey, ok := xgo.ToString(key)
|
||||||
|
if !ok {
|
||||||
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
|
Name: "attribute(key)",
|
||||||
|
Expected: "stringer",
|
||||||
|
Found: key.TypeName(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sval, ok := xgo.ToString(val)
|
||||||
|
if !ok {
|
||||||
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
|
Name: "attribute(value)",
|
||||||
|
Expected: "stringer",
|
||||||
|
Found: val.TypeName(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
attr[skey] = sval
|
||||||
|
}
|
||||||
|
return &Element{
|
||||||
|
Tag: str,
|
||||||
|
Attr: attr,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &xgo.UserFunction{
|
||||||
|
Name: str,
|
||||||
|
Value: fn,
|
||||||
|
}, nil
|
||||||
|
}
|
2
stdlib/http/http.go
Normal file
2
stdlib/http/http.go
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
package http
|
||||||
|
|
70
stdlib/http/module.go
Normal file
70
stdlib/http/module.go
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
package http
|
||||||
|
|
||||||
|
import "surdeus.su/core/xgo/v2"
|
||||||
|
import "net/http"
|
||||||
|
import "bytes"
|
||||||
|
import tjson "surdeus.su/core/xgo/v2/stdlib/json"
|
||||||
|
|
||||||
|
var Module = map[string]xgo.Object{
|
||||||
|
"get": &xgo.BuiltinFunction{
|
||||||
|
Name: "get",
|
||||||
|
Value: func(
|
||||||
|
args ...xgo.Object,
|
||||||
|
) (xgo.Object, error) {
|
||||||
|
if len(args) != 1 {
|
||||||
|
return nil, xgo.ErrWrongNumArguments
|
||||||
|
}
|
||||||
|
url, ok := xgo.ToString(args[0])
|
||||||
|
if !ok {
|
||||||
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
|
Name: "first",
|
||||||
|
Expected: "string",
|
||||||
|
Found: args[0].TypeName(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resp, err := http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Response{
|
||||||
|
Response: resp,
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"post_json": &xgo.BuiltinFunction{
|
||||||
|
Name: "post",
|
||||||
|
Value: func(
|
||||||
|
args ...xgo.Object,
|
||||||
|
) (xgo.Object, error) {
|
||||||
|
if len(args) < 2 {
|
||||||
|
return nil, xgo.ErrWrongNumArguments
|
||||||
|
}
|
||||||
|
url, ok := xgo.ToString(args[0])
|
||||||
|
if !ok {
|
||||||
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
|
Name: "first",
|
||||||
|
Expected: "string",
|
||||||
|
Found: args[0].TypeName(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var body bytes.Buffer
|
||||||
|
ret, err := tjson.Encode(args[1])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body.Write(ret)
|
||||||
|
|
||||||
|
resp, err := http.Post(
|
||||||
|
url, "application/json",
|
||||||
|
&body,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Response{
|
||||||
|
Response: resp,
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
49
stdlib/http/request.go
Normal file
49
stdlib/http/request.go
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
package http
|
||||||
|
|
||||||
|
import (
|
||||||
|
"surdeus.su/core/xgo/v2"
|
||||||
|
"net/http"
|
||||||
|
"io"
|
||||||
|
//"log"
|
||||||
|
xurl "surdeus.su/core/xgo/v2/stdlib/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Request struct {
|
||||||
|
*http.Request
|
||||||
|
xgo.ObjectImpl
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Request) TypeName() string {
|
||||||
|
return "http.Request"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Request) String() string {
|
||||||
|
return "http.Request{...}"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Request) IndexGet(
|
||||||
|
index xgo.Object,
|
||||||
|
) (xgo.Object, error) {
|
||||||
|
key, ok := xgo.ToString(index)
|
||||||
|
if !ok {
|
||||||
|
return nil, xgo.ErrInvalidIndexValueType
|
||||||
|
}
|
||||||
|
|
||||||
|
switch key {
|
||||||
|
case "url":
|
||||||
|
return &xurl.URL{
|
||||||
|
URL: r.URL,
|
||||||
|
}, nil
|
||||||
|
case "body":
|
||||||
|
bts, err := io.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &xgo.Bytes{
|
||||||
|
Value: bts,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nothing found.
|
||||||
|
return nil, nil
|
||||||
|
}
|
49
stdlib/http/response.go
Normal file
49
stdlib/http/response.go
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
package http
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
import "surdeus.su/core/xgo/v2"
|
||||||
|
import "io"
|
||||||
|
import tjson "surdeus.su/core/xgo/v2/stdlib/json"
|
||||||
|
|
||||||
|
type Response struct {
|
||||||
|
*http.Response
|
||||||
|
xgo.ObjectImpl
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Response) TypeName() string {
|
||||||
|
return "http.Response"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Response) String() string {
|
||||||
|
return "http.Response{...}"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Response) IndexGet(
|
||||||
|
index xgo.Object,
|
||||||
|
) (xgo.Object, error) {
|
||||||
|
key, ok := xgo.ToString(index)
|
||||||
|
if !ok {
|
||||||
|
return nil, xgo.ErrInvalidIndexValueType
|
||||||
|
}
|
||||||
|
|
||||||
|
switch key {
|
||||||
|
case "body":
|
||||||
|
bts, err := io.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &xgo.Bytes{
|
||||||
|
Value: bts,
|
||||||
|
}, nil
|
||||||
|
case "body_json":
|
||||||
|
bts, err := io.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tjson.Decode(bts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nothing found.
|
||||||
|
return nil, nil
|
||||||
|
}
|
|
@ -4,53 +4,53 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
gojson "encoding/json"
|
gojson "encoding/json"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
"github.com/d5/tengo/v2/stdlib/json"
|
"surdeus.su/core/xgo/v2/stdlib/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
var jsonModule = map[string]tengo.Object{
|
var jsonModule = map[string]xgo.Object{
|
||||||
"decode": &tengo.UserFunction{
|
"decode": &xgo.UserFunction{
|
||||||
Name: "decode",
|
Name: "decode",
|
||||||
Value: jsonDecode,
|
Value: jsonDecode,
|
||||||
},
|
},
|
||||||
"encode": &tengo.UserFunction{
|
"encode": &xgo.UserFunction{
|
||||||
Name: "encode",
|
Name: "encode",
|
||||||
Value: jsonEncode,
|
Value: jsonEncode,
|
||||||
},
|
},
|
||||||
"indent": &tengo.UserFunction{
|
"indent": &xgo.UserFunction{
|
||||||
Name: "encode",
|
Name: "encode",
|
||||||
Value: jsonIndent,
|
Value: jsonIndent,
|
||||||
},
|
},
|
||||||
"html_escape": &tengo.UserFunction{
|
"html_escape": &xgo.UserFunction{
|
||||||
Name: "html_escape",
|
Name: "html_escape",
|
||||||
Value: jsonHTMLEscape,
|
Value: jsonHTMLEscape,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func jsonDecode(args ...tengo.Object) (ret tengo.Object, err error) {
|
func jsonDecode(args ...xgo.Object) (ret xgo.Object, err error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
switch o := args[0].(type) {
|
switch o := args[0].(type) {
|
||||||
case *tengo.Bytes:
|
case *xgo.Bytes:
|
||||||
v, err := json.Decode(o.Value)
|
v, err := json.Decode(o.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &tengo.Error{
|
return &xgo.Error{
|
||||||
Value: &tengo.String{Value: err.Error()},
|
Value: &xgo.String{Value: err.Error()},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
return v, nil
|
return v, nil
|
||||||
case *tengo.String:
|
case *xgo.String:
|
||||||
v, err := json.Decode([]byte(o.Value))
|
v, err := json.Decode([]byte(o.Value))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &tengo.Error{
|
return &xgo.Error{
|
||||||
Value: &tengo.String{Value: err.Error()},
|
Value: &xgo.String{Value: err.Error()},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
return v, nil
|
return v, nil
|
||||||
default:
|
default:
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "bytes/string",
|
Expected: "bytes/string",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -58,36 +58,36 @@ func jsonDecode(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func jsonEncode(args ...tengo.Object) (ret tengo.Object, err error) {
|
func jsonEncode(args ...xgo.Object) (ret xgo.Object, err error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := json.Encode(args[0])
|
b, err := json.Encode(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &tengo.Error{Value: &tengo.String{Value: err.Error()}}, nil
|
return &xgo.Error{Value: &xgo.String{Value: err.Error()}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &tengo.Bytes{Value: b}, nil
|
return &xgo.Bytes{Value: b}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func jsonIndent(args ...tengo.Object) (ret tengo.Object, err error) {
|
func jsonIndent(args ...xgo.Object) (ret xgo.Object, err error) {
|
||||||
if len(args) != 3 {
|
if len(args) != 3 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
prefix, ok := tengo.ToString(args[1])
|
prefix, ok := xgo.ToString(args[1])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "prefix",
|
Name: "prefix",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[1].TypeName(),
|
Found: args[1].TypeName(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
indent, ok := tengo.ToString(args[2])
|
indent, ok := xgo.ToString(args[2])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "indent",
|
Name: "indent",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[2].TypeName(),
|
Found: args[2].TypeName(),
|
||||||
|
@ -95,26 +95,26 @@ func jsonIndent(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch o := args[0].(type) {
|
switch o := args[0].(type) {
|
||||||
case *tengo.Bytes:
|
case *xgo.Bytes:
|
||||||
var dst bytes.Buffer
|
var dst bytes.Buffer
|
||||||
err := gojson.Indent(&dst, o.Value, prefix, indent)
|
err := gojson.Indent(&dst, o.Value, prefix, indent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &tengo.Error{
|
return &xgo.Error{
|
||||||
Value: &tengo.String{Value: err.Error()},
|
Value: &xgo.String{Value: err.Error()},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
return &tengo.Bytes{Value: dst.Bytes()}, nil
|
return &xgo.Bytes{Value: dst.Bytes()}, nil
|
||||||
case *tengo.String:
|
case *xgo.String:
|
||||||
var dst bytes.Buffer
|
var dst bytes.Buffer
|
||||||
err := gojson.Indent(&dst, []byte(o.Value), prefix, indent)
|
err := gojson.Indent(&dst, []byte(o.Value), prefix, indent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &tengo.Error{
|
return &xgo.Error{
|
||||||
Value: &tengo.String{Value: err.Error()},
|
Value: &xgo.String{Value: err.Error()},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
return &tengo.Bytes{Value: dst.Bytes()}, nil
|
return &xgo.Bytes{Value: dst.Bytes()}, nil
|
||||||
default:
|
default:
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "bytes/string",
|
Expected: "bytes/string",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -122,22 +122,22 @@ func jsonIndent(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func jsonHTMLEscape(args ...tengo.Object) (ret tengo.Object, err error) {
|
func jsonHTMLEscape(args ...xgo.Object) (ret xgo.Object, err error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
switch o := args[0].(type) {
|
switch o := args[0].(type) {
|
||||||
case *tengo.Bytes:
|
case *xgo.Bytes:
|
||||||
var dst bytes.Buffer
|
var dst bytes.Buffer
|
||||||
gojson.HTMLEscape(&dst, o.Value)
|
gojson.HTMLEscape(&dst, o.Value)
|
||||||
return &tengo.Bytes{Value: dst.Bytes()}, nil
|
return &xgo.Bytes{Value: dst.Bytes()}, nil
|
||||||
case *tengo.String:
|
case *xgo.String:
|
||||||
var dst bytes.Buffer
|
var dst bytes.Buffer
|
||||||
gojson.HTMLEscape(&dst, []byte(o.Value))
|
gojson.HTMLEscape(&dst, []byte(o.Value))
|
||||||
return &tengo.Bytes{Value: dst.Bytes()}, nil
|
return &xgo.Bytes{Value: dst.Bytes()}, nil
|
||||||
default:
|
default:
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "bytes/string",
|
Expected: "bytes/string",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
|
|
@ -12,11 +12,11 @@ import (
|
||||||
"unicode/utf16"
|
"unicode/utf16"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Decode parses the JSON-encoded data and returns the result object.
|
// Decode parses the JSON-encoded data and returns the result object.
|
||||||
func Decode(data []byte) (tengo.Object, error) {
|
func Decode(data []byte) (xgo.Object, error) {
|
||||||
var d decodeState
|
var d decodeState
|
||||||
err := checkValid(data, &d.scan)
|
err := checkValid(data, &d.scan)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -82,7 +82,7 @@ func (d *decodeState) scanWhile(op int) (isFloat bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *decodeState) value() (tengo.Object, error) {
|
func (d *decodeState) value() (xgo.Object, error) {
|
||||||
switch d.opcode {
|
switch d.opcode {
|
||||||
default:
|
default:
|
||||||
panic(phasePanicMsg)
|
panic(phasePanicMsg)
|
||||||
|
@ -105,8 +105,8 @@ func (d *decodeState) value() (tengo.Object, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *decodeState) array() (tengo.Object, error) {
|
func (d *decodeState) array() (xgo.Object, error) {
|
||||||
var arr []tengo.Object
|
var arr []xgo.Object
|
||||||
for {
|
for {
|
||||||
// Look ahead for ] - can only happen on first iteration.
|
// Look ahead for ] - can only happen on first iteration.
|
||||||
d.scanWhile(scanSkipSpace)
|
d.scanWhile(scanSkipSpace)
|
||||||
|
@ -130,11 +130,11 @@ func (d *decodeState) array() (tengo.Object, error) {
|
||||||
panic(phasePanicMsg)
|
panic(phasePanicMsg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &tengo.Array{Value: arr}, nil
|
return &xgo.Array{Value: arr}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *decodeState) object() (tengo.Object, error) {
|
func (d *decodeState) object() (xgo.Object, error) {
|
||||||
m := make(map[string]tengo.Object)
|
m := make(map[string]xgo.Object)
|
||||||
for {
|
for {
|
||||||
// Read opening " of string key or closing }.
|
// Read opening " of string key or closing }.
|
||||||
d.scanWhile(scanSkipSpace)
|
d.scanWhile(scanSkipSpace)
|
||||||
|
@ -183,10 +183,10 @@ func (d *decodeState) object() (tengo.Object, error) {
|
||||||
panic(phasePanicMsg)
|
panic(phasePanicMsg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &tengo.Map{Value: m}, nil
|
return &xgo.Map{Value: m}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *decodeState) literal() (tengo.Object, error) {
|
func (d *decodeState) literal() (xgo.Object, error) {
|
||||||
// All bytes inside literal return scanContinue op code.
|
// All bytes inside literal return scanContinue op code.
|
||||||
start := d.readIndex()
|
start := d.readIndex()
|
||||||
isFloat := d.scanWhile(scanContinue)
|
isFloat := d.scanWhile(scanContinue)
|
||||||
|
@ -195,20 +195,20 @@ func (d *decodeState) literal() (tengo.Object, error) {
|
||||||
|
|
||||||
switch c := item[0]; c {
|
switch c := item[0]; c {
|
||||||
case 'n': // null
|
case 'n': // null
|
||||||
return tengo.UndefinedValue, nil
|
return xgo.UndefinedValue, nil
|
||||||
|
|
||||||
case 't', 'f': // true, false
|
case 't', 'f': // true, false
|
||||||
if c == 't' {
|
if c == 't' {
|
||||||
return tengo.TrueValue, nil
|
return xgo.TrueValue, nil
|
||||||
}
|
}
|
||||||
return tengo.FalseValue, nil
|
return xgo.FalseValue, nil
|
||||||
|
|
||||||
case '"': // string
|
case '"': // string
|
||||||
s, ok := unquote(item)
|
s, ok := unquote(item)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic(phasePanicMsg)
|
panic(phasePanicMsg)
|
||||||
}
|
}
|
||||||
return &tengo.String{Value: s}, nil
|
return &xgo.String{Value: s}, nil
|
||||||
|
|
||||||
default: // number
|
default: // number
|
||||||
if c != '-' && (c < '0' || c > '9') {
|
if c != '-' && (c < '0' || c > '9') {
|
||||||
|
@ -216,10 +216,10 @@ func (d *decodeState) literal() (tengo.Object, error) {
|
||||||
}
|
}
|
||||||
if isFloat {
|
if isFloat {
|
||||||
n, _ := strconv.ParseFloat(string(item), 10)
|
n, _ := strconv.ParseFloat(string(item), 10)
|
||||||
return &tengo.Float{Value: n}, nil
|
return &xgo.Float{Value: n}, nil
|
||||||
}
|
}
|
||||||
n, _ := strconv.ParseInt(string(item), 10, 64)
|
n, _ := strconv.ParseInt(string(item), 10, 64)
|
||||||
return &tengo.Int{Value: n}, nil
|
return &xgo.Int{Value: n}, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// safeSet holds the value true if the ASCII character with the given array
|
// safeSet holds the value true if the ASCII character with the given array
|
||||||
|
@ -125,11 +125,11 @@ var safeSet = [utf8.RuneSelf]bool{
|
||||||
var hex = "0123456789abcdef"
|
var hex = "0123456789abcdef"
|
||||||
|
|
||||||
// Encode returns the JSON encoding of the object.
|
// Encode returns the JSON encoding of the object.
|
||||||
func Encode(o tengo.Object) ([]byte, error) {
|
func Encode(o xgo.Object) ([]byte, error) {
|
||||||
var b []byte
|
var b []byte
|
||||||
|
|
||||||
switch o := o.(type) {
|
switch o := o.(type) {
|
||||||
case *tengo.Array:
|
case *xgo.Array:
|
||||||
b = append(b, '[')
|
b = append(b, '[')
|
||||||
len1 := len(o.Value) - 1
|
len1 := len(o.Value) - 1
|
||||||
for idx, elem := range o.Value {
|
for idx, elem := range o.Value {
|
||||||
|
@ -143,7 +143,7 @@ func Encode(o tengo.Object) ([]byte, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b = append(b, ']')
|
b = append(b, ']')
|
||||||
case *tengo.ImmutableArray:
|
case *xgo.ImmutableArray:
|
||||||
b = append(b, '[')
|
b = append(b, '[')
|
||||||
len1 := len(o.Value) - 1
|
len1 := len(o.Value) - 1
|
||||||
for idx, elem := range o.Value {
|
for idx, elem := range o.Value {
|
||||||
|
@ -157,7 +157,7 @@ func Encode(o tengo.Object) ([]byte, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b = append(b, ']')
|
b = append(b, ']')
|
||||||
case *tengo.Map:
|
case *xgo.Map:
|
||||||
b = append(b, '{')
|
b = append(b, '{')
|
||||||
len1 := len(o.Value) - 1
|
len1 := len(o.Value) - 1
|
||||||
idx := 0
|
idx := 0
|
||||||
|
@ -175,7 +175,7 @@ func Encode(o tengo.Object) ([]byte, error) {
|
||||||
idx++
|
idx++
|
||||||
}
|
}
|
||||||
b = append(b, '}')
|
b = append(b, '}')
|
||||||
case *tengo.ImmutableMap:
|
case *xgo.ImmutableMap:
|
||||||
b = append(b, '{')
|
b = append(b, '{')
|
||||||
len1 := len(o.Value) - 1
|
len1 := len(o.Value) - 1
|
||||||
idx := 0
|
idx := 0
|
||||||
|
@ -193,22 +193,22 @@ func Encode(o tengo.Object) ([]byte, error) {
|
||||||
idx++
|
idx++
|
||||||
}
|
}
|
||||||
b = append(b, '}')
|
b = append(b, '}')
|
||||||
case *tengo.Bool:
|
case *xgo.Bool:
|
||||||
if o.IsFalsy() {
|
if o.IsFalsy() {
|
||||||
b = strconv.AppendBool(b, false)
|
b = strconv.AppendBool(b, false)
|
||||||
} else {
|
} else {
|
||||||
b = strconv.AppendBool(b, true)
|
b = strconv.AppendBool(b, true)
|
||||||
}
|
}
|
||||||
case *tengo.Bytes:
|
case *xgo.Bytes:
|
||||||
b = append(b, '"')
|
b = append(b, '"')
|
||||||
encodedLen := base64.StdEncoding.EncodedLen(len(o.Value))
|
encodedLen := base64.StdEncoding.EncodedLen(len(o.Value))
|
||||||
dst := make([]byte, encodedLen)
|
dst := make([]byte, encodedLen)
|
||||||
base64.StdEncoding.Encode(dst, o.Value)
|
base64.StdEncoding.Encode(dst, o.Value)
|
||||||
b = append(b, dst...)
|
b = append(b, dst...)
|
||||||
b = append(b, '"')
|
b = append(b, '"')
|
||||||
case *tengo.Char:
|
case *xgo.Char:
|
||||||
b = strconv.AppendInt(b, int64(o.Value), 10)
|
b = strconv.AppendInt(b, int64(o.Value), 10)
|
||||||
case *tengo.Float:
|
case *xgo.Float:
|
||||||
var y []byte
|
var y []byte
|
||||||
|
|
||||||
f := o.Value
|
f := o.Value
|
||||||
|
@ -236,19 +236,19 @@ func Encode(o tengo.Object) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
b = append(b, y...)
|
b = append(b, y...)
|
||||||
case *tengo.Int:
|
case *xgo.Int:
|
||||||
b = strconv.AppendInt(b, o.Value, 10)
|
b = strconv.AppendInt(b, o.Value, 10)
|
||||||
case *tengo.String:
|
case *xgo.String:
|
||||||
// string encoding bug is fixed with newly introduced function
|
// string encoding bug is fixed with newly introduced function
|
||||||
// encodeString(). See: https://github.com/d5/tengo/issues/268
|
// encodeString(). See: https://github.com/d5/xgo/issues/268
|
||||||
b = encodeString(b, o.Value)
|
b = encodeString(b, o.Value)
|
||||||
case *tengo.Time:
|
case *xgo.Time:
|
||||||
y, err := o.Value.MarshalJSON()
|
y, err := o.Value.MarshalJSON()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
b = append(b, y...)
|
b = append(b, y...)
|
||||||
case *tengo.Undefined:
|
case *xgo.Undefined:
|
||||||
b = append(b, "null"...)
|
b = append(b, "null"...)
|
||||||
default:
|
default:
|
||||||
// unknown type: ignore
|
// unknown type: ignore
|
||||||
|
|
|
@ -4,9 +4,9 @@ import (
|
||||||
gojson "encoding/json"
|
gojson "encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
"github.com/d5/tengo/v2/require"
|
"surdeus.su/core/xgo/v2/require"
|
||||||
"github.com/d5/tengo/v2/stdlib/json"
|
"surdeus.su/core/xgo/v2/stdlib/json"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ARR = []interface{}
|
type ARR = []interface{}
|
||||||
|
@ -31,7 +31,7 @@ func TestJSON(t *testing.T) {
|
||||||
testJSONEncodeDecode(t, "foo")
|
testJSONEncodeDecode(t, "foo")
|
||||||
testJSONEncodeDecode(t, "foo bar")
|
testJSONEncodeDecode(t, "foo bar")
|
||||||
testJSONEncodeDecode(t, "foo \"bar\"")
|
testJSONEncodeDecode(t, "foo \"bar\"")
|
||||||
// See: https://github.com/d5/tengo/issues/268
|
// See: https://github.com/d5/xgo/issues/268
|
||||||
testJSONEncodeDecode(t, "1\u001C04")
|
testJSONEncodeDecode(t, "1\u001C04")
|
||||||
testJSONEncodeDecode(t, "çığöşü")
|
testJSONEncodeDecode(t, "çığöşü")
|
||||||
testJSONEncodeDecode(t, "ç1\u001C04IĞÖŞÜ")
|
testJSONEncodeDecode(t, "ç1\u001C04IĞÖŞÜ")
|
||||||
|
@ -92,7 +92,7 @@ func testDecodeError(t *testing.T, input string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testJSONEncodeDecode(t *testing.T, v interface{}) {
|
func testJSONEncodeDecode(t *testing.T, v interface{}) {
|
||||||
o, err := tengo.FromInterface(v)
|
o, err := xgo.FromInterface(v)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
b, err := json.Encode(o)
|
b, err := json.Encode(o)
|
||||||
|
@ -104,7 +104,7 @@ func testJSONEncodeDecode(t *testing.T, v interface{}) {
|
||||||
vj, err := gojson.Marshal(v)
|
vj, err := gojson.Marshal(v)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
aj, err := gojson.Marshal(tengo.ToInterface(a))
|
aj, err := gojson.Marshal(xgo.ToInterface(a))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Equal(t, vj, aj)
|
require.Equal(t, vj, aj)
|
||||||
|
|
76
stdlib/log/main.go
Normal file
76
stdlib/log/main.go
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
package log
|
||||||
|
|
||||||
|
import "surdeus.su/core/xgo/v2"
|
||||||
|
import "log"
|
||||||
|
|
||||||
|
var Module = map[string]xgo.Object{
|
||||||
|
"printf": &xgo.BuiltinFunction{
|
||||||
|
Name: "printf",
|
||||||
|
Value: func(
|
||||||
|
args ...xgo.Object,
|
||||||
|
) (xgo.Object, error) {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return nil, xgo.ErrWrongNumArguments
|
||||||
|
}
|
||||||
|
|
||||||
|
formatObject := args[0]
|
||||||
|
format, hasFormat := xgo.ToString(
|
||||||
|
formatObject,
|
||||||
|
)
|
||||||
|
if !hasFormat {
|
||||||
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
|
Name: "first",
|
||||||
|
Expected: "string",
|
||||||
|
Found: formatObject.TypeName(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*v := make([]any, len(args[1:]))
|
||||||
|
for i, o := range args[1:] {
|
||||||
|
v[i] = xgo.ToInterface(o)
|
||||||
|
}*/
|
||||||
|
|
||||||
|
str, err := xgo.Format(format, args...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
log.Print(str)
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"print": &xgo.BuiltinFunction{
|
||||||
|
Name: "print",
|
||||||
|
Value: func(
|
||||||
|
args ...xgo.Object,
|
||||||
|
) (xgo.Object, error) {
|
||||||
|
v := make([]any, len(args))
|
||||||
|
for i, o := range args {
|
||||||
|
var ok bool
|
||||||
|
v[i], ok = xgo.ToString(o)
|
||||||
|
if !ok {
|
||||||
|
v[i] = xgo.Undefined{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Print(v...)
|
||||||
|
return nil, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"println": &xgo.BuiltinFunction{
|
||||||
|
Name: "println",
|
||||||
|
Value: func(
|
||||||
|
args ...xgo.Object,
|
||||||
|
) (xgo.Object, error) {
|
||||||
|
v := make([]any, len(args))
|
||||||
|
for i, o := range args {
|
||||||
|
var ok bool
|
||||||
|
v[i], ok = xgo.ToString(o)
|
||||||
|
if !ok {
|
||||||
|
v[i] = xgo.Undefined{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Println(v...)
|
||||||
|
return nil, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
160
stdlib/math.go
160
stdlib/math.go
|
@ -3,244 +3,244 @@ package stdlib
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var mathModule = map[string]tengo.Object{
|
var mathModule = map[string]xgo.Object{
|
||||||
"e": &tengo.Float{Value: math.E},
|
"e": &xgo.Float{Value: math.E},
|
||||||
"pi": &tengo.Float{Value: math.Pi},
|
"pi": &xgo.Float{Value: math.Pi},
|
||||||
"phi": &tengo.Float{Value: math.Phi},
|
"phi": &xgo.Float{Value: math.Phi},
|
||||||
"sqrt2": &tengo.Float{Value: math.Sqrt2},
|
"sqrt2": &xgo.Float{Value: math.Sqrt2},
|
||||||
"sqrtE": &tengo.Float{Value: math.SqrtE},
|
"sqrtE": &xgo.Float{Value: math.SqrtE},
|
||||||
"sqrtPi": &tengo.Float{Value: math.SqrtPi},
|
"sqrtPi": &xgo.Float{Value: math.SqrtPi},
|
||||||
"sqrtPhi": &tengo.Float{Value: math.SqrtPhi},
|
"sqrtPhi": &xgo.Float{Value: math.SqrtPhi},
|
||||||
"ln2": &tengo.Float{Value: math.Ln2},
|
"ln2": &xgo.Float{Value: math.Ln2},
|
||||||
"log2E": &tengo.Float{Value: math.Log2E},
|
"log2E": &xgo.Float{Value: math.Log2E},
|
||||||
"ln10": &tengo.Float{Value: math.Ln10},
|
"ln10": &xgo.Float{Value: math.Ln10},
|
||||||
"log10E": &tengo.Float{Value: math.Log10E},
|
"log10E": &xgo.Float{Value: math.Log10E},
|
||||||
"maxFloat32": &tengo.Float{Value: math.MaxFloat32},
|
"maxFloat32": &xgo.Float{Value: math.MaxFloat32},
|
||||||
"smallestNonzeroFloat32": &tengo.Float{Value: math.SmallestNonzeroFloat32},
|
"smallestNonzeroFloat32": &xgo.Float{Value: math.SmallestNonzeroFloat32},
|
||||||
"maxFloat64": &tengo.Float{Value: math.MaxFloat64},
|
"maxFloat64": &xgo.Float{Value: math.MaxFloat64},
|
||||||
"smallestNonzeroFloat64": &tengo.Float{Value: math.SmallestNonzeroFloat64},
|
"smallestNonzeroFloat64": &xgo.Float{Value: math.SmallestNonzeroFloat64},
|
||||||
"maxInt": &tengo.Int{Value: math.MaxInt},
|
"maxInt": &xgo.Int{Value: math.MaxInt},
|
||||||
"minInt": &tengo.Int{Value: math.MinInt},
|
"minInt": &xgo.Int{Value: math.MinInt},
|
||||||
"maxInt8": &tengo.Int{Value: math.MaxInt8},
|
"maxInt8": &xgo.Int{Value: math.MaxInt8},
|
||||||
"minInt8": &tengo.Int{Value: math.MinInt8},
|
"minInt8": &xgo.Int{Value: math.MinInt8},
|
||||||
"maxInt16": &tengo.Int{Value: math.MaxInt16},
|
"maxInt16": &xgo.Int{Value: math.MaxInt16},
|
||||||
"minInt16": &tengo.Int{Value: math.MinInt16},
|
"minInt16": &xgo.Int{Value: math.MinInt16},
|
||||||
"maxInt32": &tengo.Int{Value: math.MaxInt32},
|
"maxInt32": &xgo.Int{Value: math.MaxInt32},
|
||||||
"minInt32": &tengo.Int{Value: math.MinInt32},
|
"minInt32": &xgo.Int{Value: math.MinInt32},
|
||||||
"maxInt64": &tengo.Int{Value: math.MaxInt64},
|
"maxInt64": &xgo.Int{Value: math.MaxInt64},
|
||||||
"minInt64": &tengo.Int{Value: math.MinInt64},
|
"minInt64": &xgo.Int{Value: math.MinInt64},
|
||||||
"abs": &tengo.UserFunction{
|
"abs": &xgo.UserFunction{
|
||||||
Name: "abs",
|
Name: "abs",
|
||||||
Value: FuncAFRF(math.Abs),
|
Value: FuncAFRF(math.Abs),
|
||||||
},
|
},
|
||||||
"acos": &tengo.UserFunction{
|
"acos": &xgo.UserFunction{
|
||||||
Name: "acos",
|
Name: "acos",
|
||||||
Value: FuncAFRF(math.Acos),
|
Value: FuncAFRF(math.Acos),
|
||||||
},
|
},
|
||||||
"acosh": &tengo.UserFunction{
|
"acosh": &xgo.UserFunction{
|
||||||
Name: "acosh",
|
Name: "acosh",
|
||||||
Value: FuncAFRF(math.Acosh),
|
Value: FuncAFRF(math.Acosh),
|
||||||
},
|
},
|
||||||
"asin": &tengo.UserFunction{
|
"asin": &xgo.UserFunction{
|
||||||
Name: "asin",
|
Name: "asin",
|
||||||
Value: FuncAFRF(math.Asin),
|
Value: FuncAFRF(math.Asin),
|
||||||
},
|
},
|
||||||
"asinh": &tengo.UserFunction{
|
"asinh": &xgo.UserFunction{
|
||||||
Name: "asinh",
|
Name: "asinh",
|
||||||
Value: FuncAFRF(math.Asinh),
|
Value: FuncAFRF(math.Asinh),
|
||||||
},
|
},
|
||||||
"atan": &tengo.UserFunction{
|
"atan": &xgo.UserFunction{
|
||||||
Name: "atan",
|
Name: "atan",
|
||||||
Value: FuncAFRF(math.Atan),
|
Value: FuncAFRF(math.Atan),
|
||||||
},
|
},
|
||||||
"atan2": &tengo.UserFunction{
|
"atan2": &xgo.UserFunction{
|
||||||
Name: "atan2",
|
Name: "atan2",
|
||||||
Value: FuncAFFRF(math.Atan2),
|
Value: FuncAFFRF(math.Atan2),
|
||||||
},
|
},
|
||||||
"atanh": &tengo.UserFunction{
|
"atanh": &xgo.UserFunction{
|
||||||
Name: "atanh",
|
Name: "atanh",
|
||||||
Value: FuncAFRF(math.Atanh),
|
Value: FuncAFRF(math.Atanh),
|
||||||
},
|
},
|
||||||
"cbrt": &tengo.UserFunction{
|
"cbrt": &xgo.UserFunction{
|
||||||
Name: "cbrt",
|
Name: "cbrt",
|
||||||
Value: FuncAFRF(math.Cbrt),
|
Value: FuncAFRF(math.Cbrt),
|
||||||
},
|
},
|
||||||
"ceil": &tengo.UserFunction{
|
"ceil": &xgo.UserFunction{
|
||||||
Name: "ceil",
|
Name: "ceil",
|
||||||
Value: FuncAFRF(math.Ceil),
|
Value: FuncAFRF(math.Ceil),
|
||||||
},
|
},
|
||||||
"copysign": &tengo.UserFunction{
|
"copysign": &xgo.UserFunction{
|
||||||
Name: "copysign",
|
Name: "copysign",
|
||||||
Value: FuncAFFRF(math.Copysign),
|
Value: FuncAFFRF(math.Copysign),
|
||||||
},
|
},
|
||||||
"cos": &tengo.UserFunction{
|
"cos": &xgo.UserFunction{
|
||||||
Name: "cos",
|
Name: "cos",
|
||||||
Value: FuncAFRF(math.Cos),
|
Value: FuncAFRF(math.Cos),
|
||||||
},
|
},
|
||||||
"cosh": &tengo.UserFunction{
|
"cosh": &xgo.UserFunction{
|
||||||
Name: "cosh",
|
Name: "cosh",
|
||||||
Value: FuncAFRF(math.Cosh),
|
Value: FuncAFRF(math.Cosh),
|
||||||
},
|
},
|
||||||
"dim": &tengo.UserFunction{
|
"dim": &xgo.UserFunction{
|
||||||
Name: "dim",
|
Name: "dim",
|
||||||
Value: FuncAFFRF(math.Dim),
|
Value: FuncAFFRF(math.Dim),
|
||||||
},
|
},
|
||||||
"erf": &tengo.UserFunction{
|
"erf": &xgo.UserFunction{
|
||||||
Name: "erf",
|
Name: "erf",
|
||||||
Value: FuncAFRF(math.Erf),
|
Value: FuncAFRF(math.Erf),
|
||||||
},
|
},
|
||||||
"erfc": &tengo.UserFunction{
|
"erfc": &xgo.UserFunction{
|
||||||
Name: "erfc",
|
Name: "erfc",
|
||||||
Value: FuncAFRF(math.Erfc),
|
Value: FuncAFRF(math.Erfc),
|
||||||
},
|
},
|
||||||
"exp": &tengo.UserFunction{
|
"exp": &xgo.UserFunction{
|
||||||
Name: "exp",
|
Name: "exp",
|
||||||
Value: FuncAFRF(math.Exp),
|
Value: FuncAFRF(math.Exp),
|
||||||
},
|
},
|
||||||
"exp2": &tengo.UserFunction{
|
"exp2": &xgo.UserFunction{
|
||||||
Name: "exp2",
|
Name: "exp2",
|
||||||
Value: FuncAFRF(math.Exp2),
|
Value: FuncAFRF(math.Exp2),
|
||||||
},
|
},
|
||||||
"expm1": &tengo.UserFunction{
|
"expm1": &xgo.UserFunction{
|
||||||
Name: "expm1",
|
Name: "expm1",
|
||||||
Value: FuncAFRF(math.Expm1),
|
Value: FuncAFRF(math.Expm1),
|
||||||
},
|
},
|
||||||
"floor": &tengo.UserFunction{
|
"floor": &xgo.UserFunction{
|
||||||
Name: "floor",
|
Name: "floor",
|
||||||
Value: FuncAFRF(math.Floor),
|
Value: FuncAFRF(math.Floor),
|
||||||
},
|
},
|
||||||
"gamma": &tengo.UserFunction{
|
"gamma": &xgo.UserFunction{
|
||||||
Name: "gamma",
|
Name: "gamma",
|
||||||
Value: FuncAFRF(math.Gamma),
|
Value: FuncAFRF(math.Gamma),
|
||||||
},
|
},
|
||||||
"hypot": &tengo.UserFunction{
|
"hypot": &xgo.UserFunction{
|
||||||
Name: "hypot",
|
Name: "hypot",
|
||||||
Value: FuncAFFRF(math.Hypot),
|
Value: FuncAFFRF(math.Hypot),
|
||||||
},
|
},
|
||||||
"ilogb": &tengo.UserFunction{
|
"ilogb": &xgo.UserFunction{
|
||||||
Name: "ilogb",
|
Name: "ilogb",
|
||||||
Value: FuncAFRI(math.Ilogb),
|
Value: FuncAFRI(math.Ilogb),
|
||||||
},
|
},
|
||||||
"inf": &tengo.UserFunction{
|
"inf": &xgo.UserFunction{
|
||||||
Name: "inf",
|
Name: "inf",
|
||||||
Value: FuncAIRF(math.Inf),
|
Value: FuncAIRF(math.Inf),
|
||||||
},
|
},
|
||||||
"is_inf": &tengo.UserFunction{
|
"is_inf": &xgo.UserFunction{
|
||||||
Name: "is_inf",
|
Name: "is_inf",
|
||||||
Value: FuncAFIRB(math.IsInf),
|
Value: FuncAFIRB(math.IsInf),
|
||||||
},
|
},
|
||||||
"is_nan": &tengo.UserFunction{
|
"is_nan": &xgo.UserFunction{
|
||||||
Name: "is_nan",
|
Name: "is_nan",
|
||||||
Value: FuncAFRB(math.IsNaN),
|
Value: FuncAFRB(math.IsNaN),
|
||||||
},
|
},
|
||||||
"j0": &tengo.UserFunction{
|
"j0": &xgo.UserFunction{
|
||||||
Name: "j0",
|
Name: "j0",
|
||||||
Value: FuncAFRF(math.J0),
|
Value: FuncAFRF(math.J0),
|
||||||
},
|
},
|
||||||
"j1": &tengo.UserFunction{
|
"j1": &xgo.UserFunction{
|
||||||
Name: "j1",
|
Name: "j1",
|
||||||
Value: FuncAFRF(math.J1),
|
Value: FuncAFRF(math.J1),
|
||||||
},
|
},
|
||||||
"jn": &tengo.UserFunction{
|
"jn": &xgo.UserFunction{
|
||||||
Name: "jn",
|
Name: "jn",
|
||||||
Value: FuncAIFRF(math.Jn),
|
Value: FuncAIFRF(math.Jn),
|
||||||
},
|
},
|
||||||
"ldexp": &tengo.UserFunction{
|
"ldexp": &xgo.UserFunction{
|
||||||
Name: "ldexp",
|
Name: "ldexp",
|
||||||
Value: FuncAFIRF(math.Ldexp),
|
Value: FuncAFIRF(math.Ldexp),
|
||||||
},
|
},
|
||||||
"log": &tengo.UserFunction{
|
"log": &xgo.UserFunction{
|
||||||
Name: "log",
|
Name: "log",
|
||||||
Value: FuncAFRF(math.Log),
|
Value: FuncAFRF(math.Log),
|
||||||
},
|
},
|
||||||
"log10": &tengo.UserFunction{
|
"log10": &xgo.UserFunction{
|
||||||
Name: "log10",
|
Name: "log10",
|
||||||
Value: FuncAFRF(math.Log10),
|
Value: FuncAFRF(math.Log10),
|
||||||
},
|
},
|
||||||
"log1p": &tengo.UserFunction{
|
"log1p": &xgo.UserFunction{
|
||||||
Name: "log1p",
|
Name: "log1p",
|
||||||
Value: FuncAFRF(math.Log1p),
|
Value: FuncAFRF(math.Log1p),
|
||||||
},
|
},
|
||||||
"log2": &tengo.UserFunction{
|
"log2": &xgo.UserFunction{
|
||||||
Name: "log2",
|
Name: "log2",
|
||||||
Value: FuncAFRF(math.Log2),
|
Value: FuncAFRF(math.Log2),
|
||||||
},
|
},
|
||||||
"logb": &tengo.UserFunction{
|
"logb": &xgo.UserFunction{
|
||||||
Name: "logb",
|
Name: "logb",
|
||||||
Value: FuncAFRF(math.Logb),
|
Value: FuncAFRF(math.Logb),
|
||||||
},
|
},
|
||||||
"max": &tengo.UserFunction{
|
"max": &xgo.UserFunction{
|
||||||
Name: "max",
|
Name: "max",
|
||||||
Value: FuncAFFRF(math.Max),
|
Value: FuncAFFRF(math.Max),
|
||||||
},
|
},
|
||||||
"min": &tengo.UserFunction{
|
"min": &xgo.UserFunction{
|
||||||
Name: "min",
|
Name: "min",
|
||||||
Value: FuncAFFRF(math.Min),
|
Value: FuncAFFRF(math.Min),
|
||||||
},
|
},
|
||||||
"mod": &tengo.UserFunction{
|
"mod": &xgo.UserFunction{
|
||||||
Name: "mod",
|
Name: "mod",
|
||||||
Value: FuncAFFRF(math.Mod),
|
Value: FuncAFFRF(math.Mod),
|
||||||
},
|
},
|
||||||
"nan": &tengo.UserFunction{
|
"nan": &xgo.UserFunction{
|
||||||
Name: "nan",
|
Name: "nan",
|
||||||
Value: FuncARF(math.NaN),
|
Value: FuncARF(math.NaN),
|
||||||
},
|
},
|
||||||
"nextafter": &tengo.UserFunction{
|
"nextafter": &xgo.UserFunction{
|
||||||
Name: "nextafter",
|
Name: "nextafter",
|
||||||
Value: FuncAFFRF(math.Nextafter),
|
Value: FuncAFFRF(math.Nextafter),
|
||||||
},
|
},
|
||||||
"pow": &tengo.UserFunction{
|
"pow": &xgo.UserFunction{
|
||||||
Name: "pow",
|
Name: "pow",
|
||||||
Value: FuncAFFRF(math.Pow),
|
Value: FuncAFFRF(math.Pow),
|
||||||
},
|
},
|
||||||
"pow10": &tengo.UserFunction{
|
"pow10": &xgo.UserFunction{
|
||||||
Name: "pow10",
|
Name: "pow10",
|
||||||
Value: FuncAIRF(math.Pow10),
|
Value: FuncAIRF(math.Pow10),
|
||||||
},
|
},
|
||||||
"remainder": &tengo.UserFunction{
|
"remainder": &xgo.UserFunction{
|
||||||
Name: "remainder",
|
Name: "remainder",
|
||||||
Value: FuncAFFRF(math.Remainder),
|
Value: FuncAFFRF(math.Remainder),
|
||||||
},
|
},
|
||||||
"signbit": &tengo.UserFunction{
|
"signbit": &xgo.UserFunction{
|
||||||
Name: "signbit",
|
Name: "signbit",
|
||||||
Value: FuncAFRB(math.Signbit),
|
Value: FuncAFRB(math.Signbit),
|
||||||
},
|
},
|
||||||
"sin": &tengo.UserFunction{
|
"sin": &xgo.UserFunction{
|
||||||
Name: "sin",
|
Name: "sin",
|
||||||
Value: FuncAFRF(math.Sin),
|
Value: FuncAFRF(math.Sin),
|
||||||
},
|
},
|
||||||
"sinh": &tengo.UserFunction{
|
"sinh": &xgo.UserFunction{
|
||||||
Name: "sinh",
|
Name: "sinh",
|
||||||
Value: FuncAFRF(math.Sinh),
|
Value: FuncAFRF(math.Sinh),
|
||||||
},
|
},
|
||||||
"sqrt": &tengo.UserFunction{
|
"sqrt": &xgo.UserFunction{
|
||||||
Name: "sqrt",
|
Name: "sqrt",
|
||||||
Value: FuncAFRF(math.Sqrt),
|
Value: FuncAFRF(math.Sqrt),
|
||||||
},
|
},
|
||||||
"tan": &tengo.UserFunction{
|
"tan": &xgo.UserFunction{
|
||||||
Name: "tan",
|
Name: "tan",
|
||||||
Value: FuncAFRF(math.Tan),
|
Value: FuncAFRF(math.Tan),
|
||||||
},
|
},
|
||||||
"tanh": &tengo.UserFunction{
|
"tanh": &xgo.UserFunction{
|
||||||
Name: "tanh",
|
Name: "tanh",
|
||||||
Value: FuncAFRF(math.Tanh),
|
Value: FuncAFRF(math.Tanh),
|
||||||
},
|
},
|
||||||
"trunc": &tengo.UserFunction{
|
"trunc": &xgo.UserFunction{
|
||||||
Name: "trunc",
|
Name: "trunc",
|
||||||
Value: FuncAFRF(math.Trunc),
|
Value: FuncAFRF(math.Trunc),
|
||||||
},
|
},
|
||||||
"y0": &tengo.UserFunction{
|
"y0": &xgo.UserFunction{
|
||||||
Name: "y0",
|
Name: "y0",
|
||||||
Value: FuncAFRF(math.Y0),
|
Value: FuncAFRF(math.Y0),
|
||||||
},
|
},
|
||||||
"y1": &tengo.UserFunction{
|
"y1": &xgo.UserFunction{
|
||||||
Name: "y1",
|
Name: "y1",
|
||||||
Value: FuncAFRF(math.Y1),
|
Value: FuncAFRF(math.Y1),
|
||||||
},
|
},
|
||||||
"yn": &tengo.UserFunction{
|
"yn": &xgo.UserFunction{
|
||||||
Name: "yn",
|
Name: "yn",
|
||||||
Value: FuncAIFRF(math.Yn),
|
Value: FuncAIFRF(math.Yn),
|
||||||
},
|
},
|
||||||
|
|
322
stdlib/os.go
322
stdlib/os.go
|
@ -8,208 +8,208 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var osModule = map[string]tengo.Object{
|
var osModule = map[string]xgo.Object{
|
||||||
"platform": &tengo.String{Value: runtime.GOOS},
|
"platform": &xgo.String{Value: runtime.GOOS},
|
||||||
"arch": &tengo.String{Value: runtime.GOARCH},
|
"arch": &xgo.String{Value: runtime.GOARCH},
|
||||||
"o_rdonly": &tengo.Int{Value: int64(os.O_RDONLY)},
|
"o_rdonly": &xgo.Int{Value: int64(os.O_RDONLY)},
|
||||||
"o_wronly": &tengo.Int{Value: int64(os.O_WRONLY)},
|
"o_wronly": &xgo.Int{Value: int64(os.O_WRONLY)},
|
||||||
"o_rdwr": &tengo.Int{Value: int64(os.O_RDWR)},
|
"o_rdwr": &xgo.Int{Value: int64(os.O_RDWR)},
|
||||||
"o_append": &tengo.Int{Value: int64(os.O_APPEND)},
|
"o_append": &xgo.Int{Value: int64(os.O_APPEND)},
|
||||||
"o_create": &tengo.Int{Value: int64(os.O_CREATE)},
|
"o_create": &xgo.Int{Value: int64(os.O_CREATE)},
|
||||||
"o_excl": &tengo.Int{Value: int64(os.O_EXCL)},
|
"o_excl": &xgo.Int{Value: int64(os.O_EXCL)},
|
||||||
"o_sync": &tengo.Int{Value: int64(os.O_SYNC)},
|
"o_sync": &xgo.Int{Value: int64(os.O_SYNC)},
|
||||||
"o_trunc": &tengo.Int{Value: int64(os.O_TRUNC)},
|
"o_trunc": &xgo.Int{Value: int64(os.O_TRUNC)},
|
||||||
"mode_dir": &tengo.Int{Value: int64(os.ModeDir)},
|
"mode_dir": &xgo.Int{Value: int64(os.ModeDir)},
|
||||||
"mode_append": &tengo.Int{Value: int64(os.ModeAppend)},
|
"mode_append": &xgo.Int{Value: int64(os.ModeAppend)},
|
||||||
"mode_exclusive": &tengo.Int{Value: int64(os.ModeExclusive)},
|
"mode_exclusive": &xgo.Int{Value: int64(os.ModeExclusive)},
|
||||||
"mode_temporary": &tengo.Int{Value: int64(os.ModeTemporary)},
|
"mode_temporary": &xgo.Int{Value: int64(os.ModeTemporary)},
|
||||||
"mode_symlink": &tengo.Int{Value: int64(os.ModeSymlink)},
|
"mode_symlink": &xgo.Int{Value: int64(os.ModeSymlink)},
|
||||||
"mode_device": &tengo.Int{Value: int64(os.ModeDevice)},
|
"mode_device": &xgo.Int{Value: int64(os.ModeDevice)},
|
||||||
"mode_named_pipe": &tengo.Int{Value: int64(os.ModeNamedPipe)},
|
"mode_named_pipe": &xgo.Int{Value: int64(os.ModeNamedPipe)},
|
||||||
"mode_socket": &tengo.Int{Value: int64(os.ModeSocket)},
|
"mode_socket": &xgo.Int{Value: int64(os.ModeSocket)},
|
||||||
"mode_setuid": &tengo.Int{Value: int64(os.ModeSetuid)},
|
"mode_setuid": &xgo.Int{Value: int64(os.ModeSetuid)},
|
||||||
"mode_setgui": &tengo.Int{Value: int64(os.ModeSetgid)},
|
"mode_setgui": &xgo.Int{Value: int64(os.ModeSetgid)},
|
||||||
"mode_char_device": &tengo.Int{Value: int64(os.ModeCharDevice)},
|
"mode_char_device": &xgo.Int{Value: int64(os.ModeCharDevice)},
|
||||||
"mode_sticky": &tengo.Int{Value: int64(os.ModeSticky)},
|
"mode_sticky": &xgo.Int{Value: int64(os.ModeSticky)},
|
||||||
"mode_type": &tengo.Int{Value: int64(os.ModeType)},
|
"mode_type": &xgo.Int{Value: int64(os.ModeType)},
|
||||||
"mode_perm": &tengo.Int{Value: int64(os.ModePerm)},
|
"mode_perm": &xgo.Int{Value: int64(os.ModePerm)},
|
||||||
"path_separator": &tengo.Char{Value: os.PathSeparator},
|
"path_separator": &xgo.Char{Value: os.PathSeparator},
|
||||||
"path_list_separator": &tengo.Char{Value: os.PathListSeparator},
|
"path_list_separator": &xgo.Char{Value: os.PathListSeparator},
|
||||||
"dev_null": &tengo.String{Value: os.DevNull},
|
"dev_null": &xgo.String{Value: os.DevNull},
|
||||||
"seek_set": &tengo.Int{Value: int64(io.SeekStart)},
|
"seek_set": &xgo.Int{Value: int64(io.SeekStart)},
|
||||||
"seek_cur": &tengo.Int{Value: int64(io.SeekCurrent)},
|
"seek_cur": &xgo.Int{Value: int64(io.SeekCurrent)},
|
||||||
"seek_end": &tengo.Int{Value: int64(io.SeekEnd)},
|
"seek_end": &xgo.Int{Value: int64(io.SeekEnd)},
|
||||||
"args": &tengo.UserFunction{
|
"args": &xgo.UserFunction{
|
||||||
Name: "args",
|
Name: "args",
|
||||||
Value: osArgs,
|
Value: osArgs,
|
||||||
}, // args() => array(string)
|
}, // args() => array(string)
|
||||||
"chdir": &tengo.UserFunction{
|
"chdir": &xgo.UserFunction{
|
||||||
Name: "chdir",
|
Name: "chdir",
|
||||||
Value: FuncASRE(os.Chdir),
|
Value: FuncASRE(os.Chdir),
|
||||||
}, // chdir(dir string) => error
|
}, // chdir(dir string) => error
|
||||||
"chmod": osFuncASFmRE("chmod", os.Chmod), // chmod(name string, mode int) => error
|
"chmod": osFuncASFmRE("chmod", os.Chmod), // chmod(name string, mode int) => error
|
||||||
"chown": &tengo.UserFunction{
|
"chown": &xgo.UserFunction{
|
||||||
Name: "chown",
|
Name: "chown",
|
||||||
Value: FuncASIIRE(os.Chown),
|
Value: FuncASIIRE(os.Chown),
|
||||||
}, // chown(name string, uid int, gid int) => error
|
}, // chown(name string, uid int, gid int) => error
|
||||||
"clearenv": &tengo.UserFunction{
|
"clearenv": &xgo.UserFunction{
|
||||||
Name: "clearenv",
|
Name: "clearenv",
|
||||||
Value: FuncAR(os.Clearenv),
|
Value: FuncAR(os.Clearenv),
|
||||||
}, // clearenv()
|
}, // clearenv()
|
||||||
"environ": &tengo.UserFunction{
|
"environ": &xgo.UserFunction{
|
||||||
Name: "environ",
|
Name: "environ",
|
||||||
Value: FuncARSs(os.Environ),
|
Value: FuncARSs(os.Environ),
|
||||||
}, // environ() => array(string)
|
}, // environ() => array(string)
|
||||||
"exit": &tengo.UserFunction{
|
"exit": &xgo.UserFunction{
|
||||||
Name: "exit",
|
Name: "exit",
|
||||||
Value: FuncAIR(os.Exit),
|
Value: FuncAIR(os.Exit),
|
||||||
}, // exit(code int)
|
}, // exit(code int)
|
||||||
"expand_env": &tengo.UserFunction{
|
"expand_env": &xgo.UserFunction{
|
||||||
Name: "expand_env",
|
Name: "expand_env",
|
||||||
Value: osExpandEnv,
|
Value: osExpandEnv,
|
||||||
}, // expand_env(s string) => string
|
}, // expand_env(s string) => string
|
||||||
"getegid": &tengo.UserFunction{
|
"getegid": &xgo.UserFunction{
|
||||||
Name: "getegid",
|
Name: "getegid",
|
||||||
Value: FuncARI(os.Getegid),
|
Value: FuncARI(os.Getegid),
|
||||||
}, // getegid() => int
|
}, // getegid() => int
|
||||||
"getenv": &tengo.UserFunction{
|
"getenv": &xgo.UserFunction{
|
||||||
Name: "getenv",
|
Name: "getenv",
|
||||||
Value: FuncASRS(os.Getenv),
|
Value: FuncASRS(os.Getenv),
|
||||||
}, // getenv(s string) => string
|
}, // getenv(s string) => string
|
||||||
"geteuid": &tengo.UserFunction{
|
"geteuid": &xgo.UserFunction{
|
||||||
Name: "geteuid",
|
Name: "geteuid",
|
||||||
Value: FuncARI(os.Geteuid),
|
Value: FuncARI(os.Geteuid),
|
||||||
}, // geteuid() => int
|
}, // geteuid() => int
|
||||||
"getgid": &tengo.UserFunction{
|
"getgid": &xgo.UserFunction{
|
||||||
Name: "getgid",
|
Name: "getgid",
|
||||||
Value: FuncARI(os.Getgid),
|
Value: FuncARI(os.Getgid),
|
||||||
}, // getgid() => int
|
}, // getgid() => int
|
||||||
"getgroups": &tengo.UserFunction{
|
"getgroups": &xgo.UserFunction{
|
||||||
Name: "getgroups",
|
Name: "getgroups",
|
||||||
Value: FuncARIsE(os.Getgroups),
|
Value: FuncARIsE(os.Getgroups),
|
||||||
}, // getgroups() => array(string)/error
|
}, // getgroups() => array(string)/error
|
||||||
"getpagesize": &tengo.UserFunction{
|
"getpagesize": &xgo.UserFunction{
|
||||||
Name: "getpagesize",
|
Name: "getpagesize",
|
||||||
Value: FuncARI(os.Getpagesize),
|
Value: FuncARI(os.Getpagesize),
|
||||||
}, // getpagesize() => int
|
}, // getpagesize() => int
|
||||||
"getpid": &tengo.UserFunction{
|
"getpid": &xgo.UserFunction{
|
||||||
Name: "getpid",
|
Name: "getpid",
|
||||||
Value: FuncARI(os.Getpid),
|
Value: FuncARI(os.Getpid),
|
||||||
}, // getpid() => int
|
}, // getpid() => int
|
||||||
"getppid": &tengo.UserFunction{
|
"getppid": &xgo.UserFunction{
|
||||||
Name: "getppid",
|
Name: "getppid",
|
||||||
Value: FuncARI(os.Getppid),
|
Value: FuncARI(os.Getppid),
|
||||||
}, // getppid() => int
|
}, // getppid() => int
|
||||||
"getuid": &tengo.UserFunction{
|
"getuid": &xgo.UserFunction{
|
||||||
Name: "getuid",
|
Name: "getuid",
|
||||||
Value: FuncARI(os.Getuid),
|
Value: FuncARI(os.Getuid),
|
||||||
}, // getuid() => int
|
}, // getuid() => int
|
||||||
"getwd": &tengo.UserFunction{
|
"getwd": &xgo.UserFunction{
|
||||||
Name: "getwd",
|
Name: "getwd",
|
||||||
Value: FuncARSE(os.Getwd),
|
Value: FuncARSE(os.Getwd),
|
||||||
}, // getwd() => string/error
|
}, // getwd() => string/error
|
||||||
"hostname": &tengo.UserFunction{
|
"hostname": &xgo.UserFunction{
|
||||||
Name: "hostname",
|
Name: "hostname",
|
||||||
Value: FuncARSE(os.Hostname),
|
Value: FuncARSE(os.Hostname),
|
||||||
}, // hostname() => string/error
|
}, // hostname() => string/error
|
||||||
"lchown": &tengo.UserFunction{
|
"lchown": &xgo.UserFunction{
|
||||||
Name: "lchown",
|
Name: "lchown",
|
||||||
Value: FuncASIIRE(os.Lchown),
|
Value: FuncASIIRE(os.Lchown),
|
||||||
}, // lchown(name string, uid int, gid int) => error
|
}, // lchown(name string, uid int, gid int) => error
|
||||||
"link": &tengo.UserFunction{
|
"link": &xgo.UserFunction{
|
||||||
Name: "link",
|
Name: "link",
|
||||||
Value: FuncASSRE(os.Link),
|
Value: FuncASSRE(os.Link),
|
||||||
}, // link(oldname string, newname string) => error
|
}, // link(oldname string, newname string) => error
|
||||||
"lookup_env": &tengo.UserFunction{
|
"lookup_env": &xgo.UserFunction{
|
||||||
Name: "lookup_env",
|
Name: "lookup_env",
|
||||||
Value: osLookupEnv,
|
Value: osLookupEnv,
|
||||||
}, // lookup_env(key string) => string/false
|
}, // lookup_env(key string) => string/false
|
||||||
"mkdir": osFuncASFmRE("mkdir", os.Mkdir), // mkdir(name string, perm int) => error
|
"mkdir": osFuncASFmRE("mkdir", os.Mkdir), // mkdir(name string, perm int) => error
|
||||||
"mkdir_all": osFuncASFmRE("mkdir_all", os.MkdirAll), // mkdir_all(name string, perm int) => error
|
"mkdir_all": osFuncASFmRE("mkdir_all", os.MkdirAll), // mkdir_all(name string, perm int) => error
|
||||||
"readlink": &tengo.UserFunction{
|
"readlink": &xgo.UserFunction{
|
||||||
Name: "readlink",
|
Name: "readlink",
|
||||||
Value: FuncASRSE(os.Readlink),
|
Value: FuncASRSE(os.Readlink),
|
||||||
}, // readlink(name string) => string/error
|
}, // readlink(name string) => string/error
|
||||||
"remove": &tengo.UserFunction{
|
"remove": &xgo.UserFunction{
|
||||||
Name: "remove",
|
Name: "remove",
|
||||||
Value: FuncASRE(os.Remove),
|
Value: FuncASRE(os.Remove),
|
||||||
}, // remove(name string) => error
|
}, // remove(name string) => error
|
||||||
"remove_all": &tengo.UserFunction{
|
"remove_all": &xgo.UserFunction{
|
||||||
Name: "remove_all",
|
Name: "remove_all",
|
||||||
Value: FuncASRE(os.RemoveAll),
|
Value: FuncASRE(os.RemoveAll),
|
||||||
}, // remove_all(name string) => error
|
}, // remove_all(name string) => error
|
||||||
"rename": &tengo.UserFunction{
|
"rename": &xgo.UserFunction{
|
||||||
Name: "rename",
|
Name: "rename",
|
||||||
Value: FuncASSRE(os.Rename),
|
Value: FuncASSRE(os.Rename),
|
||||||
}, // rename(oldpath string, newpath string) => error
|
}, // rename(oldpath string, newpath string) => error
|
||||||
"setenv": &tengo.UserFunction{
|
"setenv": &xgo.UserFunction{
|
||||||
Name: "setenv",
|
Name: "setenv",
|
||||||
Value: FuncASSRE(os.Setenv),
|
Value: FuncASSRE(os.Setenv),
|
||||||
}, // setenv(key string, value string) => error
|
}, // setenv(key string, value string) => error
|
||||||
"symlink": &tengo.UserFunction{
|
"symlink": &xgo.UserFunction{
|
||||||
Name: "symlink",
|
Name: "symlink",
|
||||||
Value: FuncASSRE(os.Symlink),
|
Value: FuncASSRE(os.Symlink),
|
||||||
}, // symlink(oldname string newname string) => error
|
}, // symlink(oldname string newname string) => error
|
||||||
"temp_dir": &tengo.UserFunction{
|
"temp_dir": &xgo.UserFunction{
|
||||||
Name: "temp_dir",
|
Name: "temp_dir",
|
||||||
Value: FuncARS(os.TempDir),
|
Value: FuncARS(os.TempDir),
|
||||||
}, // temp_dir() => string
|
}, // temp_dir() => string
|
||||||
"truncate": &tengo.UserFunction{
|
"truncate": &xgo.UserFunction{
|
||||||
Name: "truncate",
|
Name: "truncate",
|
||||||
Value: FuncASI64RE(os.Truncate),
|
Value: FuncASI64RE(os.Truncate),
|
||||||
}, // truncate(name string, size int) => error
|
}, // truncate(name string, size int) => error
|
||||||
"unsetenv": &tengo.UserFunction{
|
"unsetenv": &xgo.UserFunction{
|
||||||
Name: "unsetenv",
|
Name: "unsetenv",
|
||||||
Value: FuncASRE(os.Unsetenv),
|
Value: FuncASRE(os.Unsetenv),
|
||||||
}, // unsetenv(key string) => error
|
}, // unsetenv(key string) => error
|
||||||
"create": &tengo.UserFunction{
|
"create": &xgo.UserFunction{
|
||||||
Name: "create",
|
Name: "create",
|
||||||
Value: osCreate,
|
Value: osCreate,
|
||||||
}, // create(name string) => imap(file)/error
|
}, // create(name string) => imap(file)/error
|
||||||
"open": &tengo.UserFunction{
|
"open": &xgo.UserFunction{
|
||||||
Name: "open",
|
Name: "open",
|
||||||
Value: osOpen,
|
Value: osOpen,
|
||||||
}, // open(name string) => imap(file)/error
|
}, // open(name string) => imap(file)/error
|
||||||
"open_file": &tengo.UserFunction{
|
"open_file": &xgo.UserFunction{
|
||||||
Name: "open_file",
|
Name: "open_file",
|
||||||
Value: osOpenFile,
|
Value: osOpenFile,
|
||||||
}, // open_file(name string, flag int, perm int) => imap(file)/error
|
}, // open_file(name string, flag int, perm int) => imap(file)/error
|
||||||
"find_process": &tengo.UserFunction{
|
"find_process": &xgo.UserFunction{
|
||||||
Name: "find_process",
|
Name: "find_process",
|
||||||
Value: osFindProcess,
|
Value: osFindProcess,
|
||||||
}, // find_process(pid int) => imap(process)/error
|
}, // find_process(pid int) => imap(process)/error
|
||||||
"start_process": &tengo.UserFunction{
|
"start_process": &xgo.UserFunction{
|
||||||
Name: "start_process",
|
Name: "start_process",
|
||||||
Value: osStartProcess,
|
Value: osStartProcess,
|
||||||
}, // start_process(name string, argv array(string), dir string, env array(string)) => imap(process)/error
|
}, // start_process(name string, argv array(string), dir string, env array(string)) => imap(process)/error
|
||||||
"exec_look_path": &tengo.UserFunction{
|
"exec_look_path": &xgo.UserFunction{
|
||||||
Name: "exec_look_path",
|
Name: "exec_look_path",
|
||||||
Value: FuncASRSE(exec.LookPath),
|
Value: FuncASRSE(exec.LookPath),
|
||||||
}, // exec_look_path(file) => string/error
|
}, // exec_look_path(file) => string/error
|
||||||
"exec": &tengo.UserFunction{
|
"exec": &xgo.UserFunction{
|
||||||
Name: "exec",
|
Name: "exec",
|
||||||
Value: osExec,
|
Value: osExec,
|
||||||
}, // exec(name, args...) => command
|
}, // exec(name, args...) => command
|
||||||
"stat": &tengo.UserFunction{
|
"stat": &xgo.UserFunction{
|
||||||
Name: "stat",
|
Name: "stat",
|
||||||
Value: osStat,
|
Value: osStat,
|
||||||
}, // stat(name) => imap(fileinfo)/error
|
}, // stat(name) => imap(fileinfo)/error
|
||||||
"read_file": &tengo.UserFunction{
|
"read_file": &xgo.UserFunction{
|
||||||
Name: "read_file",
|
Name: "read_file",
|
||||||
Value: osReadFile,
|
Value: osReadFile,
|
||||||
}, // readfile(name) => array(byte)/error
|
}, // readfile(name) => array(byte)/error
|
||||||
}
|
}
|
||||||
|
|
||||||
func osReadFile(args ...tengo.Object) (ret tengo.Object, err error) {
|
func osReadFile(args ...xgo.Object) (ret xgo.Object, err error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
fname, ok := tengo.ToString(args[0])
|
fname, ok := xgo.ToString(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -219,19 +219,19 @@ func osReadFile(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return wrapError(err), nil
|
return wrapError(err), nil
|
||||||
}
|
}
|
||||||
if len(bytes) > tengo.MaxBytesLen {
|
if len(bytes) > xgo.MaxBytesLen {
|
||||||
return nil, tengo.ErrBytesLimit
|
return nil, xgo.ErrBytesLimit
|
||||||
}
|
}
|
||||||
return &tengo.Bytes{Value: bytes}, nil
|
return &xgo.Bytes{Value: bytes}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func osStat(args ...tengo.Object) (ret tengo.Object, err error) {
|
func osStat(args ...xgo.Object) (ret xgo.Object, err error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
fname, ok := tengo.ToString(args[0])
|
fname, ok := xgo.ToString(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -241,29 +241,29 @@ func osStat(args ...tengo.Object) (ret tengo.Object, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return wrapError(err), nil
|
return wrapError(err), nil
|
||||||
}
|
}
|
||||||
fstat := &tengo.ImmutableMap{
|
fstat := &xgo.ImmutableMap{
|
||||||
Value: map[string]tengo.Object{
|
Value: map[string]xgo.Object{
|
||||||
"name": &tengo.String{Value: stat.Name()},
|
"name": &xgo.String{Value: stat.Name()},
|
||||||
"mtime": &tengo.Time{Value: stat.ModTime()},
|
"mtime": &xgo.Time{Value: stat.ModTime()},
|
||||||
"size": &tengo.Int{Value: stat.Size()},
|
"size": &xgo.Int{Value: stat.Size()},
|
||||||
"mode": &tengo.Int{Value: int64(stat.Mode())},
|
"mode": &xgo.Int{Value: int64(stat.Mode())},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if stat.IsDir() {
|
if stat.IsDir() {
|
||||||
fstat.Value["directory"] = tengo.TrueValue
|
fstat.Value["directory"] = xgo.TrueValue
|
||||||
} else {
|
} else {
|
||||||
fstat.Value["directory"] = tengo.FalseValue
|
fstat.Value["directory"] = xgo.FalseValue
|
||||||
}
|
}
|
||||||
return fstat, nil
|
return fstat, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func osCreate(args ...tengo.Object) (tengo.Object, error) {
|
func osCreate(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
s1, ok := tengo.ToString(args[0])
|
s1, ok := xgo.ToString(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -276,13 +276,13 @@ func osCreate(args ...tengo.Object) (tengo.Object, error) {
|
||||||
return makeOSFile(res), nil
|
return makeOSFile(res), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func osOpen(args ...tengo.Object) (tengo.Object, error) {
|
func osOpen(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
s1, ok := tengo.ToString(args[0])
|
s1, ok := xgo.ToString(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -295,29 +295,29 @@ func osOpen(args ...tengo.Object) (tengo.Object, error) {
|
||||||
return makeOSFile(res), nil
|
return makeOSFile(res), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func osOpenFile(args ...tengo.Object) (tengo.Object, error) {
|
func osOpenFile(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) != 3 {
|
if len(args) != 3 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
s1, ok := tengo.ToString(args[0])
|
s1, ok := xgo.ToString(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i2, ok := tengo.ToInt(args[1])
|
i2, ok := xgo.ToInt(args[1])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "second",
|
Name: "second",
|
||||||
Expected: "int(compatible)",
|
Expected: "int(compatible)",
|
||||||
Found: args[1].TypeName(),
|
Found: args[1].TypeName(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i3, ok := tengo.ToInt(args[2])
|
i3, ok := xgo.ToInt(args[2])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "third",
|
Name: "third",
|
||||||
Expected: "int(compatible)",
|
Expected: "int(compatible)",
|
||||||
Found: args[2].TypeName(),
|
Found: args[2].TypeName(),
|
||||||
|
@ -330,16 +330,16 @@ func osOpenFile(args ...tengo.Object) (tengo.Object, error) {
|
||||||
return makeOSFile(res), nil
|
return makeOSFile(res), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func osArgs(args ...tengo.Object) (tengo.Object, error) {
|
func osArgs(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) != 0 {
|
if len(args) != 0 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
arr := &tengo.Array{}
|
arr := &xgo.Array{}
|
||||||
for _, osArg := range os.Args {
|
for _, osArg := range os.Args {
|
||||||
if len(osArg) > tengo.MaxStringLen {
|
if len(osArg) > xgo.MaxStringLen {
|
||||||
return nil, tengo.ErrStringLimit
|
return nil, xgo.ErrStringLimit
|
||||||
}
|
}
|
||||||
arr.Value = append(arr.Value, &tengo.String{Value: osArg})
|
arr.Value = append(arr.Value, &xgo.String{Value: osArg})
|
||||||
}
|
}
|
||||||
return arr, nil
|
return arr, nil
|
||||||
}
|
}
|
||||||
|
@ -347,24 +347,24 @@ func osArgs(args ...tengo.Object) (tengo.Object, error) {
|
||||||
func osFuncASFmRE(
|
func osFuncASFmRE(
|
||||||
name string,
|
name string,
|
||||||
fn func(string, os.FileMode) error,
|
fn func(string, os.FileMode) error,
|
||||||
) *tengo.UserFunction {
|
) *xgo.UserFunction {
|
||||||
return &tengo.UserFunction{
|
return &xgo.UserFunction{
|
||||||
Name: name,
|
Name: name,
|
||||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
Value: func(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) != 2 {
|
if len(args) != 2 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
s1, ok := tengo.ToString(args[0])
|
s1, ok := xgo.ToString(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i2, ok := tengo.ToInt64(args[1])
|
i2, ok := xgo.ToInt64(args[1])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "second",
|
Name: "second",
|
||||||
Expected: "int(compatible)",
|
Expected: "int(compatible)",
|
||||||
Found: args[1].TypeName(),
|
Found: args[1].TypeName(),
|
||||||
|
@ -375,13 +375,13 @@ func osFuncASFmRE(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func osLookupEnv(args ...tengo.Object) (tengo.Object, error) {
|
func osLookupEnv(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
s1, ok := tengo.ToString(args[0])
|
s1, ok := xgo.ToString(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -389,21 +389,21 @@ func osLookupEnv(args ...tengo.Object) (tengo.Object, error) {
|
||||||
}
|
}
|
||||||
res, ok := os.LookupEnv(s1)
|
res, ok := os.LookupEnv(s1)
|
||||||
if !ok {
|
if !ok {
|
||||||
return tengo.FalseValue, nil
|
return xgo.FalseValue, nil
|
||||||
}
|
}
|
||||||
if len(res) > tengo.MaxStringLen {
|
if len(res) > xgo.MaxStringLen {
|
||||||
return nil, tengo.ErrStringLimit
|
return nil, xgo.ErrStringLimit
|
||||||
}
|
}
|
||||||
return &tengo.String{Value: res}, nil
|
return &xgo.String{Value: res}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func osExpandEnv(args ...tengo.Object) (tengo.Object, error) {
|
func osExpandEnv(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
s1, ok := tengo.ToString(args[0])
|
s1, ok := xgo.ToString(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -420,25 +420,25 @@ func osExpandEnv(args ...tengo.Object) (tengo.Object, error) {
|
||||||
// this does not count the other texts that are not being replaced
|
// this does not count the other texts that are not being replaced
|
||||||
// but the code checks the final length at the end
|
// but the code checks the final length at the end
|
||||||
vlen += len(v)
|
vlen += len(v)
|
||||||
if vlen > tengo.MaxStringLen {
|
if vlen > xgo.MaxStringLen {
|
||||||
failed = true
|
failed = true
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return v
|
return v
|
||||||
})
|
})
|
||||||
if failed || len(s) > tengo.MaxStringLen {
|
if failed || len(s) > xgo.MaxStringLen {
|
||||||
return nil, tengo.ErrStringLimit
|
return nil, xgo.ErrStringLimit
|
||||||
}
|
}
|
||||||
return &tengo.String{Value: s}, nil
|
return &xgo.String{Value: s}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func osExec(args ...tengo.Object) (tengo.Object, error) {
|
func osExec(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
name, ok := tengo.ToString(args[0])
|
name, ok := xgo.ToString(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -446,9 +446,9 @@ func osExec(args ...tengo.Object) (tengo.Object, error) {
|
||||||
}
|
}
|
||||||
var execArgs []string
|
var execArgs []string
|
||||||
for idx, arg := range args[1:] {
|
for idx, arg := range args[1:] {
|
||||||
execArg, ok := tengo.ToString(arg)
|
execArg, ok := xgo.ToString(arg)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: fmt.Sprintf("args[%d]", idx),
|
Name: fmt.Sprintf("args[%d]", idx),
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[1+idx].TypeName(),
|
Found: args[1+idx].TypeName(),
|
||||||
|
@ -459,13 +459,13 @@ func osExec(args ...tengo.Object) (tengo.Object, error) {
|
||||||
return makeOSExecCommand(exec.Command(name, execArgs...)), nil
|
return makeOSExecCommand(exec.Command(name, execArgs...)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func osFindProcess(args ...tengo.Object) (tengo.Object, error) {
|
func osFindProcess(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
i1, ok := tengo.ToInt(args[0])
|
i1, ok := xgo.ToInt(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "int(compatible)",
|
Expected: "int(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -478,13 +478,13 @@ func osFindProcess(args ...tengo.Object) (tengo.Object, error) {
|
||||||
return makeOSProcess(proc), nil
|
return makeOSProcess(proc), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func osStartProcess(args ...tengo.Object) (tengo.Object, error) {
|
func osStartProcess(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) != 4 {
|
if len(args) != 4 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
name, ok := tengo.ToString(args[0])
|
name, ok := xgo.ToString(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -493,27 +493,27 @@ func osStartProcess(args ...tengo.Object) (tengo.Object, error) {
|
||||||
var argv []string
|
var argv []string
|
||||||
var err error
|
var err error
|
||||||
switch arg1 := args[1].(type) {
|
switch arg1 := args[1].(type) {
|
||||||
case *tengo.Array:
|
case *xgo.Array:
|
||||||
argv, err = stringArray(arg1.Value, "second")
|
argv, err = stringArray(arg1.Value, "second")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
case *tengo.ImmutableArray:
|
case *xgo.ImmutableArray:
|
||||||
argv, err = stringArray(arg1.Value, "second")
|
argv, err = stringArray(arg1.Value, "second")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "second",
|
Name: "second",
|
||||||
Expected: "array",
|
Expected: "array",
|
||||||
Found: arg1.TypeName(),
|
Found: arg1.TypeName(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dir, ok := tengo.ToString(args[2])
|
dir, ok := xgo.ToString(args[2])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "third",
|
Name: "third",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[2].TypeName(),
|
Found: args[2].TypeName(),
|
||||||
|
@ -522,18 +522,18 @@ func osStartProcess(args ...tengo.Object) (tengo.Object, error) {
|
||||||
|
|
||||||
var env []string
|
var env []string
|
||||||
switch arg3 := args[3].(type) {
|
switch arg3 := args[3].(type) {
|
||||||
case *tengo.Array:
|
case *xgo.Array:
|
||||||
env, err = stringArray(arg3.Value, "fourth")
|
env, err = stringArray(arg3.Value, "fourth")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
case *tengo.ImmutableArray:
|
case *xgo.ImmutableArray:
|
||||||
env, err = stringArray(arg3.Value, "fourth")
|
env, err = stringArray(arg3.Value, "fourth")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "fourth",
|
Name: "fourth",
|
||||||
Expected: "array",
|
Expected: "array",
|
||||||
Found: arg3.TypeName(),
|
Found: arg3.TypeName(),
|
||||||
|
@ -550,12 +550,12 @@ func osStartProcess(args ...tengo.Object) (tengo.Object, error) {
|
||||||
return makeOSProcess(proc), nil
|
return makeOSProcess(proc), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func stringArray(arr []tengo.Object, argName string) ([]string, error) {
|
func stringArray(arr []xgo.Object, argName string) ([]string, error) {
|
||||||
var sarr []string
|
var sarr []string
|
||||||
for idx, elem := range arr {
|
for idx, elem := range arr {
|
||||||
str, ok := elem.(*tengo.String)
|
str, ok := elem.(*xgo.String)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: fmt.Sprintf("%s[%d]", argName, idx),
|
Name: fmt.Sprintf("%s[%d]", argName, idx),
|
||||||
Expected: "string",
|
Expected: "string",
|
||||||
Found: elem.TypeName(),
|
Found: elem.TypeName(),
|
||||||
|
|
|
@ -3,113 +3,113 @@ package stdlib
|
||||||
import (
|
import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeOSExecCommand(cmd *exec.Cmd) *tengo.ImmutableMap {
|
func makeOSExecCommand(cmd *exec.Cmd) *xgo.ImmutableMap {
|
||||||
return &tengo.ImmutableMap{
|
return &xgo.ImmutableMap{
|
||||||
Value: map[string]tengo.Object{
|
Value: map[string]xgo.Object{
|
||||||
// combined_output() => bytes/error
|
// combined_output() => bytes/error
|
||||||
"combined_output": &tengo.UserFunction{
|
"combined_output": &xgo.UserFunction{
|
||||||
Name: "combined_output",
|
Name: "combined_output",
|
||||||
Value: FuncARYE(cmd.CombinedOutput),
|
Value: FuncARYE(cmd.CombinedOutput),
|
||||||
},
|
},
|
||||||
// output() => bytes/error
|
// output() => bytes/error
|
||||||
"output": &tengo.UserFunction{
|
"output": &xgo.UserFunction{
|
||||||
Name: "output",
|
Name: "output",
|
||||||
Value: FuncARYE(cmd.Output),
|
Value: FuncARYE(cmd.Output),
|
||||||
}, //
|
}, //
|
||||||
// run() => error
|
// run() => error
|
||||||
"run": &tengo.UserFunction{
|
"run": &xgo.UserFunction{
|
||||||
Name: "run",
|
Name: "run",
|
||||||
Value: FuncARE(cmd.Run),
|
Value: FuncARE(cmd.Run),
|
||||||
}, //
|
}, //
|
||||||
// start() => error
|
// start() => error
|
||||||
"start": &tengo.UserFunction{
|
"start": &xgo.UserFunction{
|
||||||
Name: "start",
|
Name: "start",
|
||||||
Value: FuncARE(cmd.Start),
|
Value: FuncARE(cmd.Start),
|
||||||
}, //
|
}, //
|
||||||
// wait() => error
|
// wait() => error
|
||||||
"wait": &tengo.UserFunction{
|
"wait": &xgo.UserFunction{
|
||||||
Name: "wait",
|
Name: "wait",
|
||||||
Value: FuncARE(cmd.Wait),
|
Value: FuncARE(cmd.Wait),
|
||||||
}, //
|
}, //
|
||||||
// set_path(path string)
|
// set_path(path string)
|
||||||
"set_path": &tengo.UserFunction{
|
"set_path": &xgo.UserFunction{
|
||||||
Name: "set_path",
|
Name: "set_path",
|
||||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
Value: func(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
s1, ok := tengo.ToString(args[0])
|
s1, ok := xgo.ToString(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmd.Path = s1
|
cmd.Path = s1
|
||||||
return tengo.UndefinedValue, nil
|
return xgo.UndefinedValue, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// set_dir(dir string)
|
// set_dir(dir string)
|
||||||
"set_dir": &tengo.UserFunction{
|
"set_dir": &xgo.UserFunction{
|
||||||
Name: "set_dir",
|
Name: "set_dir",
|
||||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
Value: func(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
s1, ok := tengo.ToString(args[0])
|
s1, ok := xgo.ToString(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmd.Dir = s1
|
cmd.Dir = s1
|
||||||
return tengo.UndefinedValue, nil
|
return xgo.UndefinedValue, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// set_env(env array(string))
|
// set_env(env array(string))
|
||||||
"set_env": &tengo.UserFunction{
|
"set_env": &xgo.UserFunction{
|
||||||
Name: "set_env",
|
Name: "set_env",
|
||||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
Value: func(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
var env []string
|
var env []string
|
||||||
var err error
|
var err error
|
||||||
switch arg0 := args[0].(type) {
|
switch arg0 := args[0].(type) {
|
||||||
case *tengo.Array:
|
case *xgo.Array:
|
||||||
env, err = stringArray(arg0.Value, "first")
|
env, err = stringArray(arg0.Value, "first")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
case *tengo.ImmutableArray:
|
case *xgo.ImmutableArray:
|
||||||
env, err = stringArray(arg0.Value, "first")
|
env, err = stringArray(arg0.Value, "first")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "array",
|
Expected: "array",
|
||||||
Found: arg0.TypeName(),
|
Found: arg0.TypeName(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cmd.Env = env
|
cmd.Env = env
|
||||||
return tengo.UndefinedValue, nil
|
return xgo.UndefinedValue, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// process() => imap(process)
|
// process() => imap(process)
|
||||||
"process": &tengo.UserFunction{
|
"process": &xgo.UserFunction{
|
||||||
Name: "process",
|
Name: "process",
|
||||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
Value: func(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) != 0 {
|
if len(args) != 0 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
return makeOSProcess(cmd.Process), nil
|
return makeOSProcess(cmd.Process), nil
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,67 +3,67 @@ package stdlib
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeOSFile(file *os.File) *tengo.ImmutableMap {
|
func makeOSFile(file *os.File) *xgo.ImmutableMap {
|
||||||
return &tengo.ImmutableMap{
|
return &xgo.ImmutableMap{
|
||||||
Value: map[string]tengo.Object{
|
Value: map[string]xgo.Object{
|
||||||
// chdir() => true/error
|
// chdir() => true/error
|
||||||
"chdir": &tengo.UserFunction{
|
"chdir": &xgo.UserFunction{
|
||||||
Name: "chdir",
|
Name: "chdir",
|
||||||
Value: FuncARE(file.Chdir),
|
Value: FuncARE(file.Chdir),
|
||||||
}, //
|
}, //
|
||||||
// chown(uid int, gid int) => true/error
|
// chown(uid int, gid int) => true/error
|
||||||
"chown": &tengo.UserFunction{
|
"chown": &xgo.UserFunction{
|
||||||
Name: "chown",
|
Name: "chown",
|
||||||
Value: FuncAIIRE(file.Chown),
|
Value: FuncAIIRE(file.Chown),
|
||||||
}, //
|
}, //
|
||||||
// close() => error
|
// close() => error
|
||||||
"close": &tengo.UserFunction{
|
"close": &xgo.UserFunction{
|
||||||
Name: "close",
|
Name: "close",
|
||||||
Value: FuncARE(file.Close),
|
Value: FuncARE(file.Close),
|
||||||
}, //
|
}, //
|
||||||
// name() => string
|
// name() => string
|
||||||
"name": &tengo.UserFunction{
|
"name": &xgo.UserFunction{
|
||||||
Name: "name",
|
Name: "name",
|
||||||
Value: FuncARS(file.Name),
|
Value: FuncARS(file.Name),
|
||||||
}, //
|
}, //
|
||||||
// readdirnames(n int) => array(string)/error
|
// readdirnames(n int) => array(string)/error
|
||||||
"readdirnames": &tengo.UserFunction{
|
"readdirnames": &xgo.UserFunction{
|
||||||
Name: "readdirnames",
|
Name: "readdirnames",
|
||||||
Value: FuncAIRSsE(file.Readdirnames),
|
Value: FuncAIRSsE(file.Readdirnames),
|
||||||
}, //
|
}, //
|
||||||
// sync() => error
|
// sync() => error
|
||||||
"sync": &tengo.UserFunction{
|
"sync": &xgo.UserFunction{
|
||||||
Name: "sync",
|
Name: "sync",
|
||||||
Value: FuncARE(file.Sync),
|
Value: FuncARE(file.Sync),
|
||||||
}, //
|
}, //
|
||||||
// write(bytes) => int/error
|
// write(bytes) => int/error
|
||||||
"write": &tengo.UserFunction{
|
"write": &xgo.UserFunction{
|
||||||
Name: "write",
|
Name: "write",
|
||||||
Value: FuncAYRIE(file.Write),
|
Value: FuncAYRIE(file.Write),
|
||||||
}, //
|
}, //
|
||||||
// write(string) => int/error
|
// write(string) => int/error
|
||||||
"write_string": &tengo.UserFunction{
|
"write_string": &xgo.UserFunction{
|
||||||
Name: "write_string",
|
Name: "write_string",
|
||||||
Value: FuncASRIE(file.WriteString),
|
Value: FuncASRIE(file.WriteString),
|
||||||
}, //
|
}, //
|
||||||
// read(bytes) => int/error
|
// read(bytes) => int/error
|
||||||
"read": &tengo.UserFunction{
|
"read": &xgo.UserFunction{
|
||||||
Name: "read",
|
Name: "read",
|
||||||
Value: FuncAYRIE(file.Read),
|
Value: FuncAYRIE(file.Read),
|
||||||
}, //
|
}, //
|
||||||
// chmod(mode int) => error
|
// chmod(mode int) => error
|
||||||
"chmod": &tengo.UserFunction{
|
"chmod": &xgo.UserFunction{
|
||||||
Name: "chmod",
|
Name: "chmod",
|
||||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
Value: func(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
i1, ok := tengo.ToInt64(args[0])
|
i1, ok := xgo.ToInt64(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "int(compatible)",
|
Expected: "int(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -73,23 +73,23 @@ func makeOSFile(file *os.File) *tengo.ImmutableMap {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// seek(offset int, whence int) => int/error
|
// seek(offset int, whence int) => int/error
|
||||||
"seek": &tengo.UserFunction{
|
"seek": &xgo.UserFunction{
|
||||||
Name: "seek",
|
Name: "seek",
|
||||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
Value: func(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) != 2 {
|
if len(args) != 2 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
i1, ok := tengo.ToInt64(args[0])
|
i1, ok := xgo.ToInt64(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "int(compatible)",
|
Expected: "int(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i2, ok := tengo.ToInt(args[1])
|
i2, ok := xgo.ToInt(args[1])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "second",
|
Name: "second",
|
||||||
Expected: "int(compatible)",
|
Expected: "int(compatible)",
|
||||||
Found: args[1].TypeName(),
|
Found: args[1].TypeName(),
|
||||||
|
@ -99,17 +99,17 @@ func makeOSFile(file *os.File) *tengo.ImmutableMap {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return wrapError(err), nil
|
return wrapError(err), nil
|
||||||
}
|
}
|
||||||
return &tengo.Int{Value: res}, nil
|
return &xgo.Int{Value: res}, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// stat() => imap(fileinfo)/error
|
// stat() => imap(fileinfo)/error
|
||||||
"stat": &tengo.UserFunction{
|
"stat": &xgo.UserFunction{
|
||||||
Name: "stat",
|
Name: "stat",
|
||||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
Value: func(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) != 0 {
|
if len(args) != 0 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
return osStat(&tengo.String{Value: file.Name()})
|
return osStat(&xgo.String{Value: file.Name()})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,25 +4,25 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeOSProcessState(state *os.ProcessState) *tengo.ImmutableMap {
|
func makeOSProcessState(state *os.ProcessState) *xgo.ImmutableMap {
|
||||||
return &tengo.ImmutableMap{
|
return &xgo.ImmutableMap{
|
||||||
Value: map[string]tengo.Object{
|
Value: map[string]xgo.Object{
|
||||||
"exited": &tengo.UserFunction{
|
"exited": &xgo.UserFunction{
|
||||||
Name: "exited",
|
Name: "exited",
|
||||||
Value: FuncARB(state.Exited),
|
Value: FuncARB(state.Exited),
|
||||||
},
|
},
|
||||||
"pid": &tengo.UserFunction{
|
"pid": &xgo.UserFunction{
|
||||||
Name: "pid",
|
Name: "pid",
|
||||||
Value: FuncARI(state.Pid),
|
Value: FuncARI(state.Pid),
|
||||||
},
|
},
|
||||||
"string": &tengo.UserFunction{
|
"string": &xgo.UserFunction{
|
||||||
Name: "string",
|
Name: "string",
|
||||||
Value: FuncARS(state.String),
|
Value: FuncARS(state.String),
|
||||||
},
|
},
|
||||||
"success": &tengo.UserFunction{
|
"success": &xgo.UserFunction{
|
||||||
Name: "success",
|
Name: "success",
|
||||||
Value: FuncARB(state.Success),
|
Value: FuncARB(state.Success),
|
||||||
},
|
},
|
||||||
|
@ -30,26 +30,26 @@ func makeOSProcessState(state *os.ProcessState) *tengo.ImmutableMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeOSProcess(proc *os.Process) *tengo.ImmutableMap {
|
func makeOSProcess(proc *os.Process) *xgo.ImmutableMap {
|
||||||
return &tengo.ImmutableMap{
|
return &xgo.ImmutableMap{
|
||||||
Value: map[string]tengo.Object{
|
Value: map[string]xgo.Object{
|
||||||
"kill": &tengo.UserFunction{
|
"kill": &xgo.UserFunction{
|
||||||
Name: "kill",
|
Name: "kill",
|
||||||
Value: FuncARE(proc.Kill),
|
Value: FuncARE(proc.Kill),
|
||||||
},
|
},
|
||||||
"release": &tengo.UserFunction{
|
"release": &xgo.UserFunction{
|
||||||
Name: "release",
|
Name: "release",
|
||||||
Value: FuncARE(proc.Release),
|
Value: FuncARE(proc.Release),
|
||||||
},
|
},
|
||||||
"signal": &tengo.UserFunction{
|
"signal": &xgo.UserFunction{
|
||||||
Name: "signal",
|
Name: "signal",
|
||||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
Value: func(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
i1, ok := tengo.ToInt64(args[0])
|
i1, ok := xgo.ToInt64(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "int(compatible)",
|
Expected: "int(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -58,11 +58,11 @@ func makeOSProcess(proc *os.Process) *tengo.ImmutableMap {
|
||||||
return wrapError(proc.Signal(syscall.Signal(i1))), nil
|
return wrapError(proc.Signal(syscall.Signal(i1))), nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"wait": &tengo.UserFunction{
|
"wait": &xgo.UserFunction{
|
||||||
Name: "wait",
|
Name: "wait",
|
||||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
Value: func(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) != 0 {
|
if len(args) != 0 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
state, err := proc.Wait()
|
state, err := proc.Wait()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -5,8 +5,8 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
"github.com/d5/tengo/v2/require"
|
"surdeus.su/core/xgo/v2/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestReadFile(t *testing.T) {
|
func TestReadFile(t *testing.T) {
|
||||||
|
@ -20,7 +20,7 @@ func TestReadFile(t *testing.T) {
|
||||||
_ = tf.Close()
|
_ = tf.Close()
|
||||||
|
|
||||||
module(t, "os").call("read_file", tf.Name()).
|
module(t, "os").call("read_file", tf.Name()).
|
||||||
expect(&tengo.Bytes{Value: content})
|
expect(&xgo.Bytes{Value: content})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadFileArgs(t *testing.T) {
|
func TestReadFileArgs(t *testing.T) {
|
||||||
|
@ -46,13 +46,13 @@ func TestFileStatFile(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
module(t, "os").call("stat", tf.Name()).expect(&tengo.ImmutableMap{
|
module(t, "os").call("stat", tf.Name()).expect(&xgo.ImmutableMap{
|
||||||
Value: map[string]tengo.Object{
|
Value: map[string]xgo.Object{
|
||||||
"name": &tengo.String{Value: stat.Name()},
|
"name": &xgo.String{Value: stat.Name()},
|
||||||
"mtime": &tengo.Time{Value: stat.ModTime()},
|
"mtime": &xgo.Time{Value: stat.ModTime()},
|
||||||
"size": &tengo.Int{Value: stat.Size()},
|
"size": &xgo.Int{Value: stat.Size()},
|
||||||
"mode": &tengo.Int{Value: int64(stat.Mode())},
|
"mode": &xgo.Int{Value: int64(stat.Mode())},
|
||||||
"directory": tengo.FalseValue,
|
"directory": xgo.FalseValue,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -65,21 +65,21 @@ func TestFileStatDir(t *testing.T) {
|
||||||
stat, err := os.Stat(td)
|
stat, err := os.Stat(td)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
module(t, "os").call("stat", td).expect(&tengo.ImmutableMap{
|
module(t, "os").call("stat", td).expect(&xgo.ImmutableMap{
|
||||||
Value: map[string]tengo.Object{
|
Value: map[string]xgo.Object{
|
||||||
"name": &tengo.String{Value: stat.Name()},
|
"name": &xgo.String{Value: stat.Name()},
|
||||||
"mtime": &tengo.Time{Value: stat.ModTime()},
|
"mtime": &xgo.Time{Value: stat.ModTime()},
|
||||||
"size": &tengo.Int{Value: stat.Size()},
|
"size": &xgo.Int{Value: stat.Size()},
|
||||||
"mode": &tengo.Int{Value: int64(stat.Mode())},
|
"mode": &xgo.Int{Value: int64(stat.Mode())},
|
||||||
"directory": tengo.TrueValue,
|
"directory": xgo.TrueValue,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOSExpandEnv(t *testing.T) {
|
func TestOSExpandEnv(t *testing.T) {
|
||||||
curMaxStringLen := tengo.MaxStringLen
|
curMaxStringLen := xgo.MaxStringLen
|
||||||
defer func() { tengo.MaxStringLen = curMaxStringLen }()
|
defer func() { xgo.MaxStringLen = curMaxStringLen }()
|
||||||
tengo.MaxStringLen = 12
|
xgo.MaxStringLen = 12
|
||||||
|
|
||||||
_ = os.Setenv("TENGO", "FOO BAR")
|
_ = os.Setenv("TENGO", "FOO BAR")
|
||||||
module(t, "os").call("expand_env", "$TENGO").expect("FOO BAR")
|
module(t, "os").call("expand_env", "$TENGO").expect("FOO BAR")
|
||||||
|
|
46
stdlib/paths/main.go
Normal file
46
stdlib/paths/main.go
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
package paths
|
||||||
|
|
||||||
|
import (
|
||||||
|
"surdeus.su/core/xgo/v2"
|
||||||
|
"path"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Module = map[string]xgo.Object{
|
||||||
|
"base": &xgo.UserFunction{
|
||||||
|
Name: "base",
|
||||||
|
Value: wrapOneArg(path.Base),
|
||||||
|
},
|
||||||
|
"ext": &xgo.UserFunction{
|
||||||
|
Name: "ext",
|
||||||
|
Value: wrapOneArg(path.Ext),
|
||||||
|
},
|
||||||
|
"dir": &xgo.UserFunction{
|
||||||
|
Name: "dir",
|
||||||
|
Value: wrapOneArg(path.Dir),
|
||||||
|
},
|
||||||
|
"clean": &xgo.UserFunction{
|
||||||
|
Name: "clean",
|
||||||
|
Value: wrapOneArg(path.Clean),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func wrapOneArg(
|
||||||
|
fn func(string) string,
|
||||||
|
) func(...xgo.Object) (xgo.Object, error) {
|
||||||
|
return func(args ...xgo.Object) (xgo.Object, error) {
|
||||||
|
if len(args) != 1 {
|
||||||
|
return nil, xgo.ErrWrongNumArguments
|
||||||
|
}
|
||||||
|
str, ok := xgo.ToString(args[0])
|
||||||
|
if !ok {
|
||||||
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
|
Name: "first",
|
||||||
|
Expected: "string(compatible)",
|
||||||
|
Found: args[0].TypeName(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &xgo.String{
|
||||||
|
Value: fn(str),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,47 +3,47 @@ package stdlib
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
var randModule = map[string]tengo.Object{
|
var randModule = map[string]xgo.Object{
|
||||||
"int": &tengo.UserFunction{
|
"int": &xgo.UserFunction{
|
||||||
Name: "int",
|
Name: "int",
|
||||||
Value: FuncARI64(rand.Int63),
|
Value: FuncARI64(rand.Int63),
|
||||||
},
|
},
|
||||||
"float": &tengo.UserFunction{
|
"float": &xgo.UserFunction{
|
||||||
Name: "float",
|
Name: "float",
|
||||||
Value: FuncARF(rand.Float64),
|
Value: FuncARF(rand.Float64),
|
||||||
},
|
},
|
||||||
"intn": &tengo.UserFunction{
|
"intn": &xgo.UserFunction{
|
||||||
Name: "intn",
|
Name: "intn",
|
||||||
Value: FuncAI64RI64(rand.Int63n),
|
Value: FuncAI64RI64(rand.Int63n),
|
||||||
},
|
},
|
||||||
"exp_float": &tengo.UserFunction{
|
"exp_float": &xgo.UserFunction{
|
||||||
Name: "exp_float",
|
Name: "exp_float",
|
||||||
Value: FuncARF(rand.ExpFloat64),
|
Value: FuncARF(rand.ExpFloat64),
|
||||||
},
|
},
|
||||||
"norm_float": &tengo.UserFunction{
|
"norm_float": &xgo.UserFunction{
|
||||||
Name: "norm_float",
|
Name: "norm_float",
|
||||||
Value: FuncARF(rand.NormFloat64),
|
Value: FuncARF(rand.NormFloat64),
|
||||||
},
|
},
|
||||||
"perm": &tengo.UserFunction{
|
"perm": &xgo.UserFunction{
|
||||||
Name: "perm",
|
Name: "perm",
|
||||||
Value: FuncAIRIs(rand.Perm),
|
Value: FuncAIRIs(rand.Perm),
|
||||||
},
|
},
|
||||||
"seed": &tengo.UserFunction{
|
"seed": &xgo.UserFunction{
|
||||||
Name: "seed",
|
Name: "seed",
|
||||||
Value: FuncAI64R(rand.Seed),
|
Value: FuncAI64R(rand.Seed),
|
||||||
},
|
},
|
||||||
"read": &tengo.UserFunction{
|
"read": &xgo.UserFunction{
|
||||||
Name: "read",
|
Name: "read",
|
||||||
Value: func(args ...tengo.Object) (ret tengo.Object, err error) {
|
Value: func(args ...xgo.Object) (ret xgo.Object, err error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
y1, ok := args[0].(*tengo.Bytes)
|
y1, ok := args[0].(*xgo.Bytes)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "bytes",
|
Expected: "bytes",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -54,18 +54,18 @@ var randModule = map[string]tengo.Object{
|
||||||
ret = wrapError(err)
|
ret = wrapError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return &tengo.Int{Value: int64(res)}, nil
|
return &xgo.Int{Value: int64(res)}, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"rand": &tengo.UserFunction{
|
"rand": &xgo.UserFunction{
|
||||||
Name: "rand",
|
Name: "rand",
|
||||||
Value: func(args ...tengo.Object) (tengo.Object, error) {
|
Value: func(args ...xgo.Object) (xgo.Object, error) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
i1, ok := tengo.ToInt64(args[0])
|
i1, ok := xgo.ToInt64(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "int(compatible)",
|
Expected: "int(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -77,49 +77,49 @@ var randModule = map[string]tengo.Object{
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func randRand(r *rand.Rand) *tengo.ImmutableMap {
|
func randRand(r *rand.Rand) *xgo.ImmutableMap {
|
||||||
return &tengo.ImmutableMap{
|
return &xgo.ImmutableMap{
|
||||||
Value: map[string]tengo.Object{
|
Value: map[string]xgo.Object{
|
||||||
"int": &tengo.UserFunction{
|
"int": &xgo.UserFunction{
|
||||||
Name: "int",
|
Name: "int",
|
||||||
Value: FuncARI64(r.Int63),
|
Value: FuncARI64(r.Int63),
|
||||||
},
|
},
|
||||||
"float": &tengo.UserFunction{
|
"float": &xgo.UserFunction{
|
||||||
Name: "float",
|
Name: "float",
|
||||||
Value: FuncARF(r.Float64),
|
Value: FuncARF(r.Float64),
|
||||||
},
|
},
|
||||||
"intn": &tengo.UserFunction{
|
"intn": &xgo.UserFunction{
|
||||||
Name: "intn",
|
Name: "intn",
|
||||||
Value: FuncAI64RI64(r.Int63n),
|
Value: FuncAI64RI64(r.Int63n),
|
||||||
},
|
},
|
||||||
"exp_float": &tengo.UserFunction{
|
"exp_float": &xgo.UserFunction{
|
||||||
Name: "exp_float",
|
Name: "exp_float",
|
||||||
Value: FuncARF(r.ExpFloat64),
|
Value: FuncARF(r.ExpFloat64),
|
||||||
},
|
},
|
||||||
"norm_float": &tengo.UserFunction{
|
"norm_float": &xgo.UserFunction{
|
||||||
Name: "norm_float",
|
Name: "norm_float",
|
||||||
Value: FuncARF(r.NormFloat64),
|
Value: FuncARF(r.NormFloat64),
|
||||||
},
|
},
|
||||||
"perm": &tengo.UserFunction{
|
"perm": &xgo.UserFunction{
|
||||||
Name: "perm",
|
Name: "perm",
|
||||||
Value: FuncAIRIs(r.Perm),
|
Value: FuncAIRIs(r.Perm),
|
||||||
},
|
},
|
||||||
"seed": &tengo.UserFunction{
|
"seed": &xgo.UserFunction{
|
||||||
Name: "seed",
|
Name: "seed",
|
||||||
Value: FuncAI64R(r.Seed),
|
Value: FuncAI64R(r.Seed),
|
||||||
},
|
},
|
||||||
"read": &tengo.UserFunction{
|
"read": &xgo.UserFunction{
|
||||||
Name: "read",
|
Name: "read",
|
||||||
Value: func(args ...tengo.Object) (
|
Value: func(args ...xgo.Object) (
|
||||||
ret tengo.Object,
|
ret xgo.Object,
|
||||||
err error,
|
err error,
|
||||||
) {
|
) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return nil, tengo.ErrWrongNumArguments
|
return nil, xgo.ErrWrongNumArguments
|
||||||
}
|
}
|
||||||
y1, ok := args[0].(*tengo.Bytes)
|
y1, ok := args[0].(*xgo.Bytes)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrInvalidArgumentType{
|
return nil, xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "bytes",
|
Expected: "bytes",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -130,7 +130,7 @@ func randRand(r *rand.Rand) *tengo.ImmutableMap {
|
||||||
ret = wrapError(err)
|
ret = wrapError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return &tengo.Int{Value: int64(res)}, nil
|
return &xgo.Int{Value: int64(res)}, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,15 +4,15 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
"github.com/d5/tengo/v2/require"
|
"surdeus.su/core/xgo/v2/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRand(t *testing.T) {
|
func TestRand(t *testing.T) {
|
||||||
var seed int64 = 1234
|
var seed int64 = 1234
|
||||||
r := rand.New(rand.NewSource(seed))
|
r := rand.New(rand.NewSource(seed))
|
||||||
|
|
||||||
module(t, "rand").call("seed", seed).expect(tengo.UndefinedValue)
|
module(t, "rand").call("seed", seed).expect(xgo.UndefinedValue)
|
||||||
module(t, "rand").call("int").expect(r.Int63())
|
module(t, "rand").call("int").expect(r.Int63())
|
||||||
module(t, "rand").call("float").expect(r.Float64())
|
module(t, "rand").call("float").expect(r.Float64())
|
||||||
module(t, "rand").call("intn", 111).expect(r.Int63n(111))
|
module(t, "rand").call("intn", 111).expect(r.Int63n(111))
|
||||||
|
@ -21,7 +21,7 @@ func TestRand(t *testing.T) {
|
||||||
module(t, "rand").call("perm", 10).expect(r.Perm(10))
|
module(t, "rand").call("perm", 10).expect(r.Perm(10))
|
||||||
|
|
||||||
buf1 := make([]byte, 10)
|
buf1 := make([]byte, 10)
|
||||||
buf2 := &tengo.Bytes{Value: make([]byte, 10)}
|
buf2 := &xgo.Bytes{Value: make([]byte, 10)}
|
||||||
n, _ := r.Read(buf1)
|
n, _ := r.Read(buf1)
|
||||||
module(t, "rand").call("read", buf2).expect(n)
|
module(t, "rand").call("read", buf2).expect(n)
|
||||||
require.Equal(t, buf1, buf2.Value)
|
require.Equal(t, buf1, buf2.Value)
|
||||||
|
@ -29,7 +29,7 @@ func TestRand(t *testing.T) {
|
||||||
seed = 9191
|
seed = 9191
|
||||||
r = rand.New(rand.NewSource(seed))
|
r = rand.New(rand.NewSource(seed))
|
||||||
randObj := module(t, "rand").call("rand", seed)
|
randObj := module(t, "rand").call("rand", seed)
|
||||||
randObj.call("seed", seed).expect(tengo.UndefinedValue)
|
randObj.call("seed", seed).expect(xgo.UndefinedValue)
|
||||||
randObj.call("int").expect(r.Int63())
|
randObj.call("int").expect(r.Int63())
|
||||||
randObj.call("float").expect(r.Float64())
|
randObj.call("float").expect(r.Float64())
|
||||||
randObj.call("intn", 111).expect(r.Int63n(111))
|
randObj.call("intn", 111).expect(r.Int63n(111))
|
||||||
|
@ -38,7 +38,7 @@ func TestRand(t *testing.T) {
|
||||||
randObj.call("perm", 10).expect(r.Perm(10))
|
randObj.call("perm", 10).expect(r.Perm(10))
|
||||||
|
|
||||||
buf1 = make([]byte, 12)
|
buf1 = make([]byte, 12)
|
||||||
buf2 = &tengo.Bytes{Value: make([]byte, 12)}
|
buf2 = &xgo.Bytes{Value: make([]byte, 12)}
|
||||||
n, _ = r.Read(buf1)
|
n, _ = r.Read(buf1)
|
||||||
randObj.call("read", buf2).expect(n)
|
randObj.call("read", buf2).expect(n)
|
||||||
require.Equal(t, buf1, buf2.Value)
|
require.Equal(t, buf1, buf2.Value)
|
||||||
|
|
|
@ -2,7 +2,13 @@
|
||||||
|
|
||||||
package stdlib
|
package stdlib
|
||||||
|
|
||||||
|
import "embed"
|
||||||
|
var _ = embed.FS{}
|
||||||
|
|
||||||
|
//go:embed srcmod_enum.xgo
|
||||||
|
var srcmodEnum string
|
||||||
|
|
||||||
// SourceModules are source type standard library modules.
|
// SourceModules are source type standard library modules.
|
||||||
var SourceModules = map[string]string{
|
var SourceModules = map[string]string{
|
||||||
"enum": "is_enumerable := func(x) {\n return is_array(x) || is_map(x) || is_immutable_array(x) || is_immutable_map(x)\n}\n\nis_array_like := func(x) {\n return is_array(x) || is_immutable_array(x)\n}\n\nexport {\n // all returns true if the given function `fn` evaluates to a truthy value on\n // all of the items in `x`. It returns undefined if `x` is not enumerable.\n all: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if !fn(k, v) { return false }\n }\n\n return true\n },\n // any returns true if the given function `fn` evaluates to a truthy value on\n // any of the items in `x`. It returns undefined if `x` is not enumerable.\n any: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if fn(k, v) { return true }\n }\n\n return false\n },\n // chunk returns an array of elements split into groups the length of size.\n // If `x` can't be split evenly, the final chunk will be the remaining elements.\n // It returns undefined if `x` is not array.\n chunk: func(x, size) {\n if !is_array_like(x) || !size { return undefined }\n\n numElements := len(x)\n if !numElements { return [] }\n\n res := []\n idx := 0\n for idx < numElements {\n res = append(res, x[idx:idx+size])\n idx += size\n }\n\n return res\n },\n // at returns an element at the given index (if `x` is array) or\n // key (if `x` is map). It returns undefined if `x` is not enumerable.\n at: func(x, key) {\n if !is_enumerable(x) { return undefined }\n\n if is_array_like(x) {\n if !is_int(key) { return undefined }\n } else {\n if !is_string(key) { return undefined }\n }\n\n return x[key]\n },\n // each iterates over elements of `x` and invokes `fn` for each element. `fn` is\n // invoked with two arguments: `key` and `value`. `key` is an int index\n // if `x` is array. `key` is a string key if `x` is map. It does not iterate\n // and returns undefined if `x` is not enumerable.\n each: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n fn(k, v)\n }\n },\n // filter iterates over elements of `x`, returning an array of all elements `fn`\n // returns truthy for. `fn` is invoked with two arguments: `key` and `value`.\n // `key` is an int index if `x` is array. It returns undefined if `x` is not array.\n filter: func(x, fn) {\n if !is_array_like(x) { return undefined }\n\n dst := []\n for k, v in x {\n if fn(k, v) { dst = append(dst, v) }\n }\n\n return dst\n },\n // find iterates over elements of `x`, returning value of the first element `fn`\n // returns truthy for. `fn` is invoked with two arguments: `key` and `value`.\n // `key` is an int index if `x` is array. `key` is a string key if `x` is map.\n // It returns undefined if `x` is not enumerable.\n find: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if fn(k, v) { return v }\n }\n },\n // find_key iterates over elements of `x`, returning key or index of the first\n // element `fn` returns truthy for. `fn` is invoked with two arguments: `key`\n // and `value`. `key` is an int index if `x` is array. `key` is a string key if\n // `x` is map. It returns undefined if `x` is not enumerable.\n find_key: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if fn(k, v) { return k }\n }\n },\n // map creates an array of values by running each element in `x` through `fn`.\n // `fn` is invoked with two arguments: `key` and `value`. `key` is an int index\n // if `x` is array. `key` is a string key if `x` is map. It returns undefined\n // if `x` is not enumerable.\n map: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n dst := []\n for k, v in x {\n dst = append(dst, fn(k, v))\n }\n\n return dst\n },\n // key returns the first argument.\n key: func(k, _) { return k },\n // value returns the second argument.\n value: func(_, v) { return v }\n}\n",
|
"enum": srcmodEnum,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,127 +0,0 @@
|
||||||
is_enumerable := func(x) {
|
|
||||||
return is_array(x) || is_map(x) || is_immutable_array(x) || is_immutable_map(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
is_array_like := func(x) {
|
|
||||||
return is_array(x) || is_immutable_array(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
// all returns true if the given function `fn` evaluates to a truthy value on
|
|
||||||
// all of the items in `x`. It returns undefined if `x` is not enumerable.
|
|
||||||
all: func(x, fn) {
|
|
||||||
if !is_enumerable(x) { return undefined }
|
|
||||||
|
|
||||||
for k, v in x {
|
|
||||||
if !fn(k, v) { return false }
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
// any returns true if the given function `fn` evaluates to a truthy value on
|
|
||||||
// any of the items in `x`. It returns undefined if `x` is not enumerable.
|
|
||||||
any: func(x, fn) {
|
|
||||||
if !is_enumerable(x) { return undefined }
|
|
||||||
|
|
||||||
for k, v in x {
|
|
||||||
if fn(k, v) { return true }
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
// chunk returns an array of elements split into groups the length of size.
|
|
||||||
// If `x` can't be split evenly, the final chunk will be the remaining elements.
|
|
||||||
// It returns undefined if `x` is not array.
|
|
||||||
chunk: func(x, size) {
|
|
||||||
if !is_array_like(x) || !size { return undefined }
|
|
||||||
|
|
||||||
numElements := len(x)
|
|
||||||
if !numElements { return [] }
|
|
||||||
|
|
||||||
res := []
|
|
||||||
idx := 0
|
|
||||||
for idx < numElements {
|
|
||||||
res = append(res, x[idx:idx+size])
|
|
||||||
idx += size
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
|
||||||
},
|
|
||||||
// at returns an element at the given index (if `x` is array) or
|
|
||||||
// key (if `x` is map). It returns undefined if `x` is not enumerable.
|
|
||||||
at: func(x, key) {
|
|
||||||
if !is_enumerable(x) { return undefined }
|
|
||||||
|
|
||||||
if is_array_like(x) {
|
|
||||||
if !is_int(key) { return undefined }
|
|
||||||
} else {
|
|
||||||
if !is_string(key) { return undefined }
|
|
||||||
}
|
|
||||||
|
|
||||||
return x[key]
|
|
||||||
},
|
|
||||||
// each iterates over elements of `x` and invokes `fn` for each element. `fn` is
|
|
||||||
// invoked with two arguments: `key` and `value`. `key` is an int index
|
|
||||||
// if `x` is array. `key` is a string key if `x` is map. It does not iterate
|
|
||||||
// and returns undefined if `x` is not enumerable.
|
|
||||||
each: func(x, fn) {
|
|
||||||
if !is_enumerable(x) { return undefined }
|
|
||||||
|
|
||||||
for k, v in x {
|
|
||||||
fn(k, v)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// filter iterates over elements of `x`, returning an array of all elements `fn`
|
|
||||||
// returns truthy for. `fn` is invoked with two arguments: `key` and `value`.
|
|
||||||
// `key` is an int index if `x` is array. It returns undefined if `x` is not array.
|
|
||||||
filter: func(x, fn) {
|
|
||||||
if !is_array_like(x) { return undefined }
|
|
||||||
|
|
||||||
dst := []
|
|
||||||
for k, v in x {
|
|
||||||
if fn(k, v) { dst = append(dst, v) }
|
|
||||||
}
|
|
||||||
|
|
||||||
return dst
|
|
||||||
},
|
|
||||||
// find iterates over elements of `x`, returning value of the first element `fn`
|
|
||||||
// returns truthy for. `fn` is invoked with two arguments: `key` and `value`.
|
|
||||||
// `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.
|
|
||||||
find: func(x, fn) {
|
|
||||||
if !is_enumerable(x) { return undefined }
|
|
||||||
|
|
||||||
for k, v in x {
|
|
||||||
if fn(k, v) { return v }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// find_key iterates over elements of `x`, returning key or index of the first
|
|
||||||
// element `fn` returns truthy for. `fn` is invoked with two arguments: `key`
|
|
||||||
// and `value`. `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.
|
|
||||||
find_key: func(x, fn) {
|
|
||||||
if !is_enumerable(x) { return undefined }
|
|
||||||
|
|
||||||
for k, v in x {
|
|
||||||
if fn(k, v) { return k }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// map creates an array of values by running each element in `x` through `fn`.
|
|
||||||
// `fn` is invoked with two arguments: `key` and `value`. `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.
|
|
||||||
map: func(x, fn) {
|
|
||||||
if !is_enumerable(x) { return undefined }
|
|
||||||
|
|
||||||
dst := []
|
|
||||||
for k, v in x {
|
|
||||||
dst = append(dst, fn(k, v))
|
|
||||||
}
|
|
||||||
|
|
||||||
return dst
|
|
||||||
},
|
|
||||||
// key returns the first argument.
|
|
||||||
key: func(k, _) { return k },
|
|
||||||
// value returns the second argument.
|
|
||||||
value: func(_, v) { return v }
|
|
||||||
}
|
|
179
stdlib/srcmod_enum.xgo
Normal file
179
stdlib/srcmod_enum.xgo
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
is_enumerable := func(x) {
|
||||||
|
return is_array(x) || is_map(x) || is_immutable_array(x) || is_immutable_map(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
is_array_like := func(x) {
|
||||||
|
return is_array(x) || is_immutable_array(x)
|
||||||
|
}
|
||||||
|
_swap := func(arr, left, right) {
|
||||||
|
if arr == undefined || len(arr) <= 1 || left < 0 || left >= len(arr) || right < 0 || right >= len(arr) || left >= right {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
temp := arr[right]
|
||||||
|
arr[right] = arr[left]
|
||||||
|
arr[left] = temp
|
||||||
|
}
|
||||||
|
|
||||||
|
_sort := func(arr, left, right, less) {
|
||||||
|
if arr == undefined || len(arr) <= 1 || left < 0 || left >= len(arr) || right < 0 || right >= len(arr) || left >= right {
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
idx := left
|
||||||
|
for i := left; i < right; i++ {
|
||||||
|
if less(arr[i], arr[right]) {
|
||||||
|
_swap(arr, idx, i)
|
||||||
|
idx++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_swap(arr, idx, right)
|
||||||
|
_sort(arr, left, idx-1, less)
|
||||||
|
_sort(arr, idx+1, right, less)
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
keys: func(x){
|
||||||
|
ret := []
|
||||||
|
for k, _ in x {
|
||||||
|
ret += [k]
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
},
|
||||||
|
values: func(x){
|
||||||
|
ret := []
|
||||||
|
for _, v in x {
|
||||||
|
ret += [v]
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
},
|
||||||
|
sort: func(arr, ...less) {
|
||||||
|
if !less {
|
||||||
|
less = func(a, b){
|
||||||
|
return a < b
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
less = less[0]
|
||||||
|
}
|
||||||
|
if arr == undefined || len(arr) <= 1 {
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
return _sort(arr, 0, len(arr)-1, less)
|
||||||
|
},
|
||||||
|
// all returns true if the given function `fn` evaluates to a truthy value on
|
||||||
|
// all of the items in `x`. It returns undefined if `x` is not enumerable.
|
||||||
|
all: func(x, fn) {
|
||||||
|
if !is_enumerable(x) { return undefined }
|
||||||
|
|
||||||
|
for k, v in x {
|
||||||
|
if !fn(k, v) { return false }
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
// any returns true if the given function `fn` evaluates to a truthy value on
|
||||||
|
// any of the items in `x`. It returns undefined if `x` is not enumerable.
|
||||||
|
any: func(x, fn) {
|
||||||
|
if !is_enumerable(x) { return undefined }
|
||||||
|
|
||||||
|
for k, v in x {
|
||||||
|
if fn(k, v) { return true }
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
// chunk returns an array of elements split into groups the length of size.
|
||||||
|
// If `x` can't be split evenly, the final chunk will be the remaining elements.
|
||||||
|
// It returns undefined if `x` is not array.
|
||||||
|
chunk: func(x, size) {
|
||||||
|
if !is_array_like(x) || !size { return undefined }
|
||||||
|
|
||||||
|
numElements := len(x)
|
||||||
|
if !numElements { return [] }
|
||||||
|
|
||||||
|
res := []
|
||||||
|
idx := 0
|
||||||
|
for idx < numElements {
|
||||||
|
res = append(res, x[idx:idx+size])
|
||||||
|
idx += size
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
},
|
||||||
|
// at returns an element at the given index (if `x` is array) or
|
||||||
|
// key (if `x` is map). It returns undefined if `x` is not enumerable.
|
||||||
|
at: func(x, key) {
|
||||||
|
if !is_enumerable(x) { return undefined }
|
||||||
|
|
||||||
|
if is_array_like(x) {
|
||||||
|
if !is_int(key) { return undefined }
|
||||||
|
} else {
|
||||||
|
if !is_string(key) { return undefined }
|
||||||
|
}
|
||||||
|
|
||||||
|
return x[key]
|
||||||
|
},
|
||||||
|
// each iterates over elements of `x` and invokes `fn` for each element. `fn` is
|
||||||
|
// invoked with two arguments: `key` and `value`. `key` is an int index
|
||||||
|
// if `x` is array. `key` is a string key if `x` is map. It does not iterate
|
||||||
|
// and returns undefined if `x` is not enumerable.
|
||||||
|
each: func(x, fn) {
|
||||||
|
if !is_enumerable(x) { return undefined }
|
||||||
|
|
||||||
|
for k, v in x {
|
||||||
|
fn(k, v)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// filter iterates over elements of `x`, returning an array of all elements `fn`
|
||||||
|
// returns truthy for. `fn` is invoked with two arguments: `key` and `value`.
|
||||||
|
// `key` is an int index if `x` is array. It returns undefined if `x` is not array.
|
||||||
|
filter: func(x, fn) {
|
||||||
|
if !is_array_like(x) { return undefined }
|
||||||
|
|
||||||
|
dst := []
|
||||||
|
for k, v in x {
|
||||||
|
if fn(k, v) { dst = append(dst, v) }
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst
|
||||||
|
},
|
||||||
|
// find iterates over elements of `x`, returning value of the first element `fn`
|
||||||
|
// returns truthy for. `fn` is invoked with two arguments: `key` and `value`.
|
||||||
|
// `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.
|
||||||
|
find: func(x, fn) {
|
||||||
|
if !is_enumerable(x) { return undefined }
|
||||||
|
|
||||||
|
for k, v in x {
|
||||||
|
if fn(k, v) { return v }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// find_key iterates over elements of `x`, returning key or index of the first
|
||||||
|
// element `fn` returns truthy for. `fn` is invoked with two arguments: `key`
|
||||||
|
// and `value`. `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.
|
||||||
|
find_key: func(x, fn) {
|
||||||
|
if !is_enumerable(x) { return undefined }
|
||||||
|
|
||||||
|
for k, v in x {
|
||||||
|
if fn(k, v) { return k }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// map creates an array of values by running each element in `x` through `fn`.
|
||||||
|
// `fn` is invoked with two arguments: `key` and `value`. `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.
|
||||||
|
map: func(x, fn) {
|
||||||
|
if !is_enumerable(x) { return undefined }
|
||||||
|
|
||||||
|
dst := []
|
||||||
|
for k, v in x {
|
||||||
|
dst = append(dst, fn(k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst
|
||||||
|
},
|
||||||
|
// key returns the first argument.
|
||||||
|
key: func(k, _) { return k },
|
||||||
|
// value returns the second argument.
|
||||||
|
value: func(_, v) { return v }
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ package stdlib
|
||||||
//go:generate go run gensrcmods.go
|
//go:generate go run gensrcmods.go
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AllModuleNames returns a list of all default module names.
|
// AllModuleNames returns a list of all default module names.
|
||||||
|
@ -20,8 +20,8 @@ func AllModuleNames() []string {
|
||||||
|
|
||||||
// GetModuleMap returns the module map that includes all modules
|
// GetModuleMap returns the module map that includes all modules
|
||||||
// for the given module names.
|
// for the given module names.
|
||||||
func GetModuleMap(names ...string) *tengo.ModuleMap {
|
func GetModuleMap(names ...string) *xgo.ModuleMap {
|
||||||
modules := tengo.NewModuleMap()
|
modules := xgo.NewModuleMap()
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
if mod := BuiltinModules[name]; mod != nil {
|
if mod := BuiltinModules[name]; mod != nil {
|
||||||
modules.AddBuiltinModule(name, mod)
|
modules.AddBuiltinModule(name, mod)
|
||||||
|
|
|
@ -5,9 +5,9 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
"github.com/d5/tengo/v2/require"
|
"surdeus.su/core/xgo/v2/require"
|
||||||
"github.com/d5/tengo/v2/stdlib"
|
"surdeus.su/core/xgo/v2/stdlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ARR = []interface{}
|
type ARR = []interface{}
|
||||||
|
@ -105,20 +105,20 @@ func (c callres) call(funcName string, args ...interface{}) callres {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
var oargs []tengo.Object
|
var oargs []xgo.Object
|
||||||
for _, v := range args {
|
for _, v := range args {
|
||||||
oargs = append(oargs, object(v))
|
oargs = append(oargs, object(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
switch o := c.o.(type) {
|
switch o := c.o.(type) {
|
||||||
case *tengo.BuiltinModule:
|
case *xgo.BuiltinModule:
|
||||||
m, ok := o.Attrs[funcName]
|
m, ok := o.Attrs[funcName]
|
||||||
if !ok {
|
if !ok {
|
||||||
return callres{t: c.t, e: fmt.Errorf(
|
return callres{t: c.t, e: fmt.Errorf(
|
||||||
"function not found: %s", funcName)}
|
"function not found: %s", funcName)}
|
||||||
}
|
}
|
||||||
|
|
||||||
f, ok := m.(*tengo.UserFunction)
|
f, ok := m.(*xgo.UserFunction)
|
||||||
if !ok {
|
if !ok {
|
||||||
return callres{t: c.t, e: fmt.Errorf(
|
return callres{t: c.t, e: fmt.Errorf(
|
||||||
"non-callable: %s", funcName)}
|
"non-callable: %s", funcName)}
|
||||||
|
@ -126,16 +126,16 @@ func (c callres) call(funcName string, args ...interface{}) callres {
|
||||||
|
|
||||||
res, err := f.Value(oargs...)
|
res, err := f.Value(oargs...)
|
||||||
return callres{t: c.t, o: res, e: err}
|
return callres{t: c.t, o: res, e: err}
|
||||||
case *tengo.UserFunction:
|
case *xgo.UserFunction:
|
||||||
res, err := o.Value(oargs...)
|
res, err := o.Value(oargs...)
|
||||||
return callres{t: c.t, o: res, e: err}
|
return callres{t: c.t, o: res, e: err}
|
||||||
case *tengo.ImmutableMap:
|
case *xgo.ImmutableMap:
|
||||||
m, ok := o.Value[funcName]
|
m, ok := o.Value[funcName]
|
||||||
if !ok {
|
if !ok {
|
||||||
return callres{t: c.t, e: fmt.Errorf("function not found: %s", funcName)}
|
return callres{t: c.t, e: fmt.Errorf("function not found: %s", funcName)}
|
||||||
}
|
}
|
||||||
|
|
||||||
f, ok := m.(*tengo.UserFunction)
|
f, ok := m.(*xgo.UserFunction)
|
||||||
if !ok {
|
if !ok {
|
||||||
return callres{t: c.t, e: fmt.Errorf("non-callable: %s", funcName)}
|
return callres{t: c.t, e: fmt.Errorf("non-callable: %s", funcName)}
|
||||||
}
|
}
|
||||||
|
@ -165,73 +165,73 @@ func module(t *testing.T, moduleName string) callres {
|
||||||
return callres{t: t, o: mod}
|
return callres{t: t, o: mod}
|
||||||
}
|
}
|
||||||
|
|
||||||
func object(v interface{}) tengo.Object {
|
func object(v interface{}) xgo.Object {
|
||||||
switch v := v.(type) {
|
switch v := v.(type) {
|
||||||
case tengo.Object:
|
case xgo.Object:
|
||||||
return v
|
return v
|
||||||
case string:
|
case string:
|
||||||
return &tengo.String{Value: v}
|
return &xgo.String{Value: v}
|
||||||
case int64:
|
case int64:
|
||||||
return &tengo.Int{Value: v}
|
return &xgo.Int{Value: v}
|
||||||
case int: // for convenience
|
case int: // for convenience
|
||||||
return &tengo.Int{Value: int64(v)}
|
return &xgo.Int{Value: int64(v)}
|
||||||
case bool:
|
case bool:
|
||||||
if v {
|
if v {
|
||||||
return tengo.TrueValue
|
return xgo.TrueValue
|
||||||
}
|
}
|
||||||
return tengo.FalseValue
|
return xgo.FalseValue
|
||||||
case rune:
|
case rune:
|
||||||
return &tengo.Char{Value: v}
|
return &xgo.Char{Value: v}
|
||||||
case byte: // for convenience
|
case byte: // for convenience
|
||||||
return &tengo.Char{Value: rune(v)}
|
return &xgo.Char{Value: rune(v)}
|
||||||
case float64:
|
case float64:
|
||||||
return &tengo.Float{Value: v}
|
return &xgo.Float{Value: v}
|
||||||
case []byte:
|
case []byte:
|
||||||
return &tengo.Bytes{Value: v}
|
return &xgo.Bytes{Value: v}
|
||||||
case MAP:
|
case MAP:
|
||||||
objs := make(map[string]tengo.Object)
|
objs := make(map[string]xgo.Object)
|
||||||
for k, v := range v {
|
for k, v := range v {
|
||||||
objs[k] = object(v)
|
objs[k] = object(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &tengo.Map{Value: objs}
|
return &xgo.Map{Value: objs}
|
||||||
case ARR:
|
case ARR:
|
||||||
var objs []tengo.Object
|
var objs []xgo.Object
|
||||||
for _, e := range v {
|
for _, e := range v {
|
||||||
objs = append(objs, object(e))
|
objs = append(objs, object(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
return &tengo.Array{Value: objs}
|
return &xgo.Array{Value: objs}
|
||||||
case IMAP:
|
case IMAP:
|
||||||
objs := make(map[string]tengo.Object)
|
objs := make(map[string]xgo.Object)
|
||||||
for k, v := range v {
|
for k, v := range v {
|
||||||
objs[k] = object(v)
|
objs[k] = object(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &tengo.ImmutableMap{Value: objs}
|
return &xgo.ImmutableMap{Value: objs}
|
||||||
case IARR:
|
case IARR:
|
||||||
var objs []tengo.Object
|
var objs []xgo.Object
|
||||||
for _, e := range v {
|
for _, e := range v {
|
||||||
objs = append(objs, object(e))
|
objs = append(objs, object(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
return &tengo.ImmutableArray{Value: objs}
|
return &xgo.ImmutableArray{Value: objs}
|
||||||
case time.Time:
|
case time.Time:
|
||||||
return &tengo.Time{Value: v}
|
return &xgo.Time{Value: v}
|
||||||
case []int:
|
case []int:
|
||||||
var objs []tengo.Object
|
var objs []xgo.Object
|
||||||
for _, e := range v {
|
for _, e := range v {
|
||||||
objs = append(objs, &tengo.Int{Value: int64(e)})
|
objs = append(objs, &xgo.Int{Value: int64(e)})
|
||||||
}
|
}
|
||||||
|
|
||||||
return &tengo.Array{Value: objs}
|
return &xgo.Array{Value: objs}
|
||||||
}
|
}
|
||||||
|
|
||||||
panic(fmt.Errorf("unknown type: %T", v))
|
panic(fmt.Errorf("unknown type: %T", v))
|
||||||
}
|
}
|
||||||
|
|
||||||
func expect(t *testing.T, input string, expected interface{}) {
|
func expect(t *testing.T, input string, expected interface{}) {
|
||||||
s := tengo.NewScript([]byte(input))
|
s := xgo.NewScript([]byte(input))
|
||||||
s.SetImports(stdlib.GetModuleMap(stdlib.AllModuleNames()...))
|
s.SetImports(stdlib.GetModuleMap(stdlib.AllModuleNames()...))
|
||||||
c, err := s.Run()
|
c, err := s.Run()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
446
stdlib/text.go
446
stdlib/text.go
File diff suppressed because it is too large
Load diff
|
@ -3,26 +3,26 @@ package stdlib
|
||||||
import (
|
import (
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeTextRegexp(re *regexp.Regexp) *tengo.ImmutableMap {
|
func makeTextRegexp(re *regexp.Regexp) *xgo.ImmutableMap {
|
||||||
return &tengo.ImmutableMap{
|
return &xgo.ImmutableMap{
|
||||||
Value: map[string]tengo.Object{
|
Value: map[string]xgo.Object{
|
||||||
// match(text) => bool
|
// match(text) => bool
|
||||||
"match": &tengo.UserFunction{
|
"match": &xgo.UserFunction{
|
||||||
Value: func(args ...tengo.Object) (
|
Value: func(args ...xgo.Object) (
|
||||||
ret tengo.Object,
|
ret xgo.Object,
|
||||||
err error,
|
err error,
|
||||||
) {
|
) {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
err = tengo.ErrWrongNumArguments
|
err = xgo.ErrWrongNumArguments
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s1, ok := tengo.ToString(args[0])
|
s1, ok := xgo.ToString(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
err = tengo.ErrInvalidArgumentType{
|
err = xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -31,9 +31,9 @@ func makeTextRegexp(re *regexp.Regexp) *tengo.ImmutableMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
if re.MatchString(s1) {
|
if re.MatchString(s1) {
|
||||||
ret = tengo.TrueValue
|
ret = xgo.TrueValue
|
||||||
} else {
|
} else {
|
||||||
ret = tengo.FalseValue
|
ret = xgo.FalseValue
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -42,20 +42,20 @@ func makeTextRegexp(re *regexp.Regexp) *tengo.ImmutableMap {
|
||||||
|
|
||||||
// find(text) => array(array({text:,begin:,end:}))/undefined
|
// find(text) => array(array({text:,begin:,end:}))/undefined
|
||||||
// find(text, maxCount) => array(array({text:,begin:,end:}))/undefined
|
// find(text, maxCount) => array(array({text:,begin:,end:}))/undefined
|
||||||
"find": &tengo.UserFunction{
|
"find": &xgo.UserFunction{
|
||||||
Value: func(args ...tengo.Object) (
|
Value: func(args ...xgo.Object) (
|
||||||
ret tengo.Object,
|
ret xgo.Object,
|
||||||
err error,
|
err error,
|
||||||
) {
|
) {
|
||||||
numArgs := len(args)
|
numArgs := len(args)
|
||||||
if numArgs != 1 && numArgs != 2 {
|
if numArgs != 1 && numArgs != 2 {
|
||||||
err = tengo.ErrWrongNumArguments
|
err = xgo.ErrWrongNumArguments
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s1, ok := tengo.ToString(args[0])
|
s1, ok := xgo.ToString(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
err = tengo.ErrInvalidArgumentType{
|
err = xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -66,35 +66,35 @@ func makeTextRegexp(re *regexp.Regexp) *tengo.ImmutableMap {
|
||||||
if numArgs == 1 {
|
if numArgs == 1 {
|
||||||
m := re.FindStringSubmatchIndex(s1)
|
m := re.FindStringSubmatchIndex(s1)
|
||||||
if m == nil {
|
if m == nil {
|
||||||
ret = tengo.UndefinedValue
|
ret = xgo.UndefinedValue
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
arr := &tengo.Array{}
|
arr := &xgo.Array{}
|
||||||
for i := 0; i < len(m); i += 2 {
|
for i := 0; i < len(m); i += 2 {
|
||||||
arr.Value = append(arr.Value,
|
arr.Value = append(arr.Value,
|
||||||
&tengo.ImmutableMap{
|
&xgo.ImmutableMap{
|
||||||
Value: map[string]tengo.Object{
|
Value: map[string]xgo.Object{
|
||||||
"text": &tengo.String{
|
"text": &xgo.String{
|
||||||
Value: s1[m[i]:m[i+1]],
|
Value: s1[m[i]:m[i+1]],
|
||||||
},
|
},
|
||||||
"begin": &tengo.Int{
|
"begin": &xgo.Int{
|
||||||
Value: int64(m[i]),
|
Value: int64(m[i]),
|
||||||
},
|
},
|
||||||
"end": &tengo.Int{
|
"end": &xgo.Int{
|
||||||
Value: int64(m[i+1]),
|
Value: int64(m[i+1]),
|
||||||
},
|
},
|
||||||
}})
|
}})
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = &tengo.Array{Value: []tengo.Object{arr}}
|
ret = &xgo.Array{Value: []xgo.Object{arr}}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
i2, ok := tengo.ToInt(args[1])
|
i2, ok := xgo.ToInt(args[1])
|
||||||
if !ok {
|
if !ok {
|
||||||
err = tengo.ErrInvalidArgumentType{
|
err = xgo.ErrInvalidArgumentType{
|
||||||
Name: "second",
|
Name: "second",
|
||||||
Expected: "int(compatible)",
|
Expected: "int(compatible)",
|
||||||
Found: args[1].TypeName(),
|
Found: args[1].TypeName(),
|
||||||
|
@ -103,24 +103,24 @@ func makeTextRegexp(re *regexp.Regexp) *tengo.ImmutableMap {
|
||||||
}
|
}
|
||||||
m := re.FindAllStringSubmatchIndex(s1, i2)
|
m := re.FindAllStringSubmatchIndex(s1, i2)
|
||||||
if m == nil {
|
if m == nil {
|
||||||
ret = tengo.UndefinedValue
|
ret = xgo.UndefinedValue
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
arr := &tengo.Array{}
|
arr := &xgo.Array{}
|
||||||
for _, m := range m {
|
for _, m := range m {
|
||||||
subMatch := &tengo.Array{}
|
subMatch := &xgo.Array{}
|
||||||
for i := 0; i < len(m); i += 2 {
|
for i := 0; i < len(m); i += 2 {
|
||||||
subMatch.Value = append(subMatch.Value,
|
subMatch.Value = append(subMatch.Value,
|
||||||
&tengo.ImmutableMap{
|
&xgo.ImmutableMap{
|
||||||
Value: map[string]tengo.Object{
|
Value: map[string]xgo.Object{
|
||||||
"text": &tengo.String{
|
"text": &xgo.String{
|
||||||
Value: s1[m[i]:m[i+1]],
|
Value: s1[m[i]:m[i+1]],
|
||||||
},
|
},
|
||||||
"begin": &tengo.Int{
|
"begin": &xgo.Int{
|
||||||
Value: int64(m[i]),
|
Value: int64(m[i]),
|
||||||
},
|
},
|
||||||
"end": &tengo.Int{
|
"end": &xgo.Int{
|
||||||
Value: int64(m[i+1]),
|
Value: int64(m[i+1]),
|
||||||
},
|
},
|
||||||
}})
|
}})
|
||||||
|
@ -136,19 +136,19 @@ func makeTextRegexp(re *regexp.Regexp) *tengo.ImmutableMap {
|
||||||
},
|
},
|
||||||
|
|
||||||
// replace(src, repl) => string
|
// replace(src, repl) => string
|
||||||
"replace": &tengo.UserFunction{
|
"replace": &xgo.UserFunction{
|
||||||
Value: func(args ...tengo.Object) (
|
Value: func(args ...xgo.Object) (
|
||||||
ret tengo.Object,
|
ret xgo.Object,
|
||||||
err error,
|
err error,
|
||||||
) {
|
) {
|
||||||
if len(args) != 2 {
|
if len(args) != 2 {
|
||||||
err = tengo.ErrWrongNumArguments
|
err = xgo.ErrWrongNumArguments
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s1, ok := tengo.ToString(args[0])
|
s1, ok := xgo.ToString(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
err = tengo.ErrInvalidArgumentType{
|
err = xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -156,9 +156,9 @@ func makeTextRegexp(re *regexp.Regexp) *tengo.ImmutableMap {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s2, ok := tengo.ToString(args[1])
|
s2, ok := xgo.ToString(args[1])
|
||||||
if !ok {
|
if !ok {
|
||||||
err = tengo.ErrInvalidArgumentType{
|
err = xgo.ErrInvalidArgumentType{
|
||||||
Name: "second",
|
Name: "second",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[1].TypeName(),
|
Found: args[1].TypeName(),
|
||||||
|
@ -168,10 +168,10 @@ func makeTextRegexp(re *regexp.Regexp) *tengo.ImmutableMap {
|
||||||
|
|
||||||
s, ok := doTextRegexpReplace(re, s1, s2)
|
s, ok := doTextRegexpReplace(re, s1, s2)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, tengo.ErrStringLimit
|
return nil, xgo.ErrStringLimit
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = &tengo.String{Value: s}
|
ret = &xgo.String{Value: s}
|
||||||
|
|
||||||
return
|
return
|
||||||
},
|
},
|
||||||
|
@ -179,20 +179,20 @@ func makeTextRegexp(re *regexp.Regexp) *tengo.ImmutableMap {
|
||||||
|
|
||||||
// split(text) => array(string)
|
// split(text) => array(string)
|
||||||
// split(text, maxCount) => array(string)
|
// split(text, maxCount) => array(string)
|
||||||
"split": &tengo.UserFunction{
|
"split": &xgo.UserFunction{
|
||||||
Value: func(args ...tengo.Object) (
|
Value: func(args ...xgo.Object) (
|
||||||
ret tengo.Object,
|
ret xgo.Object,
|
||||||
err error,
|
err error,
|
||||||
) {
|
) {
|
||||||
numArgs := len(args)
|
numArgs := len(args)
|
||||||
if numArgs != 1 && numArgs != 2 {
|
if numArgs != 1 && numArgs != 2 {
|
||||||
err = tengo.ErrWrongNumArguments
|
err = xgo.ErrWrongNumArguments
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s1, ok := tengo.ToString(args[0])
|
s1, ok := xgo.ToString(args[0])
|
||||||
if !ok {
|
if !ok {
|
||||||
err = tengo.ErrInvalidArgumentType{
|
err = xgo.ErrInvalidArgumentType{
|
||||||
Name: "first",
|
Name: "first",
|
||||||
Expected: "string(compatible)",
|
Expected: "string(compatible)",
|
||||||
Found: args[0].TypeName(),
|
Found: args[0].TypeName(),
|
||||||
|
@ -202,9 +202,9 @@ func makeTextRegexp(re *regexp.Regexp) *tengo.ImmutableMap {
|
||||||
|
|
||||||
var i2 = -1
|
var i2 = -1
|
||||||
if numArgs > 1 {
|
if numArgs > 1 {
|
||||||
i2, ok = tengo.ToInt(args[1])
|
i2, ok = xgo.ToInt(args[1])
|
||||||
if !ok {
|
if !ok {
|
||||||
err = tengo.ErrInvalidArgumentType{
|
err = xgo.ErrInvalidArgumentType{
|
||||||
Name: "second",
|
Name: "second",
|
||||||
Expected: "int(compatible)",
|
Expected: "int(compatible)",
|
||||||
Found: args[1].TypeName(),
|
Found: args[1].TypeName(),
|
||||||
|
@ -213,10 +213,10 @@ func makeTextRegexp(re *regexp.Regexp) *tengo.ImmutableMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
arr := &tengo.Array{}
|
arr := &xgo.Array{}
|
||||||
for _, s := range re.Split(s1, i2) {
|
for _, s := range re.Split(s1, i2) {
|
||||||
arr.Value = append(arr.Value,
|
arr.Value = append(arr.Value,
|
||||||
&tengo.String{Value: s})
|
&xgo.String{Value: s})
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = arr
|
ret = arr
|
||||||
|
@ -235,14 +235,14 @@ func doTextRegexpReplace(re *regexp.Regexp, src, repl string) (string, bool) {
|
||||||
for _, m := range re.FindAllStringSubmatchIndex(src, -1) {
|
for _, m := range re.FindAllStringSubmatchIndex(src, -1) {
|
||||||
var exp []byte
|
var exp []byte
|
||||||
exp = re.ExpandString(exp, repl, src, m)
|
exp = re.ExpandString(exp, repl, src, m)
|
||||||
if len(out)+m[0]-idx+len(exp) > tengo.MaxStringLen {
|
if len(out)+m[0]-idx+len(exp) > xgo.MaxStringLen {
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
out += src[idx:m[0]] + string(exp)
|
out += src[idx:m[0]] + string(exp)
|
||||||
idx = m[1]
|
idx = m[1]
|
||||||
}
|
}
|
||||||
if idx < len(src) {
|
if idx < len(src) {
|
||||||
if len(out)+len(src)-idx > tengo.MaxStringLen {
|
if len(out)+len(src)-idx > xgo.MaxStringLen {
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
out += src[idx:]
|
out += src[idx:]
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTextRE(t *testing.T) {
|
func TestTextRE(t *testing.T) {
|
||||||
|
@ -33,7 +33,7 @@ func TestTextRE(t *testing.T) {
|
||||||
text string
|
text string
|
||||||
expected interface{}
|
expected interface{}
|
||||||
}{
|
}{
|
||||||
{"a(b)", "", tengo.UndefinedValue},
|
{"a(b)", "", xgo.UndefinedValue},
|
||||||
{"a(b)", "ab", ARR{
|
{"a(b)", "ab", ARR{
|
||||||
ARR{
|
ARR{
|
||||||
IMAP{"text": "ab", "begin": 0, "end": 2},
|
IMAP{"text": "ab", "begin": 0, "end": 2},
|
||||||
|
@ -67,7 +67,7 @@ func TestTextRE(t *testing.T) {
|
||||||
count int
|
count int
|
||||||
expected interface{}
|
expected interface{}
|
||||||
}{
|
}{
|
||||||
{"a(b)", "", -1, tengo.UndefinedValue},
|
{"a(b)", "", -1, xgo.UndefinedValue},
|
||||||
{"a(b)", "ab", -1, ARR{
|
{"a(b)", "ab", -1, ARR{
|
||||||
ARR{
|
ARR{
|
||||||
IMAP{"text": "ab", "begin": 0, "end": 2},
|
IMAP{"text": "ab", "begin": 0, "end": 2},
|
||||||
|
@ -96,7 +96,7 @@ func TestTextRE(t *testing.T) {
|
||||||
IMAP{"text": "c", "begin": 9, "end": 10},
|
IMAP{"text": "c", "begin": 9, "end": 10},
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
{"(a)b(c)d", "abcdefgabcd", 0, tengo.UndefinedValue},
|
{"(a)b(c)d", "abcdefgabcd", 0, xgo.UndefinedValue},
|
||||||
{"(a)b(c)d", "abcdefgabcd", 1, ARR{
|
{"(a)b(c)d", "abcdefgabcd", 1, ARR{
|
||||||
ARR{
|
ARR{
|
||||||
IMAP{"text": "abcd", "begin": 0, "end": 4},
|
IMAP{"text": "abcd", "begin": 0, "end": 4},
|
||||||
|
@ -232,9 +232,9 @@ func TestText(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReplaceLimit(t *testing.T) {
|
func TestReplaceLimit(t *testing.T) {
|
||||||
curMaxStringLen := tengo.MaxStringLen
|
curMaxStringLen := xgo.MaxStringLen
|
||||||
defer func() { tengo.MaxStringLen = curMaxStringLen }()
|
defer func() { xgo.MaxStringLen = curMaxStringLen }()
|
||||||
tengo.MaxStringLen = 12
|
xgo.MaxStringLen = 12
|
||||||
|
|
||||||
module(t, "text").call("replace", "123456789012", "1", "x", -1).
|
module(t, "text").call("replace", "123456789012", "1", "x", -1).
|
||||||
expect("x234567890x2")
|
expect("x234567890x2")
|
||||||
|
@ -264,9 +264,9 @@ func TestReplaceLimit(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTextRepeat(t *testing.T) {
|
func TestTextRepeat(t *testing.T) {
|
||||||
curMaxStringLen := tengo.MaxStringLen
|
curMaxStringLen := xgo.MaxStringLen
|
||||||
defer func() { tengo.MaxStringLen = curMaxStringLen }()
|
defer func() { xgo.MaxStringLen = curMaxStringLen }()
|
||||||
tengo.MaxStringLen = 12
|
xgo.MaxStringLen = 12
|
||||||
|
|
||||||
module(t, "text").call("repeat", "1234", "3").
|
module(t, "text").call("repeat", "1234", "3").
|
||||||
expect("123412341234")
|
expect("123412341234")
|
||||||
|
|
608
stdlib/times.go
608
stdlib/times.go
File diff suppressed because it is too large
Load diff
|
@ -4,8 +4,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
"github.com/d5/tengo/v2/require"
|
"surdeus.su/core/xgo/v2/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTimes(t *testing.T) {
|
func TestTimes(t *testing.T) {
|
||||||
|
@ -14,14 +14,14 @@ func TestTimes(t *testing.T) {
|
||||||
location, _ := time.LoadLocation("Pacific/Auckland")
|
location, _ := time.LoadLocation("Pacific/Auckland")
|
||||||
time3 := time.Date(1982, 9, 28, 19, 21, 44, 999, location)
|
time3 := time.Date(1982, 9, 28, 19, 21, 44, 999, location)
|
||||||
|
|
||||||
module(t, "times").call("sleep", 1).expect(tengo.UndefinedValue)
|
module(t, "times").call("sleep", 1).expect(xgo.UndefinedValue)
|
||||||
|
|
||||||
require.True(t, module(t, "times").
|
require.True(t, module(t, "times").
|
||||||
call("since", time.Now().Add(-time.Hour)).
|
call("since", time.Now().Add(-time.Hour)).
|
||||||
o.(*tengo.Int).Value > 3600000000000)
|
o.(*xgo.Int).Value > 3600000000000)
|
||||||
require.True(t, module(t, "times").
|
require.True(t, module(t, "times").
|
||||||
call("until", time.Now().Add(time.Hour)).
|
call("until", time.Now().Add(time.Hour)).
|
||||||
o.(*tengo.Int).Value < 3600000000000)
|
o.(*xgo.Int).Value < 3600000000000)
|
||||||
|
|
||||||
module(t, "times").call("parse_duration", "1ns").expect(1)
|
module(t, "times").call("parse_duration", "1ns").expect(1)
|
||||||
module(t, "times").call("parse_duration", "1ms").expect(1000000)
|
module(t, "times").call("parse_duration", "1ms").expect(1000000)
|
||||||
|
@ -41,7 +41,7 @@ func TestTimes(t *testing.T) {
|
||||||
expect(time3)
|
expect(time3)
|
||||||
|
|
||||||
nowD := time.Until(module(t, "times").call("now").
|
nowD := time.Until(module(t, "times").call("now").
|
||||||
o.(*tengo.Time).Value).Nanoseconds()
|
o.(*xgo.Time).Value).Nanoseconds()
|
||||||
require.True(t, 0 > nowD && nowD > -100000000) // within 100ms
|
require.True(t, 0 > nowD && nowD > -100000000) // within 100ms
|
||||||
parsed, _ := time.Parse(time.RFC3339, "1982-09-28T19:21:44+07:00")
|
parsed, _ := time.Parse(time.RFC3339, "1982-09-28T19:21:44+07:00")
|
||||||
module(t, "times").
|
module(t, "times").
|
||||||
|
|
77
stdlib/url/url.go
Normal file
77
stdlib/url/url.go
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
package url
|
||||||
|
|
||||||
|
import (
|
||||||
|
"surdeus.su/core/xgo/v2"
|
||||||
|
"net/url"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = xgo.Object(&Values{})
|
||||||
|
|
||||||
|
type Values struct {
|
||||||
|
xgo.ObjectImpl
|
||||||
|
url.Values
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vs *Values) TypeName() string {
|
||||||
|
return "*url.Values"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vs *Values) String() string {
|
||||||
|
return fmt.Sprintf("%v", vs.Values)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vs *Values) IndexGet(
|
||||||
|
index xgo.Object,
|
||||||
|
) (xgo.Object, error) {
|
||||||
|
key, ok := xgo.ToString(index)
|
||||||
|
if !ok {
|
||||||
|
return nil, xgo.ErrInvalidIndexValueType
|
||||||
|
}
|
||||||
|
|
||||||
|
val, ok := vs.Values[key]
|
||||||
|
if !ok {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
arr := make([]xgo.Object, len(val))
|
||||||
|
for i, v := range val {
|
||||||
|
arr[i], _ = xgo.FromInterface(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &xgo.Array{Value: arr}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type URL struct {
|
||||||
|
xgo.ObjectImpl
|
||||||
|
*url.URL
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *URL) TypeName() string {
|
||||||
|
return "<URL>"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *URL) String() string {
|
||||||
|
return u.URL.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *URL) IndexGet(
|
||||||
|
index xgo.Object,
|
||||||
|
) (xgo.Object, error) {
|
||||||
|
key, ok := xgo.ToString(index)
|
||||||
|
if !ok {
|
||||||
|
return nil, xgo.ErrInvalidIndexValueType
|
||||||
|
}
|
||||||
|
|
||||||
|
switch key {
|
||||||
|
case "path":
|
||||||
|
return xgo.FromInterface(u.Path)
|
||||||
|
case "query":
|
||||||
|
return &Values{
|
||||||
|
Values: u.Query(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nothing found.
|
||||||
|
return nil, nil
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package tengo
|
package xgo
|
||||||
|
|
||||||
// SymbolScope represents a symbol scope.
|
// SymbolScope represents a symbol scope.
|
||||||
type SymbolScope string
|
type SymbolScope string
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package tengo_test
|
package xgo_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
"github.com/d5/tengo/v2/require"
|
"surdeus.su/core/xgo/v2/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSymbolTable(t *testing.T) {
|
func TestSymbolTable(t *testing.T) {
|
||||||
|
|
4
tengo.go
4
tengo.go
|
@ -1,4 +1,4 @@
|
||||||
package tengo
|
package xgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -28,7 +28,7 @@ const (
|
||||||
MaxFrames = 1024
|
MaxFrames = 1024
|
||||||
|
|
||||||
// SourceFileExtDefault is the default extension for source files.
|
// SourceFileExtDefault is the default extension for source files.
|
||||||
SourceFileExtDefault = ".tengo"
|
SourceFileExtDefault = ".xgo"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CallableFunc is a function signature for the callable functions.
|
// CallableFunc is a function signature for the callable functions.
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package tengo_test
|
package xgo_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
"github.com/d5/tengo/v2/parser"
|
"surdeus.su/core/xgo/v2/parser"
|
||||||
"github.com/d5/tengo/v2/require"
|
"surdeus.su/core/xgo/v2/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestInstructions_String(t *testing.T) {
|
func TestInstructions_String(t *testing.T) {
|
||||||
|
|
22
testdata/libs/array.tengo
vendored
Normal file
22
testdata/libs/array.tengo
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
enum := import("enumx")
|
||||||
|
fmt := import("log")
|
||||||
|
|
||||||
|
object := {
|
||||||
|
key1: "cock",
|
||||||
|
key2: "dick",
|
||||||
|
key3: "check",
|
||||||
|
key4: "die",
|
||||||
|
key5: "wasd"
|
||||||
|
}
|
||||||
|
keys := enum.keys(object)
|
||||||
|
values := enum.values(object)
|
||||||
|
|
||||||
|
sorted_values := enum.sort(values, func(a, b){
|
||||||
|
return b < a
|
||||||
|
})
|
||||||
|
|
||||||
|
ia := [5, 100, 531, 7537, 1, 2, -100, 1.535]
|
||||||
|
fmt.println(enum.sort(ia))
|
||||||
|
fmt.println(sorted_values)
|
||||||
|
|
||||||
|
|
20
testdata/libs/cjson.xgo
vendored
Normal file
20
testdata/libs/cjson.xgo
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
cjson := import("cjson")
|
||||||
|
fmt := import("fmt")
|
||||||
|
log := import("log")
|
||||||
|
dec := cjson.Decoder("<stdin>")
|
||||||
|
|
||||||
|
log.print("cock")
|
||||||
|
log.print("die")
|
||||||
|
|
||||||
|
log.println("some log")
|
||||||
|
for {
|
||||||
|
v := dec.decode()
|
||||||
|
if is_error(v) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if !v {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
log.println("got one more value")
|
||||||
|
fmt.println(v)
|
||||||
|
}
|
4
testdata/libs/data.cjson
vendored
Normal file
4
testdata/libs/data.cjson
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{"somename": {
|
||||||
|
"value": 1
|
||||||
|
}}
|
||||||
|
["array",135,"integers", 135, 135]
|
22
testdata/libs/dogs.xgo
vendored
Normal file
22
testdata/libs/dogs.xgo
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
objects := import("objects")
|
||||||
|
fmt := import("fmt")
|
||||||
|
|
||||||
|
new := func(name) {
|
||||||
|
ret := objects.new()
|
||||||
|
ret.name = name
|
||||||
|
|
||||||
|
ret.def("bark", func(self, n){
|
||||||
|
fmt.print(self.name, ": ")
|
||||||
|
for i:=0 ; i<n ; i++ {
|
||||||
|
fmt.print("BARK!")
|
||||||
|
}
|
||||||
|
fmt.println()
|
||||||
|
})
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export {
|
||||||
|
"new": new
|
||||||
|
}
|
27
testdata/libs/html.xgo
vendored
Normal file
27
testdata/libs/html.xgo
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
fmt := import("fmt")
|
||||||
|
http := import("http")
|
||||||
|
html := import("html").Renderer()
|
||||||
|
|
||||||
|
added := html.ul()
|
||||||
|
for i in [1, 2, 3, 4, 5] {
|
||||||
|
added.add(html.li().body(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.println(
|
||||||
|
html.html({
|
||||||
|
lang: "en"
|
||||||
|
}).body(
|
||||||
|
html.head().body(
|
||||||
|
html.link({
|
||||||
|
rel: "stylesheet",
|
||||||
|
href: "/web/main.css"
|
||||||
|
}).final()
|
||||||
|
),
|
||||||
|
html.body().body(
|
||||||
|
html.p().body(
|
||||||
|
">>>shit"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
added
|
||||||
|
)
|
||||||
|
)
|
19
testdata/libs/http.xgo
vendored
Normal file
19
testdata/libs/http.xgo
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
fmt := import("fmt")
|
||||||
|
http := import("http")
|
||||||
|
os := import("os")
|
||||||
|
|
||||||
|
resp := http.post_json(
|
||||||
|
"https://jsonplaceholder.typicode.com/posts", {
|
||||||
|
title: "Hello, World!",
|
||||||
|
body: "Checking shit out!",
|
||||||
|
userId: 1
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if is_error(resp) {
|
||||||
|
fmt.println(resp)
|
||||||
|
os.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
body := resp.body_json
|
||||||
|
fmt.println(body)
|
||||||
|
|
7
testdata/libs/import.xgo
vendored
Normal file
7
testdata/libs/import.xgo
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
fmt := import("fmt")
|
||||||
|
dogs := import("./tests/dogs")
|
||||||
|
|
||||||
|
dog := dogs.new("check")
|
||||||
|
//fmt.println(dog)
|
||||||
|
dog.bark(10)
|
||||||
|
|
8
testdata/libs/paths.xgo
vendored
Normal file
8
testdata/libs/paths.xgo
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
fmt := import("fmt")
|
||||||
|
paths := import("paths")
|
||||||
|
os := import("os")
|
||||||
|
|
||||||
|
for path in os.args()[2:] {
|
||||||
|
fmt.println(paths.base(path))
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package tengo
|
package xgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package tengo_test
|
package xgo_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
"github.com/d5/tengo/v2/require"
|
"surdeus.su/core/xgo/v2/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
type VariableTest struct {
|
type VariableTest struct {
|
||||||
|
|
6
vm.go
6
vm.go
|
@ -1,11 +1,11 @@
|
||||||
package tengo
|
package xgo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2/parser"
|
"surdeus.su/core/xgo/v2/parser"
|
||||||
"github.com/d5/tengo/v2/token"
|
"surdeus.su/core/xgo/v2/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
// frame represents a function call frame.
|
// frame represents a function call frame.
|
||||||
|
|
12
vm_test.go
12
vm_test.go
|
@ -1,4 +1,4 @@
|
||||||
package tengo_test
|
package xgo_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -10,11 +10,11 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/d5/tengo/v2"
|
"surdeus.su/core/xgo/v2"
|
||||||
"github.com/d5/tengo/v2/parser"
|
"surdeus.su/core/xgo/v2/parser"
|
||||||
"github.com/d5/tengo/v2/require"
|
"surdeus.su/core/xgo/v2/require"
|
||||||
"github.com/d5/tengo/v2/stdlib"
|
"surdeus.su/core/xgo/v2/stdlib"
|
||||||
"github.com/d5/tengo/v2/token"
|
"surdeus.su/core/xgo/v2/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
const testOut = "out"
|
const testOut = "out"
|
||||||
|
|
Loading…
Reference in a new issue