Compare commits
	
		
			No commits in common. "33d70d6d1a23c3d588122eacb5dbfc0b60d69917" and "29bc2c62a3c54cb41da0eac19e0acb5ce8d840ab" have entirely different histories.
		
	
	
		
			33d70d6d1a
			...
			29bc2c62a3
		
	
		
| @ -1,44 +0,0 @@ | |||||||
| // Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
 |  | ||||||
| // All rights reserved.
 |  | ||||||
| 
 |  | ||||||
| // function.go
 |  | ||||||
| package expr |  | ||||||
| 
 |  | ||||||
| // ---- Linking with Expr functions
 |  | ||||||
| type exprFunctor struct { |  | ||||||
| 	baseFunctor |  | ||||||
| 	params []ExprFuncParam |  | ||||||
| 	expr   Expr |  | ||||||
| 	defCtx ExprContext |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // func newExprFunctor(e Expr, params []string, ctx ExprContext) *exprFunctor {
 |  | ||||||
| // 	return &exprFunctor{expr: e, params: params, defCtx: ctx}
 |  | ||||||
| // }
 |  | ||||||
| 
 |  | ||||||
| func newExprFunctor(e Expr, params []ExprFuncParam, ctx ExprContext) *exprFunctor { |  | ||||||
| 	return &exprFunctor{expr: e, params: params, defCtx: ctx} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (functor *exprFunctor) Invoke(ctx ExprContext, name string, args []any) (result any, err error) { |  | ||||||
| 	if functor.defCtx != nil { |  | ||||||
| 		ctx.Merge(functor.defCtx) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for i, p := range functor.params { |  | ||||||
| 		if i < len(args) { |  | ||||||
| 			arg := args[i] |  | ||||||
| 			if funcArg, ok := arg.(Functor); ok { |  | ||||||
| 				// ctx.RegisterFunc(p, functor, 0, -1)
 |  | ||||||
| 				paramSpecs := funcArg.GetParams() |  | ||||||
| 				ctx.RegisterFunc(p.Name(), funcArg, TypeAny, paramSpecs) |  | ||||||
| 			} else { |  | ||||||
| 				ctx.UnsafeSetVar(p.Name(), arg) |  | ||||||
| 			} |  | ||||||
| 		} else { |  | ||||||
| 			ctx.UnsafeSetVar(p.Name(), nil) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	result, err = functor.expr.Eval(ctx) |  | ||||||
| 	return |  | ||||||
| } |  | ||||||
| @ -1,19 +0,0 @@ | |||||||
| // Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
 |  | ||||||
| // All rights reserved.
 |  | ||||||
| 
 |  | ||||||
| // bind-go-function.go
 |  | ||||||
| package expr |  | ||||||
| 
 |  | ||||||
| // ---- Linking with Go functions
 |  | ||||||
| type golangFunctor struct { |  | ||||||
| 	baseFunctor |  | ||||||
| 	f FuncTemplate |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func NewGolangFunctor(f FuncTemplate) *golangFunctor { |  | ||||||
| 	return &golangFunctor{f: f} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (functor *golangFunctor) Invoke(ctx ExprContext, name string, args []any) (result any, err error) { |  | ||||||
| 	return functor.f(ctx, name, args) |  | ||||||
| } |  | ||||||
| @ -1,48 +0,0 @@ | |||||||
| // Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
 |  | ||||||
| // All rights reserved.
 |  | ||||||
| 
 |  | ||||||
| // builtins-register.go
 |  | ||||||
| package expr |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"fmt" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type builtinModule struct { |  | ||||||
| 	importFunc  func(ExprContext) |  | ||||||
| 	description string |  | ||||||
| 	imported    bool |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func newBuiltinModule(importFunc func(ExprContext), description string) *builtinModule { |  | ||||||
| 	return &builtinModule{importFunc, description, false} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var builtinModuleRegister map[string]*builtinModule |  | ||||||
| 
 |  | ||||||
| func RegisterBuiltinModule(name string, importFunc func(ExprContext), description string) { |  | ||||||
| 	if builtinModuleRegister == nil { |  | ||||||
| 		builtinModuleRegister = make(map[string]*builtinModule) |  | ||||||
| 	} |  | ||||||
| 	if _, exists := builtinModuleRegister[name]; exists { |  | ||||||
| 		panic(fmt.Errorf("module %q already registered", name)) |  | ||||||
| 	} |  | ||||||
| 	builtinModuleRegister[name] = newBuiltinModule(importFunc, description) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func IterateBuiltinModules(op func(name, description string, imported bool) bool) { |  | ||||||
| 	if op != nil { |  | ||||||
| 		for name, mod := range builtinModuleRegister { |  | ||||||
| 			if !op(name, mod.description, mod.imported) { |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ----
 |  | ||||||
| func init() { |  | ||||||
| 	if builtinModuleRegister == nil { |  | ||||||
| 		builtinModuleRegister = make(map[string]*builtinModule) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @ -5,17 +5,17 @@ | |||||||
| package expr | package expr | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
| 	ParamCount     = "count" | 	paramCount     = "count" | ||||||
| 	ParamItem      = "item" | 	paramItem      = "item" | ||||||
| 	ParamParts     = "parts" | 	paramParts     = "parts" | ||||||
| 	ParamSeparator = "separator" | 	paramSeparator = "separator" | ||||||
| 	ParamSource    = "source" | 	paramSource    = "source" | ||||||
| 	ParamSuffix    = "suffix" | 	paramSuffix    = "suffix" | ||||||
| 	ParamPrefix    = "prefix" | 	paramPrefix    = "prefix" | ||||||
| 	ParamStart     = "start" | 	paramStart     = "start" | ||||||
| 	ParamEnd       = "end" | 	paramEnd       = "end" | ||||||
| 	ParamValue     = "value" | 	paramValue     = "value" | ||||||
| 	ParamEllipsis  = "..." | 	paramEllipsis  = "..." | ||||||
| 	ParamFilepath  = "filepath" | 	paramFilepath  = "filepath" | ||||||
| 	ParamDirpath   = "dirpath" | 	paramDirpath   = "dirpath" | ||||||
| ) | ) | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| // Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
 | // Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
 | ||||||
| // All rights reserved.
 | // All rights reserved.
 | ||||||
| 
 | 
 | ||||||
| // builtin-base.go
 | // func-builtins.go
 | ||||||
| package expr | package expr | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| @ -159,7 +159,7 @@ func iteratorFunc(ctx ExprContext, name string, args []any) (result any, err err | |||||||
| 
 | 
 | ||||||
| func ImportBuiltinsFuncs(ctx ExprContext) { | func ImportBuiltinsFuncs(ctx ExprContext) { | ||||||
| 	anyParams := []ExprFuncParam{ | 	anyParams := []ExprFuncParam{ | ||||||
| 		NewFuncParam(ParamValue), | 		NewFuncParam(paramValue), | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ctx.RegisterFunc("isNil", NewGolangFunctor(isNilFunc), TypeBoolean, anyParams) | 	ctx.RegisterFunc("isNil", NewGolangFunctor(isNilFunc), TypeBoolean, anyParams) | ||||||
| @ -176,11 +176,11 @@ func ImportBuiltinsFuncs(ctx ExprContext) { | |||||||
| 	ctx.RegisterFunc("int", NewGolangFunctor(intFunc), TypeInt, anyParams) | 	ctx.RegisterFunc("int", NewGolangFunctor(intFunc), TypeInt, anyParams) | ||||||
| 	ctx.RegisterFunc("dec", NewGolangFunctor(decFunc), TypeFloat, anyParams) | 	ctx.RegisterFunc("dec", NewGolangFunctor(decFunc), TypeFloat, anyParams) | ||||||
| 	ctx.RegisterFunc("fract", NewGolangFunctor(fractFunc), TypeFraction, []ExprFuncParam{ | 	ctx.RegisterFunc("fract", NewGolangFunctor(fractFunc), TypeFraction, []ExprFuncParam{ | ||||||
| 		NewFuncParam(ParamValue), | 		NewFuncParam(paramValue), | ||||||
| 		NewFuncParamFlagDef("denominator", PfDefault, 1), | 		NewFuncParamFlagDef("denominator", PfDefault, 1), | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
| 	RegisterBuiltinModule("base", ImportBuiltinsFuncs, "Base expression tools like isNil(), int(), etc.") | 	registerImport("base", ImportBuiltinsFuncs, "Base expression tools like isNil(), int(), etc.") | ||||||
| } | } | ||||||
| @ -1,7 +1,7 @@ | |||||||
| // Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
 | // Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
 | ||||||
| // All rights reserved.
 | // All rights reserved.
 | ||||||
| 
 | 
 | ||||||
| // builtin-fmt.go
 | // func-fmt.go
 | ||||||
| package expr | package expr | ||||||
| 
 | 
 | ||||||
| import "fmt" | import "fmt" | ||||||
| @ -24,13 +24,13 @@ func printLnFunc(ctx ExprContext, name string, args []any) (result any, err erro | |||||||
| 
 | 
 | ||||||
| func ImportFmtFuncs(ctx ExprContext) { | func ImportFmtFuncs(ctx ExprContext) { | ||||||
| 	ctx.RegisterFunc("print", NewGolangFunctor(printFunc), TypeInt, []ExprFuncParam{ | 	ctx.RegisterFunc("print", NewGolangFunctor(printFunc), TypeInt, []ExprFuncParam{ | ||||||
| 		NewFuncParamFlag(ParamItem, PfRepeat), | 		NewFuncParamFlag(paramItem, PfRepeat), | ||||||
| 	}) | 	}) | ||||||
| 	ctx.RegisterFunc("println", NewGolangFunctor(printLnFunc), TypeInt, []ExprFuncParam{ | 	ctx.RegisterFunc("println", NewGolangFunctor(printLnFunc), TypeInt, []ExprFuncParam{ | ||||||
| 		NewFuncParamFlag(ParamItem, PfRepeat), | 		NewFuncParamFlag(paramItem, PfRepeat), | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
| 	RegisterBuiltinModule("fmt", ImportFmtFuncs, "String and console formatting functions") | 	registerImport("fmt", ImportFmtFuncs, "String and console formatting functions") | ||||||
| } | } | ||||||
| @ -1,7 +1,7 @@ | |||||||
| // Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
 | // Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
 | ||||||
| // All rights reserved.
 | // All rights reserved.
 | ||||||
| 
 | 
 | ||||||
| // builtin-import.go
 | // func-import.go
 | ||||||
| package expr | package expr | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| @ -63,13 +63,13 @@ func doImport(ctx ExprContext, name string, dirList []string, it Iterator) (resu | |||||||
| 
 | 
 | ||||||
| func ImportImportFuncs(ctx ExprContext) { | func ImportImportFuncs(ctx ExprContext) { | ||||||
| 	ctx.RegisterFunc("import", NewGolangFunctor(importFunc), TypeAny, []ExprFuncParam{ | 	ctx.RegisterFunc("import", NewGolangFunctor(importFunc), TypeAny, []ExprFuncParam{ | ||||||
| 		NewFuncParamFlag(ParamFilepath, PfRepeat), | 		NewFuncParamFlag(paramFilepath, PfRepeat), | ||||||
| 	}) | 	}) | ||||||
| 	ctx.RegisterFunc("importAll", NewGolangFunctor(importAllFunc), TypeAny, []ExprFuncParam{ | 	ctx.RegisterFunc("importAll", NewGolangFunctor(importAllFunc), TypeAny, []ExprFuncParam{ | ||||||
| 		NewFuncParamFlag(ParamFilepath, PfRepeat), | 		NewFuncParamFlag(paramFilepath, PfRepeat), | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
| 	RegisterBuiltinModule("import", ImportImportFuncs, "Functions import() and include()") | 	registerImport("import", ImportImportFuncs, "Functions import() and include()") | ||||||
| } | } | ||||||
| @ -1,7 +1,7 @@ | |||||||
| // Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
 | // Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
 | ||||||
| // All rights reserved.
 | // All rights reserved.
 | ||||||
| 
 | 
 | ||||||
| // builtin-math-arith.go
 | // funcs-math.go
 | ||||||
| package expr | package expr | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| @ -168,14 +168,14 @@ func mulFunc(ctx ExprContext, name string, args []any) (result any, err error) { | |||||||
| 
 | 
 | ||||||
| func ImportMathFuncs(ctx ExprContext) { | func ImportMathFuncs(ctx ExprContext) { | ||||||
| 	ctx.RegisterFunc("add", &golangFunctor{f: addFunc}, TypeNumber, []ExprFuncParam{ | 	ctx.RegisterFunc("add", &golangFunctor{f: addFunc}, TypeNumber, []ExprFuncParam{ | ||||||
| 		NewFuncParamFlagDef(ParamValue, PfDefault|PfRepeat, int64(0)), | 		NewFuncParamFlagDef(paramValue, PfDefault|PfRepeat, int64(0)), | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	ctx.RegisterFunc("mul", &golangFunctor{f: mulFunc}, TypeNumber, []ExprFuncParam{ | 	ctx.RegisterFunc("mul", &golangFunctor{f: mulFunc}, TypeNumber, []ExprFuncParam{ | ||||||
| 		NewFuncParamFlagDef(ParamValue, PfDefault|PfRepeat, int64(1)), | 		NewFuncParamFlagDef(paramValue, PfDefault|PfRepeat, int64(1)), | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
| 	RegisterBuiltinModule("math.arith", ImportMathFuncs, "Functions add() and mul()") | 	registerImport("math.arith", ImportMathFuncs, "Functions add() and mul()") | ||||||
| } | } | ||||||
| @ -1,7 +1,7 @@ | |||||||
| // Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
 | // Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
 | ||||||
| // All rights reserved.
 | // All rights reserved.
 | ||||||
| 
 | 
 | ||||||
| // builtin-os-file.go
 | // func-os.go
 | ||||||
| package expr | package expr | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| @ -188,13 +188,13 @@ func readFileFunc(ctx ExprContext, name string, args []any) (result any, err err | |||||||
| 
 | 
 | ||||||
| func ImportOsFuncs(ctx ExprContext) { | func ImportOsFuncs(ctx ExprContext) { | ||||||
| 	ctx.RegisterFunc("openFile", NewGolangFunctor(openFileFunc), TypeHandle, []ExprFuncParam{ | 	ctx.RegisterFunc("openFile", NewGolangFunctor(openFileFunc), TypeHandle, []ExprFuncParam{ | ||||||
| 		NewFuncParam(ParamFilepath), | 		NewFuncParam(paramFilepath), | ||||||
| 	}) | 	}) | ||||||
| 	ctx.RegisterFunc("appendFile", NewGolangFunctor(appendFileFunc), TypeHandle, []ExprFuncParam{ | 	ctx.RegisterFunc("appendFile", NewGolangFunctor(appendFileFunc), TypeHandle, []ExprFuncParam{ | ||||||
| 		NewFuncParam(ParamFilepath), | 		NewFuncParam(paramFilepath), | ||||||
| 	}) | 	}) | ||||||
| 	ctx.RegisterFunc("createFile", NewGolangFunctor(createFileFunc), TypeHandle, []ExprFuncParam{ | 	ctx.RegisterFunc("createFile", NewGolangFunctor(createFileFunc), TypeHandle, []ExprFuncParam{ | ||||||
| 		NewFuncParam(ParamFilepath), | 		NewFuncParam(paramFilepath), | ||||||
| 	}) | 	}) | ||||||
| 	ctx.RegisterFunc("writeFile", NewGolangFunctor(writeFileFunc), TypeInt, []ExprFuncParam{ | 	ctx.RegisterFunc("writeFile", NewGolangFunctor(writeFileFunc), TypeInt, []ExprFuncParam{ | ||||||
| 		NewFuncParam(TypeHandle), | 		NewFuncParam(TypeHandle), | ||||||
| @ -210,5 +210,5 @@ func ImportOsFuncs(ctx ExprContext) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
| 	RegisterBuiltinModule("os.file", ImportOsFuncs, "Operating system file functions") | 	registerImport("os.file", ImportOsFuncs, "Operating system file functions") | ||||||
| } | } | ||||||
| @ -1,7 +1,7 @@ | |||||||
| // Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
 | // Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
 | ||||||
| // All rights reserved.
 | // All rights reserved.
 | ||||||
| 
 | 
 | ||||||
| // builtin-string.go
 | // func-string.go
 | ||||||
| package expr | package expr | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| @ -45,13 +45,13 @@ func joinStrFunc(ctx ExprContext, name string, args []any) (result any, err erro | |||||||
| 			} else if it, ok := args[1].(Iterator); ok { | 			} else if it, ok := args[1].(Iterator); ok { | ||||||
| 				result, err = doJoinStr(name, sep, it) | 				result, err = doJoinStr(name, sep, it) | ||||||
| 			} else { | 			} else { | ||||||
| 				err = errInvalidParameterValue(name, ParamParts, args[1]) | 				err = errInvalidParameterValue(name, paramParts, args[1]) | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
| 			result, err = doJoinStr(name, sep, NewArrayIterator(args[1:])) | 			result, err = doJoinStr(name, sep, NewArrayIterator(args[1:])) | ||||||
| 		} | 		} | ||||||
| 	} else { | 	} else { | ||||||
| 		err = errWrongParamType(name, ParamSeparator, TypeString, args[0]) | 		err = errWrongParamType(name, paramSeparator, TypeString, args[0]) | ||||||
| 	} | 	} | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
| @ -63,7 +63,7 @@ func subStrFunc(ctx ExprContext, name string, args []any) (result any, err error | |||||||
| 	var ok bool | 	var ok bool | ||||||
| 
 | 
 | ||||||
| 	if source, ok = args[0].(string); !ok { | 	if source, ok = args[0].(string); !ok { | ||||||
| 		return nil, errWrongParamType(name, ParamSource, TypeString, args[0]) | 		return nil, errWrongParamType(name, paramSource, TypeString, args[0]) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if start, err = toInt(args[1], name+"()"); err != nil { | 	if start, err = toInt(args[1], name+"()"); err != nil { | ||||||
| @ -91,7 +91,7 @@ func trimStrFunc(ctx ExprContext, name string, args []any) (result any, err erro | |||||||
| 	var ok bool | 	var ok bool | ||||||
| 
 | 
 | ||||||
| 	if source, ok = args[0].(string); !ok { | 	if source, ok = args[0].(string); !ok { | ||||||
| 		return nil, errWrongParamType(name, ParamSource, TypeString, args[0]) | 		return nil, errWrongParamType(name, paramSource, TypeString, args[0]) | ||||||
| 	} | 	} | ||||||
| 	result = strings.TrimSpace(source) | 	result = strings.TrimSpace(source) | ||||||
| 	return | 	return | ||||||
| @ -104,7 +104,7 @@ func startsWithStrFunc(ctx ExprContext, name string, args []any) (result any, er | |||||||
| 	result = false | 	result = false | ||||||
| 
 | 
 | ||||||
| 	if source, ok = args[0].(string); !ok { | 	if source, ok = args[0].(string); !ok { | ||||||
| 		return result, errWrongParamType(name, ParamSource, TypeString, args[0]) | 		return result, errWrongParamType(name, paramSource, TypeString, args[0]) | ||||||
| 	} | 	} | ||||||
| 	for i, targetSpec := range args[1:] { | 	for i, targetSpec := range args[1:] { | ||||||
| 		if target, ok := targetSpec.(string); ok { | 		if target, ok := targetSpec.(string); ok { | ||||||
| @ -127,7 +127,7 @@ func endsWithStrFunc(ctx ExprContext, name string, args []any) (result any, err | |||||||
| 	result = false | 	result = false | ||||||
| 
 | 
 | ||||||
| 	if source, ok = args[0].(string); !ok { | 	if source, ok = args[0].(string); !ok { | ||||||
| 		return result, errWrongParamType(name, ParamSource, TypeString, args[0]) | 		return result, errWrongParamType(name, paramSource, TypeString, args[0]) | ||||||
| 	} | 	} | ||||||
| 	for i, targetSpec := range args[1:] { | 	for i, targetSpec := range args[1:] { | ||||||
| 		if target, ok := targetSpec.(string); ok { | 		if target, ok := targetSpec.(string); ok { | ||||||
| @ -150,7 +150,7 @@ func splitStrFunc(ctx ExprContext, name string, args []any) (result any, err err | |||||||
| 	var ok bool | 	var ok bool | ||||||
| 
 | 
 | ||||||
| 	if source, ok = args[0].(string); !ok { | 	if source, ok = args[0].(string); !ok { | ||||||
| 		return result, errWrongParamType(name, ParamSource, TypeString, args[0]) | 		return result, errWrongParamType(name, paramSource, TypeString, args[0]) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if sep, ok = args[1].(string); !ok { | 	if sep, ok = args[1].(string); !ok { | ||||||
| @ -183,41 +183,41 @@ func splitStrFunc(ctx ExprContext, name string, args []any) (result any, err err | |||||||
| // Import above functions in the context
 | // Import above functions in the context
 | ||||||
| func ImportStringFuncs(ctx ExprContext) { | func ImportStringFuncs(ctx ExprContext) { | ||||||
| 	ctx.RegisterFunc("joinStr", NewGolangFunctor(joinStrFunc), TypeString, []ExprFuncParam{ | 	ctx.RegisterFunc("joinStr", NewGolangFunctor(joinStrFunc), TypeString, []ExprFuncParam{ | ||||||
| 		NewFuncParam(ParamSeparator), | 		NewFuncParam(paramSeparator), | ||||||
| 		NewFuncParamFlag(ParamItem, PfRepeat), | 		NewFuncParamFlag(paramItem, PfRepeat), | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	ctx.RegisterFunc("subStr", NewGolangFunctor(subStrFunc), TypeString, []ExprFuncParam{ | 	ctx.RegisterFunc("subStr", NewGolangFunctor(subStrFunc), TypeString, []ExprFuncParam{ | ||||||
| 		NewFuncParam(ParamSource), | 		NewFuncParam(paramSource), | ||||||
| 		NewFuncParamFlagDef(ParamStart, PfDefault, int64(0)), | 		NewFuncParamFlagDef(paramStart, PfDefault, int64(0)), | ||||||
| 		NewFuncParamFlagDef(ParamCount, PfDefault, int64(-1)), | 		NewFuncParamFlagDef(paramCount, PfDefault, int64(-1)), | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	ctx.RegisterFunc("splitStr", NewGolangFunctor(splitStrFunc), "list of "+TypeString, []ExprFuncParam{ | 	ctx.RegisterFunc("splitStr", NewGolangFunctor(splitStrFunc), "list of "+TypeString, []ExprFuncParam{ | ||||||
| 		NewFuncParam(ParamSource), | 		NewFuncParam(paramSource), | ||||||
| 		NewFuncParamFlagDef(ParamSeparator, PfDefault, ""), | 		NewFuncParamFlagDef(paramSeparator, PfDefault, ""), | ||||||
| 		NewFuncParamFlagDef(ParamCount, PfDefault, int64(-1)), | 		NewFuncParamFlagDef(paramCount, PfDefault, int64(-1)), | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	ctx.RegisterFunc("trimStr", NewGolangFunctor(trimStrFunc), TypeString, []ExprFuncParam{ | 	ctx.RegisterFunc("trimStr", NewGolangFunctor(trimStrFunc), TypeString, []ExprFuncParam{ | ||||||
| 		NewFuncParam(ParamSource), | 		NewFuncParam(paramSource), | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	ctx.RegisterFunc("startsWithStr", NewGolangFunctor(startsWithStrFunc), TypeBoolean, []ExprFuncParam{ | 	ctx.RegisterFunc("startsWithStr", NewGolangFunctor(startsWithStrFunc), TypeBoolean, []ExprFuncParam{ | ||||||
| 		NewFuncParam(ParamSource), | 		NewFuncParam(paramSource), | ||||||
| 		NewFuncParam(ParamPrefix), | 		NewFuncParam(paramPrefix), | ||||||
| 		NewFuncParamFlag("other "+ParamPrefix, PfRepeat), | 		NewFuncParamFlag("other "+paramPrefix, PfRepeat), | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	ctx.RegisterFunc("endsWithStr", NewGolangFunctor(endsWithStrFunc), TypeBoolean, []ExprFuncParam{ | 	ctx.RegisterFunc("endsWithStr", NewGolangFunctor(endsWithStrFunc), TypeBoolean, []ExprFuncParam{ | ||||||
| 		NewFuncParam(ParamSource), | 		NewFuncParam(paramSource), | ||||||
| 		NewFuncParam(ParamSuffix), | 		NewFuncParam(paramSuffix), | ||||||
| 		NewFuncParamFlag("other "+ParamSuffix, PfRepeat), | 		NewFuncParamFlag("other "+paramSuffix, PfRepeat), | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Register the import function in the import-register.
 | // Register the import function in the import-register.
 | ||||||
| // That will allow to import all function of this module by the "builtin" operator."
 | // That will allow to import all function of this module by the "builtin" operator."
 | ||||||
| func init() { | func init() { | ||||||
| 	RegisterBuiltinModule("string", ImportStringFuncs, "string utilities") | 	registerImport("string", ImportStringFuncs, "string utilities") | ||||||
| } | } | ||||||
							
								
								
									
										53
									
								
								function.go
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								function.go
									
									
									
									
									
								
							| @ -42,6 +42,59 @@ func (functor *baseFunctor) GetFunc() ExprFunc { | |||||||
| 	return functor.info | 	return functor.info | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // ---- Linking with Go functions
 | ||||||
|  | type golangFunctor struct { | ||||||
|  | 	baseFunctor | ||||||
|  | 	f FuncTemplate | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func NewGolangFunctor(f FuncTemplate) *golangFunctor { | ||||||
|  | 	return &golangFunctor{f: f} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (functor *golangFunctor) Invoke(ctx ExprContext, name string, args []any) (result any, err error) { | ||||||
|  | 	return functor.f(ctx, name, args) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ---- Linking with Expr functions
 | ||||||
|  | type exprFunctor struct { | ||||||
|  | 	baseFunctor | ||||||
|  | 	params []ExprFuncParam | ||||||
|  | 	expr   Expr | ||||||
|  | 	defCtx ExprContext | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // func newExprFunctor(e Expr, params []string, ctx ExprContext) *exprFunctor {
 | ||||||
|  | // 	return &exprFunctor{expr: e, params: params, defCtx: ctx}
 | ||||||
|  | // }
 | ||||||
|  | 
 | ||||||
|  | func newExprFunctor(e Expr, params []ExprFuncParam, ctx ExprContext) *exprFunctor { | ||||||
|  | 	return &exprFunctor{expr: e, params: params, defCtx: ctx} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (functor *exprFunctor) Invoke(ctx ExprContext, name string, args []any) (result any, err error) { | ||||||
|  | 	if functor.defCtx != nil { | ||||||
|  | 		ctx.Merge(functor.defCtx) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for i, p := range functor.params { | ||||||
|  | 		if i < len(args) { | ||||||
|  | 			arg := args[i] | ||||||
|  | 			if funcArg, ok := arg.(Functor); ok { | ||||||
|  | 				// ctx.RegisterFunc(p, functor, 0, -1)
 | ||||||
|  | 				paramSpecs := funcArg.GetParams() | ||||||
|  | 				ctx.RegisterFunc(p.Name(), funcArg, TypeAny, paramSpecs) | ||||||
|  | 			} else { | ||||||
|  | 				ctx.UnsafeSetVar(p.Name(), arg) | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			ctx.UnsafeSetVar(p.Name(), nil) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	result, err = functor.expr.Eval(ctx) | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // ---- Function Parameters
 | // ---- Function Parameters
 | ||||||
| type paramFlags uint16 | type paramFlags uint16 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -12,8 +12,8 @@ import ( | |||||||
| var globalCtx *SimpleStore | var globalCtx *SimpleStore | ||||||
| 
 | 
 | ||||||
| func ImportInContext(name string) (exists bool) { | func ImportInContext(name string) (exists bool) { | ||||||
| 	var mod *builtinModule | 	var mod *module | ||||||
| 	if mod, exists = builtinModuleRegister[name]; exists { | 	if mod, exists = moduleRegister[name]; exists { | ||||||
| 		mod.importFunc(globalCtx) | 		mod.importFunc(globalCtx) | ||||||
| 		mod.imported = true | 		mod.imported = true | ||||||
| 	} | 	} | ||||||
| @ -22,7 +22,7 @@ func ImportInContext(name string) (exists bool) { | |||||||
| 
 | 
 | ||||||
| func ImportInContextByGlobPattern(pattern string) (count int, err error) { | func ImportInContextByGlobPattern(pattern string) (count int, err error) { | ||||||
| 	var matched bool | 	var matched bool | ||||||
| 	for name, mod := range builtinModuleRegister { | 	for name, mod := range moduleRegister { | ||||||
| 		if matched, err = filepath.Match(pattern, name); err == nil { | 		if matched, err = filepath.Match(pattern, name); err == nil { | ||||||
| 			if matched { | 			if matched { | ||||||
| 				count++ | 				count++ | ||||||
|  | |||||||
| @ -41,7 +41,7 @@ func EvalStringV(source string, args []Arg) (result any, err error) { | |||||||
| 				functor := NewGolangFunctor(f) | 				functor := NewGolangFunctor(f) | ||||||
| 				// ctx.RegisterFunc(arg.Name, functor, 0, -1)
 | 				// ctx.RegisterFunc(arg.Name, functor, 0, -1)
 | ||||||
| 				ctx.RegisterFunc(arg.Name, functor, TypeAny, []ExprFuncParam{ | 				ctx.RegisterFunc(arg.Name, functor, TypeAny, []ExprFuncParam{ | ||||||
| 					NewFuncParamFlagDef(ParamValue, PfDefault|PfRepeat, 0), | 					NewFuncParamFlagDef(paramValue, PfDefault|PfRepeat, 0), | ||||||
| 				}) | 				}) | ||||||
| 			} else { | 			} else { | ||||||
| 				err = fmt.Errorf("invalid function specification: %q", arg.Name) | 				err = fmt.Errorf("invalid function specification: %q", arg.Name) | ||||||
|  | |||||||
							
								
								
									
										48
									
								
								module-register.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								module-register.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | |||||||
|  | // Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
 | ||||||
|  | // All rights reserved.
 | ||||||
|  | 
 | ||||||
|  | // module-register.go
 | ||||||
|  | package expr | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type module struct { | ||||||
|  | 	importFunc  func(ExprContext) | ||||||
|  | 	description string | ||||||
|  | 	imported    bool | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func newModule(importFunc func(ExprContext), description string) *module { | ||||||
|  | 	return &module{importFunc, description, false} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var moduleRegister map[string]*module | ||||||
|  | 
 | ||||||
|  | func registerImport(name string, importFunc func(ExprContext), description string) { | ||||||
|  | 	if moduleRegister == nil { | ||||||
|  | 		moduleRegister = make(map[string]*module) | ||||||
|  | 	} | ||||||
|  | 	if _, exists := moduleRegister[name]; exists { | ||||||
|  | 		panic(fmt.Errorf("module %q already registered", name)) | ||||||
|  | 	} | ||||||
|  | 	moduleRegister[name] = newModule(importFunc, description) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func IterateModules(op func(name, description string, imported bool) bool) { | ||||||
|  | 	if op != nil { | ||||||
|  | 		for name, mod := range moduleRegister { | ||||||
|  | 			if !op(name, mod.description, mod.imported) { | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // ----
 | ||||||
|  | func init() { | ||||||
|  | 	if moduleRegister == nil { | ||||||
|  | 		moduleRegister = make(map[string]*module) | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @ -68,7 +68,7 @@ func evalAssignCoalesce(ctx ExprContext, self *term) (v any, err error) { | |||||||
| 		if functor, ok := rightValue.(Functor); ok { | 		if functor, ok := rightValue.(Functor); ok { | ||||||
| 			//ctx.RegisterFunc(leftTerm.source(), functor, 0, -1)
 | 			//ctx.RegisterFunc(leftTerm.source(), functor, 0, -1)
 | ||||||
| 			ctx.RegisterFunc(leftTerm.source(), functor, TypeAny, []ExprFuncParam{ | 			ctx.RegisterFunc(leftTerm.source(), functor, TypeAny, []ExprFuncParam{ | ||||||
| 				NewFuncParamFlag(ParamValue, PfDefault|PfRepeat), | 				NewFuncParamFlag(paramValue, PfDefault|PfRepeat), | ||||||
| 			}) | 			}) | ||||||
| 		} else { | 		} else { | ||||||
| 			v = rightValue | 			v = rightValue | ||||||
|  | |||||||
| @ -12,7 +12,7 @@ func TestIterateModules(t *testing.T) { | |||||||
| 	section := "Module-Register" | 	section := "Module-Register" | ||||||
| 
 | 
 | ||||||
| 	mods := make([]string, 0, 100) | 	mods := make([]string, 0, 100) | ||||||
| 	IterateBuiltinModules(func(name, description string, imported bool) bool { | 	IterateModules(func(name, description string, imported bool) bool { | ||||||
| 		mods = append(mods, name) | 		mods = append(mods, name) | ||||||
| 		return true | 		return true | ||||||
| 	}) | 	}) | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user