mirror of
				https://github.com/MontFerret/ferret.git
				synced 2025-10-30 23:37:40 +02:00 
			
		
		
		
	Added namespace builder (#336)
* Added namespace builder * Fixed linting issues * Added extra check * Updated e2e lib * Renamed NamespaceBuilder to NamespaceContainer and changed func receivers * Renamed NewLib to RegisterLib
This commit is contained in:
		| @@ -10,12 +10,16 @@ import ( | ||||
| 	"github.com/MontFerret/ferret/pkg/runtime/values" | ||||
| ) | ||||
|  | ||||
| func Assertions() map[string]core.Function { | ||||
| 	return map[string]core.Function{ | ||||
| 		"EXPECT":       expect, | ||||
| 		"T::EXPECT":    expect, | ||||
| 		"T::HTTP::GET": httpGet, | ||||
| 	} | ||||
| func HTTPHelpers(ns core.Namespace) error { | ||||
| 	return ns.RegisterFunctions(core.Functions{ | ||||
| 		"GET": httpGet, | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func Assertions(ns core.Namespace) error { | ||||
| 	return ns.RegisterFunctions(core.Functions{ | ||||
| 		"EXPECT": expect, | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func expect(_ context.Context, args ...core.Value) (core.Value, error) { | ||||
|   | ||||
| @@ -101,7 +101,18 @@ func (r *Runner) runQueries(ctx context.Context, dir string) ([]Result, error) { | ||||
|  | ||||
| 	c := compiler.New() | ||||
|  | ||||
| 	if err := c.RegisterFunctions(Assertions()); err != nil { | ||||
| 	// backward compatible | ||||
| 	if err := Assertions(c); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	ns := c.Namespace("T") | ||||
|  | ||||
| 	if err := Assertions(ns); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if err := HTTPHelpers(ns.Namespace("HTTP")); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -1,9 +1,6 @@ | ||||
| package compiler | ||||
|  | ||||
| import ( | ||||
| 	"regexp" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/MontFerret/ferret/pkg/parser" | ||||
| 	"github.com/MontFerret/ferret/pkg/runtime" | ||||
| 	"github.com/MontFerret/ferret/pkg/runtime/core" | ||||
| @@ -11,14 +8,15 @@ import ( | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| var fnNameValidation = regexp.MustCompile("^[a-zA-Z]+[a-zA-Z0-9_]*(::[a-zA-Z]+[a-zA-Z0-9_]*)*$") | ||||
|  | ||||
| type FqlCompiler struct { | ||||
| 	funcs map[string]core.Function | ||||
| 	*NamespaceContainer | ||||
| } | ||||
|  | ||||
| func New(setters ...Option) *FqlCompiler { | ||||
| 	c := &FqlCompiler{} | ||||
| 	c.NamespaceContainer = newRootNamespace() | ||||
| 	c.funcs = make(map[string]core.Function) | ||||
|  | ||||
| 	opts := &Options{} | ||||
|  | ||||
| 	for _, setter := range setters { | ||||
| @@ -26,67 +24,14 @@ func New(setters ...Option) *FqlCompiler { | ||||
| 	} | ||||
|  | ||||
| 	if !opts.noStdlib { | ||||
| 		c.funcs = stdlib.NewLib() | ||||
| 	} else { | ||||
| 		c.funcs = make(map[string]core.Function) | ||||
| 		if err := stdlib.RegisterLib(c.NamespaceContainer); err != nil { | ||||
| 			panic(err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return c | ||||
| } | ||||
|  | ||||
| func (c *FqlCompiler) RegisterFunction(name string, fun core.Function) error { | ||||
| 	_, exists := c.funcs[name] | ||||
|  | ||||
| 	if exists { | ||||
| 		return errors.Errorf("function already exists: %s", name) | ||||
| 	} | ||||
|  | ||||
| 	// validation the name | ||||
| 	if !fnNameValidation.MatchString(name) { | ||||
| 		return errors.Errorf("invalid function name: %s", name) | ||||
| 	} | ||||
|  | ||||
| 	c.funcs[strings.ToUpper(name)] = fun | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (c *FqlCompiler) RemoveFunction(name string) { | ||||
| 	delete(c.funcs, strings.ToUpper(name)) | ||||
| } | ||||
|  | ||||
| func (c *FqlCompiler) RegisterFunctions(funcs map[string]core.Function) error { | ||||
| 	for name, fun := range funcs { | ||||
| 		if err := c.RegisterFunction(name, fun); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (c *FqlCompiler) RegisteredFunctions() []string { | ||||
| 	res := make([]string, 0, len(c.funcs)) | ||||
|  | ||||
| 	for k := range c.funcs { | ||||
| 		res = append(res, k) | ||||
| 	} | ||||
|  | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| func (c *FqlCompiler) RegisteredFunctionsNS(namespace string) []string { | ||||
| 	res := make([]string, 0, len(c.funcs)) | ||||
|  | ||||
| 	for k := range c.funcs { | ||||
| 		if strings.HasPrefix(k, namespace) { | ||||
| 			res = append(res, k) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| func (c *FqlCompiler) Compile(query string) (program *runtime.Program, err error) { | ||||
| 	if query == "" { | ||||
| 		return nil, ErrEmptyQuery | ||||
|   | ||||
| @@ -14,7 +14,7 @@ func TestFunctionNSCall(t *testing.T) { | ||||
| 		c := compiler.New() | ||||
|  | ||||
| 		var counter int | ||||
| 		err := c.RegisterFunction("T::SPY", func(_ context.Context, _ ...core.Value) (core.Value, error) { | ||||
| 		err := c.Namespace("T").RegisterFunction("SPY", func(_ context.Context, _ ...core.Value) (core.Value, error) { | ||||
| 			counter++ | ||||
|  | ||||
| 			return values.None, nil | ||||
| @@ -39,7 +39,7 @@ func TestFunctionNSCall(t *testing.T) { | ||||
| 		c := compiler.New() | ||||
|  | ||||
| 		var counter int | ||||
| 		err := c.RegisterFunction("T::UTILS::SPY", func(_ context.Context, _ ...core.Value) (core.Value, error) { | ||||
| 		err := c.Namespace("T").Namespace("UTILS").RegisterFunction("SPY", func(_ context.Context, _ ...core.Value) (core.Value, error) { | ||||
| 			counter++ | ||||
|  | ||||
| 			return values.None, nil | ||||
| @@ -64,7 +64,7 @@ func TestFunctionNSCall(t *testing.T) { | ||||
| 		c := compiler.New() | ||||
|  | ||||
| 		var counter int | ||||
| 		err := c.RegisterFunction("T::UTILS::SPY", func(_ context.Context, _ ...core.Value) (core.Value, error) { | ||||
| 		err := c.Namespace("T").Namespace("UTILS").RegisterFunction("SPY", func(_ context.Context, _ ...core.Value) (core.Value, error) { | ||||
| 			counter++ | ||||
|  | ||||
| 			return values.None, nil | ||||
| @@ -78,17 +78,4 @@ func TestFunctionNSCall(t *testing.T) { | ||||
|  | ||||
| 		So(err, ShouldNotBeNil) | ||||
| 	}) | ||||
|  | ||||
| 	Convey("Should NOT register RETURN T:UTILS::SPY", t, func() { | ||||
| 		c := compiler.New() | ||||
|  | ||||
| 		var counter int | ||||
| 		err := c.RegisterFunction("T::UTILS:SPY", func(_ context.Context, _ ...core.Value) (core.Value, error) { | ||||
| 			counter++ | ||||
|  | ||||
| 			return values.None, nil | ||||
| 		}) | ||||
|  | ||||
| 		So(err, ShouldNotBeNil) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -34,7 +34,7 @@ func TestRegexpOperator(t *testing.T) { | ||||
|  | ||||
| 	Convey("Should be possible to use negative regular expression operator", t, func() { | ||||
| 		c := compiler.New() | ||||
| 		c.RegisterFunction("T::REGEXP", func(_ context.Context, _ ...core.Value) (value core.Value, e error) { | ||||
| 		c.Namespace("T").RegisterFunction("REGEXP", func(_ context.Context, _ ...core.Value) (value core.Value, e error) { | ||||
| 			return values.NewString("[a-z]+bar$"), nil | ||||
| 		}) | ||||
|  | ||||
|   | ||||
							
								
								
									
										97
									
								
								pkg/compiler/namespace.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								pkg/compiler/namespace.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,97 @@ | ||||
| package compiler | ||||
|  | ||||
| import ( | ||||
| 	"github.com/MontFerret/ferret/pkg/runtime/core" | ||||
| 	"github.com/pkg/errors" | ||||
| 	"regexp" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| var fnNameValidation = regexp.MustCompile("^[a-zA-Z]+[a-zA-Z0-9_]*(::[a-zA-Z]+[a-zA-Z0-9_]*)*$") | ||||
|  | ||||
| const emptyNS = "" | ||||
| const separator = "::" | ||||
|  | ||||
| type NamespaceContainer struct { | ||||
| 	funcs core.Functions | ||||
| 	name  string | ||||
| } | ||||
|  | ||||
| func newRootNamespace() *NamespaceContainer { | ||||
| 	ns := new(NamespaceContainer) | ||||
| 	ns.funcs = make(core.Functions) | ||||
|  | ||||
| 	return ns | ||||
| } | ||||
|  | ||||
| func newNamespace(funcs core.Functions, name string) *NamespaceContainer { | ||||
| 	return &NamespaceContainer{funcs, strings.ToUpper(name)} | ||||
| } | ||||
|  | ||||
| func (nc *NamespaceContainer) Namespace(name string) core.Namespace { | ||||
| 	return newNamespace(nc.funcs, nc.makeFullName(name)) | ||||
| } | ||||
|  | ||||
| func (nc *NamespaceContainer) RegisterFunction(name string, fun core.Function) error { | ||||
| 	nsName := nc.makeFullName(name) | ||||
| 	_, exists := nc.funcs[nsName] | ||||
|  | ||||
| 	if exists { | ||||
| 		return errors.Errorf("function already exists: %s", name) | ||||
| 	} | ||||
|  | ||||
| 	// validation the name | ||||
| 	if strings.Contains(name, separator) { | ||||
| 		return errors.Errorf("invalid function name: %s", name) | ||||
| 	} | ||||
|  | ||||
| 	if !fnNameValidation.MatchString(nsName) { | ||||
| 		return errors.Errorf("invalid function or namespace name: %s", nsName) | ||||
| 	} | ||||
|  | ||||
| 	nc.funcs[strings.ToUpper(nsName)] = fun | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (nc *NamespaceContainer) RemoveFunction(name string) { | ||||
| 	delete(nc.funcs, strings.ToUpper(nc.makeFullName(name))) | ||||
| } | ||||
|  | ||||
| func (nc *NamespaceContainer) RegisterFunctions(funcs core.Functions) error { | ||||
| 	for name, fun := range funcs { | ||||
| 		if err := nc.RegisterFunction(name, fun); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (nc *NamespaceContainer) RegisteredFunctions() []string { | ||||
| 	res := make([]string, 0, len(nc.funcs)) | ||||
|  | ||||
| 	// root namespace, return all functions | ||||
| 	if nc.name == emptyNS { | ||||
| 		for k := range nc.funcs { | ||||
| 			res = append(res, k) | ||||
| 		} | ||||
| 	} else { | ||||
| 		nsPrefix := nc.name + separator | ||||
| 		for k := range nc.funcs { | ||||
| 			if strings.HasPrefix(k, nsPrefix) { | ||||
| 				res = append(res, k) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return res | ||||
| } | ||||
|  | ||||
| func (nc *NamespaceContainer) makeFullName(name string) string { | ||||
| 	if nc.name == emptyNS { | ||||
| 		return name | ||||
| 	} | ||||
|  | ||||
| 	return nc.name + separator + name | ||||
| } | ||||
							
								
								
									
										96
									
								
								pkg/compiler/namespace_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								pkg/compiler/namespace_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| package compiler_test | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"github.com/MontFerret/ferret/pkg/compiler" | ||||
| 	"github.com/MontFerret/ferret/pkg/runtime/core" | ||||
| 	"github.com/MontFerret/ferret/pkg/runtime/values" | ||||
| 	. "github.com/smartystreets/goconvey/convey" | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
| func TestNamespaceBuilder(t *testing.T) { | ||||
| 	Convey("Namespaces", t, func() { | ||||
| 		Convey("Should return an error when a function name contains NS separator", func() { | ||||
| 			c := compiler.New() | ||||
| 			err := c.RegisterFunction("T::SPY", func(ctx context.Context, args ...core.Value) (value core.Value, e error) { | ||||
| 				return values.None, nil | ||||
| 			}) | ||||
|  | ||||
| 			So(err, ShouldNotBeNil) | ||||
| 		}) | ||||
|  | ||||
| 		Convey("Should successfully register a name within a namespace", func() { | ||||
| 			c := compiler.New() | ||||
| 			err := c.Namespace("T").RegisterFunction("SPY", func(ctx context.Context, args ...core.Value) (value core.Value, e error) { | ||||
| 				return values.None, nil | ||||
| 			}) | ||||
|  | ||||
| 			So(err, ShouldBeNil) | ||||
|  | ||||
| 			funcs := c.RegisteredFunctions() | ||||
|  | ||||
| 			var exists bool | ||||
|  | ||||
| 			for _, name := range funcs { | ||||
| 				exists = name == "T::SPY" | ||||
|  | ||||
| 				if exists { | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			So(exists, ShouldBeTrue) | ||||
| 		}) | ||||
|  | ||||
| 		Convey("Root namespace should return all registered functions", func() { | ||||
| 			c := compiler.New() | ||||
| 			err := c.Namespace("T").RegisterFunction("SPY", func(ctx context.Context, args ...core.Value) (value core.Value, e error) { | ||||
| 				return values.None, nil | ||||
| 			}) | ||||
|  | ||||
| 			So(err, ShouldBeNil) | ||||
|  | ||||
| 			funcs := c.RegisteredFunctions() | ||||
|  | ||||
| 			So(len(funcs), ShouldBeGreaterThan, 1) | ||||
| 		}) | ||||
|  | ||||
| 		Convey("Namespace should return all registered functions", func() { | ||||
| 			c := compiler.New() | ||||
| 			err := c.Namespace("T").RegisterFunction("SPY", func(ctx context.Context, args ...core.Value) (value core.Value, e error) { | ||||
| 				return values.None, nil | ||||
| 			}) | ||||
|  | ||||
| 			So(err, ShouldBeNil) | ||||
|  | ||||
| 			err = c.Namespace("T").Namespace("UTILS").RegisterFunction("SPY", func(ctx context.Context, args ...core.Value) (value core.Value, e error) { | ||||
| 				return values.None, nil | ||||
| 			}) | ||||
|  | ||||
| 			So(err, ShouldBeNil) | ||||
|  | ||||
| 			funcs := c.Namespace("T").RegisteredFunctions() | ||||
|  | ||||
| 			So(funcs, ShouldHaveLength, 2) | ||||
|  | ||||
| 			funcs2 := c.Namespace("T").Namespace("UTILS").RegisteredFunctions() | ||||
|  | ||||
| 			So(funcs2, ShouldHaveLength, 1) | ||||
| 		}) | ||||
|  | ||||
| 		Convey("Namespace should return an error if namespace name is incorrect", func() { | ||||
| 			c := compiler.New() | ||||
| 			noop := func(ctx context.Context, args ...core.Value) (value core.Value, e error) { | ||||
| 				return values.None, nil | ||||
| 			} | ||||
| 			err := c.Namespace("T::").RegisterFunction("SPY", noop) | ||||
|  | ||||
| 			So(err, ShouldNotBeNil) | ||||
|  | ||||
| 			err = c.Namespace("@F").RegisterFunction("SPY", noop) | ||||
|  | ||||
| 			So(err, ShouldNotBeNil) | ||||
| 		}) | ||||
| 	}) | ||||
| } | ||||
| @@ -7,7 +7,19 @@ import ( | ||||
|  | ||||
| const MaxArgs = 65536 | ||||
|  | ||||
| type Function = func(ctx context.Context, args ...Value) (Value, error) | ||||
| type ( | ||||
| 	Function = func(ctx context.Context, args ...Value) (Value, error) | ||||
|  | ||||
| 	Functions map[string]Function | ||||
|  | ||||
| 	Namespace interface { | ||||
| 		Namespace(name string) Namespace | ||||
| 		RegisterFunction(name string, fun Function) error | ||||
| 		RegisterFunctions(funs Functions) error | ||||
| 		RegisteredFunctions() []string | ||||
| 		RemoveFunction(name string) | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| func ValidateArgs(args []Value, minimum, maximum int) error { | ||||
| 	count := len(args) | ||||
|   | ||||
| @@ -5,8 +5,8 @@ import ( | ||||
| 	"github.com/MontFerret/ferret/pkg/runtime/values" | ||||
| ) | ||||
|  | ||||
| func NewLib() map[string]core.Function { | ||||
| 	return map[string]core.Function{ | ||||
| func RegisterLib(ns core.Namespace) error { | ||||
| 	return ns.RegisterFunctions(core.Functions{ | ||||
| 		"APPEND":         Append, | ||||
| 		"FIRST":          First, | ||||
| 		"FLATTEN":        Flatten, | ||||
| @@ -29,7 +29,7 @@ func NewLib() map[string]core.Function { | ||||
| 		"UNION_DISTINCT": UnionDistinct, | ||||
| 		"UNIQUE":         Unique, | ||||
| 		"UNSHIFT":        Unshift, | ||||
| 	} | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func ToUniqueArray(arr *values.Array) *values.Array { | ||||
|   | ||||
| @@ -2,9 +2,9 @@ package collections | ||||
|  | ||||
| import "github.com/MontFerret/ferret/pkg/runtime/core" | ||||
|  | ||||
| func NewLib() map[string]core.Function { | ||||
| 	return map[string]core.Function{ | ||||
| func RegisterLib(ns core.Namespace) error { | ||||
| 	return ns.RegisterFunctions(core.Functions{ | ||||
| 		"LENGTH":  Length, | ||||
| 		"REVERSE": Reverse, | ||||
| 	} | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -12,8 +12,8 @@ import ( | ||||
|  | ||||
| const defaultTimeout = 5000 | ||||
|  | ||||
| func NewLib() map[string]core.Function { | ||||
| 	return map[string]core.Function{ | ||||
| func RegisterLib(ns core.Namespace) error { | ||||
| 	return ns.RegisterFunctions(core.Functions{ | ||||
| 		"ATTR_GET":          AttributeGet, | ||||
| 		"ATTR_REMOVE":       AttributeRemove, | ||||
| 		"ATTR_SET":          AttributeSet, | ||||
| @@ -67,7 +67,7 @@ func NewLib() map[string]core.Function { | ||||
| 		"WAIT_NO_STYLE_ALL": WaitNoStyleAll, | ||||
| 		"WAIT_NAVIGATION":   WaitNavigation, | ||||
| 		"XPATH":             XPath, | ||||
| 	} | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func OpenOrCastPage(ctx context.Context, value core.Value) (drivers.HTMLPage, bool, error) { | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| package stdlib | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/MontFerret/ferret/pkg/runtime/core" | ||||
| 	"github.com/MontFerret/ferret/pkg/stdlib/arrays" | ||||
| 	"github.com/MontFerret/ferret/pkg/stdlib/collections" | ||||
| @@ -13,27 +12,34 @@ import ( | ||||
| 	"github.com/MontFerret/ferret/pkg/stdlib/utils" | ||||
| ) | ||||
|  | ||||
| func NewLib() map[string]core.Function { | ||||
| 	lib := make(map[string]core.Function) | ||||
|  | ||||
| 	add := func(l map[string]core.Function) { | ||||
| 		for name, fn := range l { | ||||
| 			if _, exists := lib[name]; exists { | ||||
| 				panic(fmt.Sprintf("%s function already exists", name)) | ||||
| 			} | ||||
|  | ||||
| 			lib[name] = fn | ||||
| 		} | ||||
| func RegisterLib(ns core.Namespace) error { | ||||
| 	if err := types.RegisterLib(ns); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	add(types.NewLib()) | ||||
| 	add(strings.NewLib()) | ||||
| 	add(math.NewLib()) | ||||
| 	add(collections.NewLib()) | ||||
| 	add(arrays.NewLib()) | ||||
| 	add(objects.NewLib()) | ||||
| 	add(html.NewLib()) | ||||
| 	add(utils.NewLib()) | ||||
| 	if err := strings.RegisterLib(ns); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	return lib | ||||
| 	if err := math.RegisterLib(ns); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if err := collections.RegisterLib(ns); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if err := arrays.RegisterLib(ns); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if err := objects.RegisterLib(ns); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if err := html.RegisterLib(ns); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	return utils.RegisterLib(ns) | ||||
| } | ||||
|   | ||||
| @@ -15,8 +15,8 @@ const ( | ||||
| 	GradToDeg = math.Pi / 200 | ||||
| ) | ||||
|  | ||||
| func NewLib() map[string]core.Function { | ||||
| 	return map[string]core.Function{ | ||||
| func RegisterLib(ns core.Namespace) error { | ||||
| 	return ns.RegisterFunctions(core.Functions{ | ||||
| 		"ABS":                 Abs, | ||||
| 		"ACOS":                Acos, | ||||
| 		"ASIN":                Asin, | ||||
| @@ -50,7 +50,7 @@ func NewLib() map[string]core.Function { | ||||
| 		"TAN":                 Tan, | ||||
| 		"VARIANCE_POPULATION": PopulationVariance, | ||||
| 		"VARIANCE_SAMPLE":     SampleVariance, | ||||
| 	} | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func toFloat(arg core.Value) float64 { | ||||
|   | ||||
| @@ -2,8 +2,8 @@ package objects | ||||
|  | ||||
| import "github.com/MontFerret/ferret/pkg/runtime/core" | ||||
|  | ||||
| func NewLib() map[string]core.Function { | ||||
| 	return map[string]core.Function{ | ||||
| func RegisterLib(ns core.Namespace) error { | ||||
| 	return ns.RegisterFunctions(core.Functions{ | ||||
| 		"HAS":             Has, | ||||
| 		"KEYS":            Keys, | ||||
| 		"KEEP_KEYS":       KeepKeys, | ||||
| @@ -11,5 +11,5 @@ func NewLib() map[string]core.Function { | ||||
| 		"ZIP":             Zip, | ||||
| 		"VALUES":          Values, | ||||
| 		"MERGE_RECURSIVE": MergeRecursive, | ||||
| 	} | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -2,8 +2,8 @@ package strings | ||||
|  | ||||
| import "github.com/MontFerret/ferret/pkg/runtime/core" | ||||
|  | ||||
| func NewLib() map[string]core.Function { | ||||
| 	return map[string]core.Function{ | ||||
| func RegisterLib(ns core.Namespace) error { | ||||
| 	return ns.RegisterFunctions(core.Functions{ | ||||
| 		"CONCAT":               Concat, | ||||
| 		"CONCAT_SEPARATOR":     ConcatWithSeparator, | ||||
| 		"CONTAINS":             Contains, | ||||
| @@ -37,5 +37,5 @@ func NewLib() map[string]core.Function { | ||||
| 		"UPPER":                Upper, | ||||
| 		"FMT":                  Fmt, | ||||
| 		"UNESCAPE_HTML":        UnescapeHTML, | ||||
| 	} | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -5,8 +5,8 @@ import ( | ||||
| 	"github.com/MontFerret/ferret/pkg/runtime/values" | ||||
| ) | ||||
|  | ||||
| func NewLib() map[string]core.Function { | ||||
| 	return map[string]core.Function{ | ||||
| func RegisterLib(ns core.Namespace) error { | ||||
| 	return ns.RegisterFunctions(core.Functions{ | ||||
| 		"TO_BOOL":          ToBool, | ||||
| 		"TO_INT":           ToInt, | ||||
| 		"TO_FLOAT":         ToFloat, | ||||
| @@ -26,7 +26,7 @@ func NewLib() map[string]core.Function { | ||||
| 		"IS_BINARY":        IsBinary, | ||||
| 		"IS_NAN":           IsNaN, | ||||
| 		"TYPENAME":         TypeName, | ||||
| 	} | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func isTypeof(value core.Value, ctype core.Type) core.Value { | ||||
|   | ||||
| @@ -2,9 +2,9 @@ package utils | ||||
|  | ||||
| import "github.com/MontFerret/ferret/pkg/runtime/core" | ||||
|  | ||||
| func NewLib() map[string]core.Function { | ||||
| 	return map[string]core.Function{ | ||||
| func RegisterLib(ns core.Namespace) error { | ||||
| 	return ns.RegisterFunctions(core.Functions{ | ||||
| 		"WAIT":  Wait, | ||||
| 		"PRINT": Print, | ||||
| 	} | ||||
| 	}) | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user