new iter-iter iterator and kern.func-info module
This commit is contained in:
+10
-10
@@ -272,7 +272,7 @@ func setFunc(ctx kern.ExprContext, name string, args map[string]any) (result any
|
|||||||
|
|
||||||
func ImportBuiltinsFuncs(ctx kern.ExprContext) {
|
func ImportBuiltinsFuncs(ctx kern.ExprContext) {
|
||||||
anyParams := []kern.ExprFuncParam{
|
anyParams := []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamValue),
|
kern.NewFuncParam(kern.ParamValue),
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.RegisterFunc("isNil", kern.NewGolangFunctor(isNilFunc), kern.TypeBoolean, anyParams)
|
ctx.RegisterFunc("isNil", kern.NewGolangFunctor(isNilFunc), kern.TypeBoolean, anyParams)
|
||||||
@@ -290,27 +290,27 @@ func ImportBuiltinsFuncs(ctx kern.ExprContext) {
|
|||||||
ctx.RegisterFunc("dec", kern.NewGolangFunctor(decFunc), kern.TypeFloat, anyParams)
|
ctx.RegisterFunc("dec", kern.NewGolangFunctor(decFunc), kern.TypeFloat, anyParams)
|
||||||
ctx.RegisterFunc("string", kern.NewGolangFunctor(stringFunc), kern.TypeString, anyParams)
|
ctx.RegisterFunc("string", kern.NewGolangFunctor(stringFunc), kern.TypeString, anyParams)
|
||||||
ctx.RegisterFunc("fract", kern.NewGolangFunctor(fractFunc), kern.TypeFraction, []kern.ExprFuncParam{
|
ctx.RegisterFunc("fract", kern.NewGolangFunctor(fractFunc), kern.TypeFraction, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamValue),
|
kern.NewFuncParam(kern.ParamValue),
|
||||||
NewFuncParamFlagDef(ParamDenominator, PfDefault, int64(1)),
|
kern.NewFuncParamFlagDef(ParamDenominator, kern.PfDefault, int64(1)),
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.RegisterFunc("eval", kern.NewGolangFunctor(evalFunc), kern.TypeAny, []kern.ExprFuncParam{
|
ctx.RegisterFunc("eval", kern.NewGolangFunctor(evalFunc), kern.TypeAny, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamSource),
|
kern.NewFuncParam(kern.ParamSource),
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.RegisterFunc("var", kern.NewGolangFunctor(varFunc), kern.TypeAny, []kern.ExprFuncParam{
|
ctx.RegisterFunc("var", kern.NewGolangFunctor(varFunc), kern.TypeAny, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamName),
|
kern.NewFuncParam(kern.ParamName),
|
||||||
NewFuncParamFlagDef(kern.ParamValue, PfDefault, nil),
|
kern.NewFuncParamFlagDef(kern.ParamValue, kern.PfDefault, nil),
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.RegisterFunc("set", kern.NewGolangFunctor(setFunc), kern.TypeAny, []kern.ExprFuncParam{
|
ctx.RegisterFunc("set", kern.NewGolangFunctor(setFunc), kern.TypeAny, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamName),
|
kern.NewFuncParam(kern.ParamName),
|
||||||
NewFuncParam(kern.ParamValue),
|
kern.NewFuncParam(kern.ParamValue),
|
||||||
})
|
})
|
||||||
|
|
||||||
// ctx.RegisterFunc("unset", kern.NewGolangFunctor(unsetFunc), kern.TypeAny, []kern.ExprFuncParam{
|
// ctx.RegisterFunc("unset", kern.NewGolangFunctor(unsetFunc), kern.TypeAny, []kern.ExprFuncParam{
|
||||||
// NewFuncParam(kern.ParamName),
|
// kern.NewFuncParam(kern.ParamName),
|
||||||
// NewFuncParam(kern.ParamValue),
|
// kern.NewFuncParam(kern.ParamValue),
|
||||||
// })
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -47,10 +47,10 @@ func printLnFunc(ctx kern.ExprContext, name string, args map[string]any) (result
|
|||||||
|
|
||||||
func ImportFmtFuncs(ctx kern.ExprContext) {
|
func ImportFmtFuncs(ctx kern.ExprContext) {
|
||||||
ctx.RegisterFunc("print", kern.NewGolangFunctor(printFunc), kern.TypeInt, []kern.ExprFuncParam{
|
ctx.RegisterFunc("print", kern.NewGolangFunctor(printFunc), kern.TypeInt, []kern.ExprFuncParam{
|
||||||
NewFuncParamFlag(kern.ParamItem, PfRepeat),
|
kern.NewFuncParamFlag(kern.ParamItem, kern.PfRepeat),
|
||||||
})
|
})
|
||||||
ctx.RegisterFunc("println", kern.NewGolangFunctor(printLnFunc), kern.TypeInt, []kern.ExprFuncParam{
|
ctx.RegisterFunc("println", kern.NewGolangFunctor(printLnFunc), kern.TypeInt, []kern.ExprFuncParam{
|
||||||
NewFuncParamFlag(kern.ParamItem, PfRepeat),
|
kern.NewFuncParamFlag(kern.ParamItem, kern.PfRepeat),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -69,10 +69,10 @@ func doImport(ctx kern.ExprContext, name string, dirList []string, it kern.Itera
|
|||||||
|
|
||||||
func ImportImportFuncs(ctx kern.ExprContext) {
|
func ImportImportFuncs(ctx kern.ExprContext) {
|
||||||
ctx.RegisterFunc("import", kern.NewGolangFunctor(importFunc), kern.TypeAny, []kern.ExprFuncParam{
|
ctx.RegisterFunc("import", kern.NewGolangFunctor(importFunc), kern.TypeAny, []kern.ExprFuncParam{
|
||||||
NewFuncParamFlag(kern.ParamFilepath, PfRepeat),
|
kern.NewFuncParamFlag(kern.ParamFilepath, kern.PfRepeat),
|
||||||
})
|
})
|
||||||
ctx.RegisterFunc("importAll", kern.NewGolangFunctor(importAllFunc), kern.TypeAny, []kern.ExprFuncParam{
|
ctx.RegisterFunc("importAll", kern.NewGolangFunctor(importAllFunc), kern.TypeAny, []kern.ExprFuncParam{
|
||||||
NewFuncParamFlag(kern.ParamFilepath, PfRepeat),
|
kern.NewFuncParamFlag(kern.ParamFilepath, kern.PfRepeat),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -94,9 +94,9 @@ func runFunc(ctx kern.ExprContext, name string, args map[string]any) (result any
|
|||||||
|
|
||||||
func ImportIterFuncs(ctx kern.ExprContext) {
|
func ImportIterFuncs(ctx kern.ExprContext) {
|
||||||
ctx.RegisterFunc("run", kern.NewGolangFunctor(runFunc), kern.TypeAny, []kern.ExprFuncParam{
|
ctx.RegisterFunc("run", kern.NewGolangFunctor(runFunc), kern.TypeAny, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamIterator),
|
kern.NewFuncParam(kern.ParamIterator),
|
||||||
NewFuncParamFlag(iterParamOperator, PfOptional),
|
kern.NewFuncParamFlag(iterParamOperator, kern.PfOptional),
|
||||||
NewFuncParamFlag(iterParamVars, PfOptional),
|
kern.NewFuncParamFlag(iterParamVars, kern.PfOptional),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -172,11 +172,11 @@ func mulFunc(ctx kern.ExprContext, name string, args map[string]any) (result any
|
|||||||
|
|
||||||
func ImportMathFuncs(ctx kern.ExprContext) {
|
func ImportMathFuncs(ctx kern.ExprContext) {
|
||||||
ctx.RegisterFunc("add", kern.NewGolangFunctor(addFunc), kern.TypeNumber, []kern.ExprFuncParam{
|
ctx.RegisterFunc("add", kern.NewGolangFunctor(addFunc), kern.TypeNumber, []kern.ExprFuncParam{
|
||||||
NewFuncParamFlagDef(kern.ParamValue, PfDefault|PfRepeat, int64(0)),
|
kern.NewFuncParamFlagDef(kern.ParamValue, kern.PfDefault|kern.PfRepeat, int64(0)),
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.RegisterFunc("mul", kern.NewGolangFunctor(mulFunc), kern.TypeNumber, []kern.ExprFuncParam{
|
ctx.RegisterFunc("mul", kern.NewGolangFunctor(mulFunc), kern.TypeNumber, []kern.ExprFuncParam{
|
||||||
NewFuncParamFlagDef(kern.ParamValue, PfDefault|PfRepeat, int64(1)),
|
kern.NewFuncParamFlagDef(kern.ParamValue, kern.PfDefault|kern.PfRepeat, int64(1)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-10
@@ -224,37 +224,37 @@ func fileReadTextAllFunc(ctx kern.ExprContext, name string, args map[string]any)
|
|||||||
|
|
||||||
func ImportOsFuncs(ctx kern.ExprContext) {
|
func ImportOsFuncs(ctx kern.ExprContext) {
|
||||||
ctx.RegisterFunc("fileOpen", kern.NewGolangFunctor(openFileFunc), kern.TypeFileHandle, []kern.ExprFuncParam{
|
ctx.RegisterFunc("fileOpen", kern.NewGolangFunctor(openFileFunc), kern.TypeFileHandle, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamFilepath),
|
kern.NewFuncParam(kern.ParamFilepath),
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.RegisterFunc("fileAppend", kern.NewGolangFunctor(appendFileFunc), kern.TypeFileHandle, []kern.ExprFuncParam{
|
ctx.RegisterFunc("fileAppend", kern.NewGolangFunctor(appendFileFunc), kern.TypeFileHandle, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamFilepath),
|
kern.NewFuncParam(kern.ParamFilepath),
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.RegisterFunc("fileCreate", kern.NewGolangFunctor(createFileFunc), kern.TypeFileHandle, []kern.ExprFuncParam{
|
ctx.RegisterFunc("fileCreate", kern.NewGolangFunctor(createFileFunc), kern.TypeFileHandle, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamFilepath),
|
kern.NewFuncParam(kern.ParamFilepath),
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.RegisterFunc("fileClose", kern.NewGolangFunctor(closeFileFunc), kern.TypeBoolean, []kern.ExprFuncParam{
|
ctx.RegisterFunc("fileClose", kern.NewGolangFunctor(closeFileFunc), kern.TypeBoolean, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamHandle),
|
kern.NewFuncParam(kern.ParamHandle),
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.RegisterFunc("fileWriteText", kern.NewGolangFunctor(fileWriteTextFunc), kern.TypeInt, []kern.ExprFuncParam{
|
ctx.RegisterFunc("fileWriteText", kern.NewGolangFunctor(fileWriteTextFunc), kern.TypeInt, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamHandle),
|
kern.NewFuncParam(kern.ParamHandle),
|
||||||
NewFuncParamFlagDef(kern.ParamItem, PfDefault|PfRepeat, ""),
|
kern.NewFuncParamFlagDef(kern.ParamItem, kern.PfDefault|kern.PfRepeat, ""),
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.RegisterFunc("fileReadText", kern.NewGolangFunctor(fileReadTextFunc), kern.TypeString, []kern.ExprFuncParam{
|
ctx.RegisterFunc("fileReadText", kern.NewGolangFunctor(fileReadTextFunc), kern.TypeString, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamHandle),
|
kern.NewFuncParam(kern.ParamHandle),
|
||||||
NewFuncParamFlagDef(osLimitCh, PfDefault, "\n"),
|
kern.NewFuncParamFlagDef(osLimitCh, kern.PfDefault, "\n"),
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.RegisterFunc("fileReadTextAll", kern.NewGolangFunctor(fileReadTextAllFunc), kern.TypeString, []kern.ExprFuncParam{
|
ctx.RegisterFunc("fileReadTextAll", kern.NewGolangFunctor(fileReadTextAllFunc), kern.TypeString, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamHandle),
|
kern.NewFuncParam(kern.ParamHandle),
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.RegisterFunc("fileReadIterator", kern.NewGolangFunctor(fileReadIteratorFunc), kern.TypeIterator, []kern.ExprFuncParam{
|
ctx.RegisterFunc("fileReadIterator", kern.NewGolangFunctor(fileReadIteratorFunc), kern.TypeIterator, []kern.ExprFuncParam{
|
||||||
NewFuncParam(paramHandleOrPath),
|
kern.NewFuncParam(paramHandleOrPath),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-17
@@ -225,44 +225,44 @@ func lowerStrFunc(ctx kern.ExprContext, name string, args map[string]any) (resul
|
|||||||
// Import above functions in the context
|
// Import above functions in the context
|
||||||
func ImportStringFuncs(ctx kern.ExprContext) {
|
func ImportStringFuncs(ctx kern.ExprContext) {
|
||||||
ctx.RegisterFunc("strJoin", kern.NewGolangFunctor(joinStrFunc), kern.TypeString, []kern.ExprFuncParam{
|
ctx.RegisterFunc("strJoin", kern.NewGolangFunctor(joinStrFunc), kern.TypeString, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamSeparator),
|
kern.NewFuncParam(kern.ParamSeparator),
|
||||||
NewFuncParamFlag(kern.ParamItem, PfRepeat),
|
kern.NewFuncParamFlag(kern.ParamItem, kern.PfRepeat),
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.RegisterFunc("strSub", kern.NewGolangFunctor(subStrFunc), kern.TypeString, []kern.ExprFuncParam{
|
ctx.RegisterFunc("strSub", kern.NewGolangFunctor(subStrFunc), kern.TypeString, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamSource),
|
kern.NewFuncParam(kern.ParamSource),
|
||||||
NewFuncParamFlagDef(kern.ParamStart, PfDefault, int64(0)),
|
kern.NewFuncParamFlagDef(kern.ParamStart, kern.PfDefault, int64(0)),
|
||||||
NewFuncParamFlagDef(kern.ParamCount, PfDefault, int64(-1)),
|
kern.NewFuncParamFlagDef(kern.ParamCount, kern.PfDefault, int64(-1)),
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.RegisterFunc("strSplit", kern.NewGolangFunctor(splitStrFunc), "list of "+kern.TypeString, []kern.ExprFuncParam{
|
ctx.RegisterFunc("strSplit", kern.NewGolangFunctor(splitStrFunc), "list of "+kern.TypeString, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamSource),
|
kern.NewFuncParam(kern.ParamSource),
|
||||||
NewFuncParamFlagDef(kern.ParamSeparator, PfDefault, ""),
|
kern.NewFuncParamFlagDef(kern.ParamSeparator, kern.PfDefault, ""),
|
||||||
NewFuncParamFlagDef(kern.ParamCount, PfDefault, int64(-1)),
|
kern.NewFuncParamFlagDef(kern.ParamCount, kern.PfDefault, int64(-1)),
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.RegisterFunc("strTrim", kern.NewGolangFunctor(trimStrFunc), kern.TypeString, []kern.ExprFuncParam{
|
ctx.RegisterFunc("strTrim", kern.NewGolangFunctor(trimStrFunc), kern.TypeString, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamSource),
|
kern.NewFuncParam(kern.ParamSource),
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.RegisterFunc("strStartsWith", kern.NewGolangFunctor(startsWithStrFunc), kern.TypeBoolean, []kern.ExprFuncParam{
|
ctx.RegisterFunc("strStartsWith", kern.NewGolangFunctor(startsWithStrFunc), kern.TypeBoolean, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamSource),
|
kern.NewFuncParam(kern.ParamSource),
|
||||||
NewFuncParam(kern.ParamPrefix),
|
kern.NewFuncParam(kern.ParamPrefix),
|
||||||
NewFuncParamFlag(strParamOther, PfRepeat),
|
kern.NewFuncParamFlag(strParamOther, kern.PfRepeat),
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.RegisterFunc("strEndsWith", kern.NewGolangFunctor(endsWithStrFunc), kern.TypeBoolean, []kern.ExprFuncParam{
|
ctx.RegisterFunc("strEndsWith", kern.NewGolangFunctor(endsWithStrFunc), kern.TypeBoolean, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamSource),
|
kern.NewFuncParam(kern.ParamSource),
|
||||||
NewFuncParam(kern.ParamSuffix),
|
kern.NewFuncParam(kern.ParamSuffix),
|
||||||
NewFuncParamFlag(strParamOther, PfRepeat),
|
kern.NewFuncParamFlag(strParamOther, kern.PfRepeat),
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.RegisterFunc("strUpper", kern.NewGolangFunctor(upperStrFunc), kern.TypeString, []kern.ExprFuncParam{
|
ctx.RegisterFunc("strUpper", kern.NewGolangFunctor(upperStrFunc), kern.TypeString, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamSource),
|
kern.NewFuncParam(kern.ParamSource),
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.RegisterFunc("strLower", kern.NewGolangFunctor(lowerStrFunc), kern.TypeString, []kern.ExprFuncParam{
|
ctx.RegisterFunc("strLower", kern.NewGolangFunctor(lowerStrFunc), kern.TypeString, []kern.ExprFuncParam{
|
||||||
NewFuncParam(kern.ParamSource),
|
kern.NewFuncParam(kern.ParamSource),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -116,8 +116,11 @@ func NewDictIterator(dict *kern.DictType, args []any) (it *DictIterator, err err
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
dictIt.makeKeys(*dict, sortType)
|
dictIt.makeKeys(*dict, sortType)
|
||||||
return dictIt, err
|
it = dictIt
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMapIterator(m map[any]any) (it *DictIterator) {
|
func NewMapIterator(m map[any]any) (it *DictIterator) {
|
||||||
@@ -139,7 +142,6 @@ func (it *DictIterator) TypeName() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (it *DictIterator) HasOperation(name string) bool {
|
func (it *DictIterator) HasOperation(name string) bool {
|
||||||
// yes := name == NextName || name == ResetName || name == IndexName || name == CountName || name == CurrentName
|
|
||||||
yes := slices.Contains([]string{kern.NextName, kern.ResetName, kern.IndexName, kern.CountName, kern.CurrentName, kern.CleanName, kern.KeyName, kern.ValueName}, name)
|
yes := slices.Contains([]string{kern.NextName, kern.ResetName, kern.IndexName, kern.CountName, kern.CurrentName, kern.CleanName, kern.KeyName, kern.ValueName}, name)
|
||||||
return yes
|
return yes
|
||||||
}
|
}
|
||||||
|
|||||||
-388
@@ -1,388 +0,0 @@
|
|||||||
// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
|
|
||||||
// All rights reserved.
|
|
||||||
|
|
||||||
// function.go
|
|
||||||
package expr
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.portale-stac.it/go-pkg/expr/kern"
|
|
||||||
"git.portale-stac.it/go-pkg/expr/scan"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ---- Function template
|
|
||||||
// type FuncTemplate func(ctx expr.ExprContext, name string, args map[string]any) (result any, err error)
|
|
||||||
|
|
||||||
// ---- Common functor definition
|
|
||||||
type BaseFunctor struct {
|
|
||||||
info kern.ExprFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
func (functor *BaseFunctor) ToString(opt kern.FmtOpt) (s string) {
|
|
||||||
if functor.info != nil {
|
|
||||||
s = functor.info.ToString(opt)
|
|
||||||
} else {
|
|
||||||
s = "func(){}"
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func (functor *BaseFunctor) GetParams() (params []kern.ExprFuncParam) {
|
|
||||||
if functor.info != nil {
|
|
||||||
return functor.info.Params()
|
|
||||||
} else {
|
|
||||||
return []kern.ExprFuncParam{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (functor *BaseFunctor) SetFunc(info kern.ExprFunc) {
|
|
||||||
functor.info = info
|
|
||||||
}
|
|
||||||
|
|
||||||
func (functor *BaseFunctor) GetFunc() kern.ExprFunc {
|
|
||||||
return functor.info
|
|
||||||
}
|
|
||||||
|
|
||||||
func (functor *BaseFunctor) GetDefinitionContext() kern.ExprContext {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Function Parameters
|
|
||||||
type paramFlags uint16
|
|
||||||
|
|
||||||
const (
|
|
||||||
PfDefault paramFlags = 1 << iota
|
|
||||||
PfOptional
|
|
||||||
PfRepeat
|
|
||||||
)
|
|
||||||
|
|
||||||
type funcParamInfo struct {
|
|
||||||
name string
|
|
||||||
flags paramFlags
|
|
||||||
defaultValue any
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFuncParam(name string) kern.ExprFuncParam {
|
|
||||||
return &funcParamInfo{name: name}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFuncParamFlag(name string, flags paramFlags) kern.ExprFuncParam {
|
|
||||||
return &funcParamInfo{name: name, flags: flags}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFuncParamFlagDef(name string, flags paramFlags, defValue any) *funcParamInfo {
|
|
||||||
return &funcParamInfo{name: name, flags: flags, defaultValue: defValue}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (param *funcParamInfo) Name() string {
|
|
||||||
return param.name
|
|
||||||
}
|
|
||||||
|
|
||||||
func (param *funcParamInfo) Type() string {
|
|
||||||
return kern.TypeAny
|
|
||||||
}
|
|
||||||
|
|
||||||
func (param *funcParamInfo) IsDefault() bool {
|
|
||||||
return (param.flags & PfDefault) != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (param *funcParamInfo) IsOptional() bool {
|
|
||||||
return (param.flags & PfOptional) != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (param *funcParamInfo) IsRepeat() bool {
|
|
||||||
return (param.flags & PfRepeat) != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (param *funcParamInfo) DefaultValue() any {
|
|
||||||
return param.defaultValue
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Functions
|
|
||||||
|
|
||||||
// funcInfo implements expr.ExprFunc
|
|
||||||
type funcInfo struct {
|
|
||||||
name string
|
|
||||||
minArgs int
|
|
||||||
maxArgs int
|
|
||||||
functor kern.Functor
|
|
||||||
formalParams []kern.ExprFuncParam
|
|
||||||
returnType string
|
|
||||||
}
|
|
||||||
|
|
||||||
func newFuncInfo(name string, functor kern.Functor, returnType string, params []kern.ExprFuncParam) (info *funcInfo, err error) {
|
|
||||||
var minArgs = 0
|
|
||||||
var maxArgs = 0
|
|
||||||
for _, p := range params {
|
|
||||||
if maxArgs == -1 {
|
|
||||||
return nil, fmt.Errorf("no more params can be specified after the ellipsis symbol: %q", p.Name())
|
|
||||||
}
|
|
||||||
if p.IsDefault() || p.IsOptional() {
|
|
||||||
maxArgs++
|
|
||||||
} else if maxArgs == minArgs {
|
|
||||||
minArgs++
|
|
||||||
maxArgs++
|
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("can't specify non-optional param after optional ones: %q", p.Name())
|
|
||||||
}
|
|
||||||
if p.IsRepeat() {
|
|
||||||
minArgs--
|
|
||||||
maxArgs = -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
info = &funcInfo{
|
|
||||||
name: name, minArgs: minArgs, maxArgs: maxArgs, functor: functor, returnType: returnType, formalParams: params,
|
|
||||||
}
|
|
||||||
functor.SetFunc(info)
|
|
||||||
return info, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (info *funcInfo) Params() []kern.ExprFuncParam {
|
|
||||||
return info.formalParams
|
|
||||||
}
|
|
||||||
|
|
||||||
func (info *funcInfo) ReturnType() string {
|
|
||||||
return info.returnType
|
|
||||||
}
|
|
||||||
|
|
||||||
func (info *funcInfo) ToString(opt kern.FmtOpt) string {
|
|
||||||
var sb strings.Builder
|
|
||||||
if len(info.Name()) == 0 {
|
|
||||||
sb.WriteString("func")
|
|
||||||
} else {
|
|
||||||
sb.WriteString(info.Name())
|
|
||||||
}
|
|
||||||
sb.WriteByte('(')
|
|
||||||
if info.formalParams != nil {
|
|
||||||
for i, p := range info.formalParams {
|
|
||||||
if i > 0 {
|
|
||||||
sb.WriteString(", ")
|
|
||||||
}
|
|
||||||
sb.WriteString(p.Name())
|
|
||||||
|
|
||||||
if p.IsDefault() {
|
|
||||||
sb.WriteByte('=')
|
|
||||||
if s, ok := p.DefaultValue().(string); ok {
|
|
||||||
sb.WriteByte('"')
|
|
||||||
sb.WriteString(s)
|
|
||||||
sb.WriteByte('"')
|
|
||||||
} else {
|
|
||||||
sb.WriteString(fmt.Sprintf("%v", p.DefaultValue()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if info.maxArgs < 0 {
|
|
||||||
sb.WriteString(" ...")
|
|
||||||
}
|
|
||||||
sb.WriteString("):")
|
|
||||||
if len(info.returnType) > 0 {
|
|
||||||
sb.WriteString(info.returnType)
|
|
||||||
} else {
|
|
||||||
sb.WriteString(kern.TypeAny)
|
|
||||||
}
|
|
||||||
sb.WriteString("{}")
|
|
||||||
return sb.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (info *funcInfo) Name() string {
|
|
||||||
return info.name
|
|
||||||
}
|
|
||||||
|
|
||||||
func (info *funcInfo) MinArgs() int {
|
|
||||||
return info.minArgs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (info *funcInfo) MaxArgs() int {
|
|
||||||
return info.maxArgs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (info *funcInfo) Functor() kern.Functor {
|
|
||||||
return info.functor
|
|
||||||
}
|
|
||||||
|
|
||||||
func (info *funcInfo) AllocContext(parentCtx kern.ExprContext) (ctx kern.ExprContext) {
|
|
||||||
if defCtx := info.functor.GetDefinitionContext(); defCtx != nil {
|
|
||||||
ctx = defCtx.Clone()
|
|
||||||
ctx.SetParent(defCtx)
|
|
||||||
} else {
|
|
||||||
ctx = parentCtx.Clone()
|
|
||||||
ctx.SetParent(parentCtx)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (info *funcInfo) ParamSpec(paramName string) kern.ExprFuncParam {
|
|
||||||
for _, spec := range info.formalParams {
|
|
||||||
if spec.Name() == paramName {
|
|
||||||
return spec
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func initActualParams(ctx kern.ExprContext, info kern.ExprFunc, callTerm *scan.Term) (actualParams map[string]any, err error) {
|
|
||||||
var varArgs []any
|
|
||||||
var varName string
|
|
||||||
|
|
||||||
namedParamsStarted := false
|
|
||||||
|
|
||||||
formalParams := info.Params()
|
|
||||||
actualParams = make(map[string]any, len(formalParams))
|
|
||||||
if callTerm == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, tree := range callTerm.Children {
|
|
||||||
var paramValue any
|
|
||||||
paramCtx := ctx.Clone()
|
|
||||||
if paramValue, err = tree.Compute(paramCtx); err != nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if paramName, namedParam := kern.GetAssignVarName(tree); namedParam {
|
|
||||||
if info.ParamSpec(paramName) == nil {
|
|
||||||
err = fmt.Errorf("%s(): unknown param %q", info.Name(), paramName)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
actualParams[paramName] = paramValue
|
|
||||||
namedParamsStarted = true
|
|
||||||
} else if !namedParamsStarted {
|
|
||||||
if varArgs != nil {
|
|
||||||
varArgs = append(varArgs, paramValue)
|
|
||||||
} else if i < len(formalParams) {
|
|
||||||
spec := formalParams[i]
|
|
||||||
if spec.IsRepeat() {
|
|
||||||
varArgs = make([]any, 0, len(callTerm.Children)-i)
|
|
||||||
varArgs = append(varArgs, paramValue)
|
|
||||||
varName = spec.Name()
|
|
||||||
} else {
|
|
||||||
actualParams[spec.Name()] = paramValue
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = kern.ErrTooManyParams(info.Name(), len(formalParams), len(callTerm.Children))
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = fmt.Errorf("%s(): positional param nr %d not allowed after named params", info.Name(), i+1)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
if varArgs != nil {
|
|
||||||
actualParams[varName] = varArgs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (info *funcInfo) PrepareCall(name string, actualParams map[string]any) (err error) {
|
|
||||||
passedCount := len(actualParams)
|
|
||||||
if info.MinArgs() > passedCount {
|
|
||||||
err = kern.ErrTooFewParams(name, info.MinArgs(), info.MaxArgs(), passedCount)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if passedCount < len(info.formalParams) {
|
|
||||||
for _, p := range info.formalParams {
|
|
||||||
if _, exists := actualParams[p.Name()]; !exists {
|
|
||||||
if !p.IsDefault() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if p.IsRepeat() {
|
|
||||||
varArgs := make([]any, 1)
|
|
||||||
varArgs[0] = p.DefaultValue()
|
|
||||||
actualParams[p.Name()] = varArgs
|
|
||||||
} else {
|
|
||||||
actualParams[p.Name()] = p.DefaultValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if info.MaxArgs() >= 0 && info.MaxArgs() < len(actualParams) {
|
|
||||||
err = kern.ErrTooManyParams(name, info.MaxArgs(), len(actualParams))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----- Call a function ---
|
|
||||||
|
|
||||||
// func getAssignVarName(t *term) (name string, ok bool) {
|
|
||||||
// if ok = t.symbol() == SymEqual; ok {
|
|
||||||
// name = t.children[0].source()
|
|
||||||
// }
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func CallFunctionByTerm(parentCtx expr.ExprContext, name string, callTerm *term) (result any, err error) {
|
|
||||||
// var actualParams map[string]any
|
|
||||||
// if info, exists := GetFuncInfo(parentCtx, name); exists {
|
|
||||||
// if actualParams, err = initActualParams(parentCtx, info, callTerm); err == nil {
|
|
||||||
// ctx := info.AllocContext(parentCtx)
|
|
||||||
// if err = info.PrepareCall(name, actualParams); err == nil {
|
|
||||||
// functor := info.Functor()
|
|
||||||
// result, err = functor.InvokeNamed(ctx, name, actualParams)
|
|
||||||
// exportObjectsToParent(ctx)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// err = fmt.Errorf("unknown function %s()", name)
|
|
||||||
// }
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func CallFunctionByArgs(parentCtx expr.ExprContext, name string, args []any) (result any, err error) {
|
|
||||||
// var actualParams map[string]any
|
|
||||||
// if info, exists := GetFuncInfo(parentCtx, name); exists {
|
|
||||||
// functor := info.Functor()
|
|
||||||
// actualParams = bindActualParams(functor, args)
|
|
||||||
// ctx := info.AllocContext(parentCtx)
|
|
||||||
// if err = info.PrepareCall(name, actualParams); err == nil {
|
|
||||||
// result, err = functor.InvokeNamed(ctx, name, actualParams)
|
|
||||||
// exportObjectsToParent(ctx)
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// err = fmt.Errorf("unknown function %s()", name)
|
|
||||||
// }
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func CallFunctionByParams(parentCtx expr.ExprContext, name string, actualParams map[string]any) (result any, err error) {
|
|
||||||
// //var actualParams map[string]any
|
|
||||||
// if info, exists := GetFuncInfo(parentCtx, name); exists {
|
|
||||||
// functor := info.Functor()
|
|
||||||
// ctx := info.AllocContext(parentCtx)
|
|
||||||
// if err = info.PrepareCall(name, actualParams); err == nil {
|
|
||||||
// result, err = functor.InvokeNamed(ctx, name, actualParams)
|
|
||||||
// exportObjectsToParent(ctx)
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// err = fmt.Errorf("unknown function %s()", name)
|
|
||||||
// }
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func GetParam(args map[string]any, paramName string, paramNum int) (value any, exists bool) {
|
|
||||||
// if value, exists = args[paramName]; !exists {
|
|
||||||
// if paramNum > 0 && paramNum <= len(args) {
|
|
||||||
// value, exists = args["arg"+strconv.Itoa(paramNum)]
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func bindActualParams(functor Functor, args []any) (actualParams map[string]any) {
|
|
||||||
// formalParams := functor.GetParams()
|
|
||||||
// actualParams = make(map[string]any, len(args))
|
|
||||||
// for i, arg := range args {
|
|
||||||
// if i < len(formalParams) {
|
|
||||||
// actualParams[formalParams[i].Name()] = arg
|
|
||||||
// } else {
|
|
||||||
// actualParams["arg"+strconv.Itoa(i+1)] = arg
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
+1
-1
@@ -45,7 +45,7 @@ func EvalStringV(source string, args []Arg) (result any, err error) {
|
|||||||
functor := kern.NewGolangFunctor(f)
|
functor := kern.NewGolangFunctor(f)
|
||||||
// ctx.RegisterFunc(arg.Name, functor, 0, -1)
|
// ctx.RegisterFunc(arg.Name, functor, 0, -1)
|
||||||
ctx.RegisterFunc(arg.Name, functor, kern.TypeAny, []kern.ExprFuncParam{
|
ctx.RegisterFunc(arg.Name, functor, kern.TypeAny, []kern.ExprFuncParam{
|
||||||
NewFuncParamFlagDef(kern.ParamValue, PfDefault|PfRepeat, 0),
|
kern.NewFuncParamFlagDef(kern.ParamValue, kern.PfDefault|kern.PfRepeat, 0),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
err = fmt.Errorf("invalid function specification: %q", arg.Name)
|
err = fmt.Errorf("invalid function specification: %q", arg.Name)
|
||||||
|
|||||||
+20
-2
@@ -5,10 +5,13 @@
|
|||||||
package expr
|
package expr
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"slices"
|
||||||
|
|
||||||
"git.portale-stac.it/go-pkg/expr/kern"
|
"git.portale-stac.it/go-pkg/expr/kern"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewIterator(value any) (it kern.Iterator, err error) {
|
func NewIterator(ctx kern.ExprContext, value any, args map[string]any) (it kern.Iterator, err error) {
|
||||||
if value == nil {
|
if value == nil {
|
||||||
return NewArrayIterator([]any{}), nil
|
return NewArrayIterator([]any{}), nil
|
||||||
}
|
}
|
||||||
@@ -21,9 +24,24 @@ func NewIterator(value any) (it kern.Iterator, err error) {
|
|||||||
case []any:
|
case []any:
|
||||||
it = NewArrayIterator(v)
|
it = NewArrayIterator(v)
|
||||||
case kern.Iterator:
|
case kern.Iterator:
|
||||||
it = v
|
// it = v
|
||||||
|
var op kern.Functor
|
||||||
|
if len(args) >= 1 {
|
||||||
|
if opArg, ok := args["op"]; ok {
|
||||||
|
if op, ok = opArg.(kern.Functor); !ok {
|
||||||
|
err = fmt.Errorf("the 'op' argument must be a kern.Functor, got %T", opArg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
it, err = NewIterIter(v, ctx, op, args)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
it = NewArrayIterator([]any{value})
|
it = NewArrayIterator([]any{value})
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func HasStandardOperation(name string) bool {
|
||||||
|
return slices.Contains([]string{kern.NextName, kern.ResetName, kern.IndexName, kern.CountName, kern.CurrentName, kern.CleanName}, name)
|
||||||
|
}
|
||||||
|
|||||||
+132
@@ -0,0 +1,132 @@
|
|||||||
|
// Copyright (c) 2024-2026 Celestino Amoroso (celestino.amoroso@gmail.com).
|
||||||
|
// All rights reserved.
|
||||||
|
|
||||||
|
// iter-iter.go
|
||||||
|
package expr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"git.portale-stac.it/go-pkg/expr/kern"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IterIter struct {
|
||||||
|
it kern.Iterator
|
||||||
|
count int64
|
||||||
|
index int64
|
||||||
|
ctx kern.ExprContext
|
||||||
|
op kern.Functor
|
||||||
|
opName string
|
||||||
|
args map[string]any
|
||||||
|
current any
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewIterIter(it kern.Iterator, ctx kern.ExprContext, op kern.Functor, args map[string]any) (iter kern.Iterator, err error) {
|
||||||
|
var opName string
|
||||||
|
if op != nil {
|
||||||
|
if f := op.GetFunc(); f != nil {
|
||||||
|
opName = f.Name()
|
||||||
|
// } else {
|
||||||
|
// return nil, fmt.Errorf("invalid functor argument for iter-iter: expected kern.Functor, got %T", args["op"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(opName) == 0 {
|
||||||
|
opName = "anonymous"
|
||||||
|
}
|
||||||
|
iter = &IterIter{it: it, count: 0, index: -1, ctx: ctx, op: op, opName: opName, args: args}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *IterIter) String() string {
|
||||||
|
return fmt.Sprintf("$(%s)", it.it)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *IterIter) TypeName() string {
|
||||||
|
return "IterIter"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *IterIter) HasOperation(name string) bool {
|
||||||
|
return HasStandardOperation(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *IterIter) CallOperation(name string, args map[string]any) (v any, err error) {
|
||||||
|
switch name {
|
||||||
|
case kern.NextName:
|
||||||
|
v, err = it.Next()
|
||||||
|
case kern.ResetName:
|
||||||
|
err = it.Reset()
|
||||||
|
case kern.CleanName:
|
||||||
|
err = it.Clean()
|
||||||
|
case kern.IndexName:
|
||||||
|
v = int64(it.Index())
|
||||||
|
case kern.CurrentName:
|
||||||
|
v, err = it.Current()
|
||||||
|
case kern.CountName:
|
||||||
|
v = it.count
|
||||||
|
default:
|
||||||
|
err = kern.ErrNoOperation(name)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *IterIter) Current() (item any, err error) {
|
||||||
|
if it.current != nil {
|
||||||
|
item = it.current
|
||||||
|
} else if it.op != nil {
|
||||||
|
if item, err = it.op.InvokeNamed(it.ctx, it.opName, it.args); err == nil {
|
||||||
|
it.current = item
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var exists bool
|
||||||
|
if it.current, exists = it.ctx.GetVar("_"); !exists {
|
||||||
|
err = fmt.Errorf("current item not available")
|
||||||
|
} else {
|
||||||
|
item = it.current
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *IterIter) Next() (item any, err error) {
|
||||||
|
var src any
|
||||||
|
|
||||||
|
it.current = nil
|
||||||
|
ctx := it.ctx
|
||||||
|
for src, err = it.it.Next(); src == nil && err == nil; src, err = it.it.Next() {
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
if src == nil {
|
||||||
|
err = io.EOF
|
||||||
|
} else {
|
||||||
|
ctx.UnsafeSetVar("_", src)
|
||||||
|
ctx.UnsafeSetVar("__", it.it.Index())
|
||||||
|
ctx.UnsafeSetVar("_#", it.it.Count())
|
||||||
|
item, err = it.Current()
|
||||||
|
ctx.DeleteVar("_#")
|
||||||
|
ctx.DeleteVar("__")
|
||||||
|
ctx.DeleteVar("_")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *IterIter) Index() int64 {
|
||||||
|
return it.index
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *IterIter) Count() int64 {
|
||||||
|
return it.count
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *IterIter) Reset() error {
|
||||||
|
it.index = -1
|
||||||
|
it.count = 0
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (it *IterIter) Clean() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -5,19 +5,19 @@
|
|||||||
package kern
|
package kern
|
||||||
|
|
||||||
// ---- Linking with Go functions
|
// ---- Linking with Go functions
|
||||||
type golangFunctor struct {
|
type GolangFunctor struct {
|
||||||
BaseFunctor
|
BaseFunctor
|
||||||
f FuncTemplate
|
f FuncTemplate
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGolangFunctor(f FuncTemplate) *golangFunctor {
|
func NewGolangFunctor(f FuncTemplate) *GolangFunctor {
|
||||||
return &golangFunctor{f: f}
|
return &GolangFunctor{f: f}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (functor *golangFunctor) TypeName() string {
|
func (functor *GolangFunctor) TypeName() string {
|
||||||
return "GoFunctor"
|
return "GoFunctor"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (functor *golangFunctor) InvokeNamed(ctx ExprContext, name string, args map[string]any) (result any, err error) {
|
func (functor *GolangFunctor) InvokeNamed(ctx ExprContext, name string, args map[string]any) (result any, err error) {
|
||||||
return functor.f(ctx, name, args)
|
return functor.f(ctx, name, args)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,3 +37,8 @@ type ExprFunc interface {
|
|||||||
PrepareCall(name string, actualParams map[string]any) (err error)
|
PrepareCall(name string, actualParams map[string]any) (err error)
|
||||||
AllocContext(parentCtx ExprContext) (ctx ExprContext)
|
AllocContext(parentCtx ExprContext) (ctx ExprContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsFunctor(v any) (ok bool) {
|
||||||
|
_, ok = v.(Functor)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,164 @@
|
|||||||
|
// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
|
||||||
|
// All rights reserved.
|
||||||
|
|
||||||
|
// func-info.go
|
||||||
|
package kern
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// --- Functions
|
||||||
|
|
||||||
|
// FuncInfo implements expr.ExprFunc
|
||||||
|
type FuncInfo struct {
|
||||||
|
name string
|
||||||
|
minArgs int
|
||||||
|
maxArgs int
|
||||||
|
functor Functor
|
||||||
|
formalParams []ExprFuncParam
|
||||||
|
returnType string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFuncInfo(name string, functor Functor, returnType string, params []ExprFuncParam) (info *FuncInfo, err error) {
|
||||||
|
var minArgs = 0
|
||||||
|
var maxArgs = 0
|
||||||
|
for _, p := range params {
|
||||||
|
if maxArgs == -1 {
|
||||||
|
return nil, fmt.Errorf("no more params can be specified after the ellipsis symbol: %q", p.Name())
|
||||||
|
}
|
||||||
|
if p.IsDefault() || p.IsOptional() {
|
||||||
|
maxArgs++
|
||||||
|
} else if maxArgs == minArgs {
|
||||||
|
minArgs++
|
||||||
|
maxArgs++
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("can't specify non-optional param after optional ones: %q", p.Name())
|
||||||
|
}
|
||||||
|
if p.IsRepeat() {
|
||||||
|
minArgs--
|
||||||
|
maxArgs = -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
info = &FuncInfo{
|
||||||
|
name: name, minArgs: minArgs, maxArgs: maxArgs, functor: functor, returnType: returnType, formalParams: params,
|
||||||
|
}
|
||||||
|
functor.SetFunc(info)
|
||||||
|
return info, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (info *FuncInfo) Params() []ExprFuncParam {
|
||||||
|
return info.formalParams
|
||||||
|
}
|
||||||
|
|
||||||
|
func (info *FuncInfo) ReturnType() string {
|
||||||
|
return info.returnType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (info *FuncInfo) ToString(opt FmtOpt) string {
|
||||||
|
var sb strings.Builder
|
||||||
|
if len(info.Name()) == 0 {
|
||||||
|
sb.WriteString("func")
|
||||||
|
} else {
|
||||||
|
sb.WriteString(info.Name())
|
||||||
|
}
|
||||||
|
sb.WriteByte('(')
|
||||||
|
if info.formalParams != nil {
|
||||||
|
for i, p := range info.formalParams {
|
||||||
|
if i > 0 {
|
||||||
|
sb.WriteString(", ")
|
||||||
|
}
|
||||||
|
sb.WriteString(p.Name())
|
||||||
|
|
||||||
|
if p.IsDefault() {
|
||||||
|
sb.WriteByte('=')
|
||||||
|
if s, ok := p.DefaultValue().(string); ok {
|
||||||
|
sb.WriteByte('"')
|
||||||
|
sb.WriteString(s)
|
||||||
|
sb.WriteByte('"')
|
||||||
|
} else {
|
||||||
|
sb.WriteString(fmt.Sprintf("%v", p.DefaultValue()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if info.maxArgs < 0 {
|
||||||
|
sb.WriteString(" ...")
|
||||||
|
}
|
||||||
|
sb.WriteString("):")
|
||||||
|
if len(info.returnType) > 0 {
|
||||||
|
sb.WriteString(info.returnType)
|
||||||
|
} else {
|
||||||
|
sb.WriteString(TypeAny)
|
||||||
|
}
|
||||||
|
sb.WriteString("{}")
|
||||||
|
return sb.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (info *FuncInfo) Name() string {
|
||||||
|
return info.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (info *FuncInfo) MinArgs() int {
|
||||||
|
return info.minArgs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (info *FuncInfo) MaxArgs() int {
|
||||||
|
return info.maxArgs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (info *FuncInfo) Functor() Functor {
|
||||||
|
return info.functor
|
||||||
|
}
|
||||||
|
|
||||||
|
func (info *FuncInfo) AllocContext(parentCtx ExprContext) (ctx ExprContext) {
|
||||||
|
if defCtx := info.functor.GetDefinitionContext(); defCtx != nil {
|
||||||
|
ctx = defCtx.Clone()
|
||||||
|
ctx.SetParent(defCtx)
|
||||||
|
} else {
|
||||||
|
ctx = parentCtx.Clone()
|
||||||
|
ctx.SetParent(parentCtx)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (info *FuncInfo) ParamSpec(paramName string) ExprFuncParam {
|
||||||
|
for _, spec := range info.formalParams {
|
||||||
|
if spec.Name() == paramName {
|
||||||
|
return spec
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (info *FuncInfo) PrepareCall(name string, actualParams map[string]any) (err error) {
|
||||||
|
passedCount := len(actualParams)
|
||||||
|
if info.MinArgs() > passedCount {
|
||||||
|
err = ErrTooFewParams(name, info.MinArgs(), info.MaxArgs(), passedCount)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if passedCount < len(info.formalParams) {
|
||||||
|
for _, p := range info.formalParams {
|
||||||
|
if _, exists := actualParams[p.Name()]; !exists {
|
||||||
|
if !p.IsDefault() {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if p.IsRepeat() {
|
||||||
|
varArgs := make([]any, 1)
|
||||||
|
varArgs[0] = p.DefaultValue()
|
||||||
|
actualParams[p.Name()] = varArgs
|
||||||
|
} else {
|
||||||
|
actualParams[p.Name()] = p.DefaultValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.MaxArgs() >= 0 && info.MaxArgs() < len(actualParams) {
|
||||||
|
err = ErrTooManyParams(name, info.MaxArgs(), len(actualParams))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
+5
-10
@@ -14,11 +14,6 @@ type FuncTemplate func(ctx ExprContext, name string, args map[string]any) (resul
|
|||||||
|
|
||||||
type DeepFuncTemplate func(a, b any) (eq bool, err error)
|
type DeepFuncTemplate func(a, b any) (eq bool, err error)
|
||||||
|
|
||||||
func IsFunctor(v any) (ok bool) {
|
|
||||||
_, ok = v.(Functor)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Common functor definition
|
// ---- Common functor definition
|
||||||
type BaseFunctor struct {
|
type BaseFunctor struct {
|
||||||
info ExprFunc
|
info ExprFunc
|
||||||
@@ -54,17 +49,17 @@ func (functor *BaseFunctor) GetDefinitionContext() ExprContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---- Function Parameters
|
// ---- Function Parameters
|
||||||
type paramFlags uint16
|
type FuncParamFlags uint16
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PfDefault paramFlags = 1 << iota
|
PfDefault FuncParamFlags = 1 << iota
|
||||||
PfOptional
|
PfOptional
|
||||||
PfRepeat
|
PfRepeat
|
||||||
)
|
)
|
||||||
|
|
||||||
type funcParamInfo struct {
|
type funcParamInfo struct {
|
||||||
name string
|
name string
|
||||||
flags paramFlags
|
flags FuncParamFlags
|
||||||
defaultValue any
|
defaultValue any
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,11 +67,11 @@ func NewFuncParam(name string) ExprFuncParam {
|
|||||||
return &funcParamInfo{name: name}
|
return &funcParamInfo{name: name}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFuncParamFlag(name string, flags paramFlags) ExprFuncParam {
|
func NewFuncParamFlag(name string, flags FuncParamFlags) ExprFuncParam {
|
||||||
return &funcParamInfo{name: name, flags: flags}
|
return &funcParamInfo{name: name, flags: flags}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFuncParamFlagDef(name string, flags paramFlags, defValue any) *funcParamInfo {
|
func NewFuncParamFlagDef(name string, flags FuncParamFlags, defValue any) *funcParamInfo {
|
||||||
return &funcParamInfo{name: name, flags: flags, defaultValue: defValue}
|
return &funcParamInfo{name: name, flags: flags, defaultValue: defValue}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -70,14 +70,14 @@ func evalFuncDef(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
|
|||||||
paramList := make([]kern.ExprFuncParam, 0, len(opTerm.Children))
|
paramList := make([]kern.ExprFuncParam, 0, len(opTerm.Children))
|
||||||
for _, param := range opTerm.Children {
|
for _, param := range opTerm.Children {
|
||||||
var defValue any
|
var defValue any
|
||||||
flags := paramFlags(0)
|
flags := kern.FuncParamFlags(0)
|
||||||
if len(param.Children) > 0 {
|
if len(param.Children) > 0 {
|
||||||
flags |= PfDefault
|
flags |= kern.PfDefault
|
||||||
if defValue, err = param.Children[0].Compute(ctx); err != nil {
|
if defValue, err = param.Children[0].Compute(ctx); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
info := NewFuncParamFlagDef(param.Source(), flags, defValue)
|
info := kern.NewFuncParamFlagDef(param.Source(), flags, defValue)
|
||||||
paramList = append(paramList, info)
|
paramList = append(paramList, info)
|
||||||
}
|
}
|
||||||
v = newExprFunctor(ast, paramList, ctx)
|
v = newExprFunctor(ast, paramList, ctx)
|
||||||
|
|||||||
+55
-7
@@ -5,7 +5,9 @@
|
|||||||
package expr
|
package expr
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"slices"
|
"slices"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.portale-stac.it/go-pkg/expr/kern"
|
"git.portale-stac.it/go-pkg/expr/kern"
|
||||||
@@ -125,7 +127,7 @@ func evalIterator(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
|
|||||||
} else {
|
} else {
|
||||||
if dictIt, ok := firstChildValue.(*kern.DictType); ok {
|
if dictIt, ok := firstChildValue.(*kern.DictType); ok {
|
||||||
var args []any
|
var args []any
|
||||||
if args, err = evalSibling(ctx, opTerm.Children, nil); err == nil {
|
if args, err = evalSiblings(ctx, opTerm.Children, nil); err == nil {
|
||||||
v, err = NewDictIterator(dictIt, args)
|
v, err = NewDictIterator(dictIt, args)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -134,24 +136,70 @@ func evalIterator(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
|
|||||||
}
|
}
|
||||||
} else if list, ok := firstChildValue.(*kern.ListType); ok {
|
} else if list, ok := firstChildValue.(*kern.ListType); ok {
|
||||||
var args []any
|
var args []any
|
||||||
if args, err = evalSibling(ctx, opTerm.Children, nil); err == nil {
|
if args, err = evalSiblings(ctx, opTerm.Children, nil); err == nil {
|
||||||
v = NewListIterator(list, args)
|
v = NewListIterator(list, args)
|
||||||
}
|
}
|
||||||
} else if intVal, ok := firstChildValue.(int64); ok {
|
} else if intVal, ok := firstChildValue.(int64); ok {
|
||||||
var args []any
|
var args []any
|
||||||
if args, err = evalSibling(ctx, opTerm.Children, intVal); err == nil {
|
if args, err = evalSiblings(ctx, opTerm.Children, intVal); err == nil {
|
||||||
v, err = NewIntIterator(args)
|
v, err = NewIntIterator(args)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var list []any
|
var siblings []any
|
||||||
if list, err = evalSibling(ctx, opTerm.Children, firstChildValue); err == nil {
|
if siblings, err = evalSiblings(ctx, opTerm.Children, firstChildValue); err == nil {
|
||||||
v = NewArrayIterator(list)
|
// if v, err = evalIterIter(ctx, firstChildValue, siblings); err == nil && v == nil {
|
||||||
|
// if it, ok := firstChildValue.(kern.Iterator); ok {
|
||||||
|
// if len(siblings) > 1 {
|
||||||
|
// if op, ok := siblings[1].(kern.Functor); ok {
|
||||||
|
// args := make(map[string]any, len(siblings)-2)
|
||||||
|
// for i, arg := range siblings[2:] {
|
||||||
|
// args["arg"+strconv.Itoa(i+1)] = arg
|
||||||
|
// }
|
||||||
|
// v, err = NewIterIter(it, ctx, op, args)
|
||||||
|
// } else {
|
||||||
|
// err = opTerm.Children[1].Errorf("the first sibling parameter must be a functor to be used as operation for the iterator")
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// v, err = NewIterIter(it, ctx, nil, nil)
|
||||||
|
// }
|
||||||
|
if v, err = evalIterIter(ctx, firstChildValue, siblings); err == nil && v == nil {
|
||||||
|
v = NewArrayIterator(siblings)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func evalSibling(ctx kern.ExprContext, terms []*scan.Term, firstChildValue any) (list []any, err error) {
|
func evalIterIter(ctx kern.ExprContext, firstChildValue any, siblings []any) (v any, err error) {
|
||||||
|
var op kern.Functor
|
||||||
|
var args map[string]any
|
||||||
|
|
||||||
|
if it, ok := firstChildValue.(kern.Iterator); ok {
|
||||||
|
if len(siblings) > 1 {
|
||||||
|
if op, ok = siblings[1].(kern.Functor); ok {
|
||||||
|
args = make(map[string]any, len(siblings)-2)
|
||||||
|
for i, arg := range siblings[2:] {
|
||||||
|
switch a := arg.(type) {
|
||||||
|
case *kern.DictType:
|
||||||
|
for keyAny, item := range *a {
|
||||||
|
if key, ok := keyAny.(string); ok {
|
||||||
|
args[key] = item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
args["arg"+strconv.Itoa(i+1)] = arg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if op == nil {
|
||||||
|
return nil, fmt.Errorf("the first sibling parameter must be a functor to be used as operation for the iterator")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v, err = NewIterIter(it, ctx, op, args)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func evalSiblings(ctx kern.ExprContext, terms []*scan.Term, firstChildValue any) (list []any, err error) {
|
||||||
items := make([]any, 0, len(terms))
|
items := make([]any, 0, len(terms))
|
||||||
for i, tree := range terms {
|
for i, tree := range terms {
|
||||||
var param any
|
var param any
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ func evalBuiltin(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
|
|||||||
} else {
|
} else {
|
||||||
var moduleSpec any
|
var moduleSpec any
|
||||||
var it kern.Iterator
|
var it kern.Iterator
|
||||||
if it, err = NewIterator(childValue); err != nil {
|
if it, err = NewIterator(ctx, childValue, nil); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for moduleSpec, err = it.Next(); err == nil; moduleSpec, err = it.Next() {
|
for moduleSpec, err = it.Next(); err == nil; moduleSpec, err = it.Next() {
|
||||||
|
|||||||
+1
-1
@@ -111,7 +111,7 @@ func evalAssignDefault(ctx kern.ExprContext, opTerm *scan.Term) (v any, err erro
|
|||||||
if functor, ok := rightValue.(kern.Functor); ok {
|
if functor, ok := rightValue.(kern.Functor); ok {
|
||||||
//ctx.RegisterFunc(leftTerm.source(), functor, 0, -1)
|
//ctx.RegisterFunc(leftTerm.source(), functor, 0, -1)
|
||||||
ctx.RegisterFunc(leftTerm.Source(), functor, kern.TypeAny, []kern.ExprFuncParam{
|
ctx.RegisterFunc(leftTerm.Source(), functor, kern.TypeAny, []kern.ExprFuncParam{
|
||||||
NewFuncParamFlag(kern.ParamValue, PfDefault|PfRepeat),
|
kern.NewFuncParamFlag(kern.ParamValue, kern.PfDefault|kern.PfRepeat),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
v = rightValue
|
v = rightValue
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ func evalDigest(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if it, err = NewIterator(leftValue); err != nil {
|
if it, err = NewIterator(ctx, leftValue, nil); err != nil {
|
||||||
return nil, fmt.Errorf("left operand of DIGEST must be an iterable data-source; got %s", kern.TypeName(leftValue))
|
return nil, fmt.Errorf("left operand of DIGEST must be an iterable data-source; got %s", kern.TypeName(leftValue))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -28,6 +28,7 @@ func evalFilter(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
|
|||||||
var leftValue, rightValue any
|
var leftValue, rightValue any
|
||||||
var it kern.Iterator
|
var it kern.Iterator
|
||||||
var item any
|
var item any
|
||||||
|
var ok bool
|
||||||
|
|
||||||
if err = opTerm.CheckOperands(); err != nil {
|
if err = opTerm.CheckOperands(); err != nil {
|
||||||
return
|
return
|
||||||
@@ -37,9 +38,11 @@ func evalFilter(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if it, err = NewIterator(leftValue); err != nil {
|
if it, ok = leftValue.(kern.Iterator); !ok {
|
||||||
|
if it, err = NewIterator(ctx, leftValue, nil); err != nil {
|
||||||
return nil, fmt.Errorf("left operand of FILTER must be an iterable data-source; got %s", kern.TypeName(leftValue))
|
return nil, fmt.Errorf("left operand of FILTER must be an iterable data-source; got %s", kern.TypeName(leftValue))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
values := kern.NewListA()
|
values := kern.NewListA()
|
||||||
for item, err = it.Next(); err == nil; item, err = it.Next() {
|
for item, err = it.Next(); err == nil; item, err = it.Next() {
|
||||||
|
|||||||
+1
-1
@@ -40,7 +40,7 @@ func evalGroupBy(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if it, err = NewIterator(leftValue); err != nil {
|
if it, err = NewIterator(ctx, leftValue, nil); err != nil {
|
||||||
return nil, fmt.Errorf("left operand of MAP must be an iterable data-source; got %s", kern.TypeName(leftValue))
|
return nil, fmt.Errorf("left operand of MAP must be an iterable data-source; got %s", kern.TypeName(leftValue))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -41,11 +41,11 @@ func evalJoin(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if itLeft, err = NewIterator(leftValue); err != nil {
|
if itLeft, err = NewIterator(ctx, leftValue, nil); err != nil {
|
||||||
return nil, fmt.Errorf("left operand of JOIN must be an iterable data-source; got %s", kern.TypeName(leftValue))
|
return nil, fmt.Errorf("left operand of JOIN must be an iterable data-source; got %s", kern.TypeName(leftValue))
|
||||||
}
|
}
|
||||||
|
|
||||||
if itRight, err = NewIterator(rightValue); err != nil {
|
if itRight, err = NewIterator(ctx, rightValue, nil); err != nil {
|
||||||
return nil, fmt.Errorf("right operand of JOIN must be an iterable data-source; got %s", kern.TypeName(rightValue))
|
return nil, fmt.Errorf("right operand of JOIN must be an iterable data-source; got %s", kern.TypeName(rightValue))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ func evalMap(ctx kern.ExprContext, opTerm *scan.Term) (v any, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if it, err = NewIterator(leftValue); err != nil {
|
if it, err = NewIterator(ctx, leftValue, nil); err != nil {
|
||||||
return nil, fmt.Errorf("left operand of MAP must be an iterable data-source; got %s", kern.TypeName(leftValue))
|
return nil, fmt.Errorf("left operand of MAP must be an iterable data-source; got %s", kern.TypeName(leftValue))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -100,7 +100,7 @@ func importPluginFromSearchPath(ctx kern.ExprContext, name any) (count int, err
|
|||||||
var it kern.Iterator
|
var it kern.Iterator
|
||||||
dirList := buildSearchDirList(ctx, "plugin", ENV_EXPR_PLUGIN_PATH)
|
dirList := buildSearchDirList(ctx, "plugin", ENV_EXPR_PLUGIN_PATH)
|
||||||
count = 0
|
count = 0
|
||||||
if it, err = NewIterator(name); err != nil {
|
if it, err = NewIterator(ctx, name, nil); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for moduleSpec, err = it.Next(); err == nil; moduleSpec, err = it.Next() {
|
for moduleSpec, err = it.Next(); err == nil; moduleSpec, err = it.Next() {
|
||||||
|
|||||||
+3
-3
@@ -200,12 +200,12 @@ func (ctx *SimpleStore) GetLocalFuncInfo(name string) (info kern.ExprFunc, exist
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *SimpleStore) RegisterFuncInfo(info kern.ExprFunc) {
|
func (ctx *SimpleStore) RegisterFuncInfo(info kern.ExprFunc) {
|
||||||
ctx.funcStore[info.Name()], _ = info.(*funcInfo)
|
ctx.funcStore[info.Name()], _ = info.(*kern.FuncInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *SimpleStore) RegisterFunc(name string, functor kern.Functor, returnType string, params []kern.ExprFuncParam) (exprFunc kern.ExprFunc, err error) {
|
func (ctx *SimpleStore) RegisterFunc(name string, functor kern.Functor, returnType string, params []kern.ExprFuncParam) (exprFunc kern.ExprFunc, err error) {
|
||||||
var info *funcInfo
|
var info *kern.FuncInfo
|
||||||
if info, err = newFuncInfo(name, functor, returnType, params); err == nil {
|
if info, err = kern.NewFuncInfo(name, functor, returnType, params); err == nil {
|
||||||
ctx.funcStore[name] = info
|
ctx.funcStore[name] = info
|
||||||
exprFunc = info
|
exprFunc = info
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -100,7 +100,7 @@ func TestGoFunction(t *testing.T) {
|
|||||||
|
|
||||||
ctx := NewSimpleStoreWithoutGlobalContext()
|
ctx := NewSimpleStoreWithoutGlobalContext()
|
||||||
ctx.RegisterFunc("myName", kern.NewGolangFunctor(myName), kern.TypeString, []kern.ExprFuncParam{
|
ctx.RegisterFunc("myName", kern.NewGolangFunctor(myName), kern.TypeString, []kern.ExprFuncParam{
|
||||||
NewFuncParamFlagDef("name", PfOptional|PfDefault, "Celestino Amoroso"),
|
kern.NewFuncParamFlagDef("name", kern.PfOptional|kern.PfDefault, "Celestino Amoroso"),
|
||||||
})
|
})
|
||||||
|
|
||||||
runCtxTestSuite(t, ctx, section, inputs)
|
runCtxTestSuite(t, ctx, section, inputs)
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
|
||||||
|
// All rights reserved.
|
||||||
|
|
||||||
|
// t_iter-iter_test.go
|
||||||
|
package expr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.portale-stac.it/go-pkg/expr/kern"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestIterIterator(t *testing.T) {
|
||||||
|
section := "Iterator"
|
||||||
|
inputs := []inputType{
|
||||||
|
/* 1 */ {`it=$(4); $(it) filter ${_}==100`, kern.NewListA(), nil},
|
||||||
|
/* 2 */ {`it=$(4); $(it, func(){$_}) filter ${_}==100`, kern.NewListA(), nil},
|
||||||
|
/* 3 */ {`it=$(4); $(it, func(arg1){arg1+$_}, 10) filter ${_}==100`, kern.NewListA(), nil},
|
||||||
|
}
|
||||||
|
|
||||||
|
runTestSuiteSpec(t, section, inputs, 3)
|
||||||
|
// runTestSuite(t, section, inputs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// func TestNewIterIterator(t *testing.T) {
|
||||||
|
// var it kern.Iterator
|
||||||
|
// var err error
|
||||||
|
|
||||||
|
// list := kern.NewListA("a", "b", "c", "d")
|
||||||
|
// itList := NewListIterator(list, []any{1, 3, 1})
|
||||||
|
// it, err = NewIterator(nil, itList, map[string]any{"op": kern.NewFunctor("test")})
|
||||||
|
// if err != nil {
|
||||||
|
// t.Errorf("error: %v", err)
|
||||||
|
// } else {
|
||||||
|
// if item, err := it.Next(); err != nil {
|
||||||
|
// t.Errorf("error: %v", err)
|
||||||
|
// } else if item != "b" {
|
||||||
|
// t.Errorf("expected %q, got %q", "b", item)
|
||||||
|
// } else {
|
||||||
|
// t.Logf("Next: %v", item)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func TestNewIterIteratorNoOp(t *testing.T) {
|
||||||
|
// var it kern.Iterator
|
||||||
|
// var err error
|
||||||
|
|
||||||
|
// list := kern.NewListA("a", "b", "c", "d")
|
||||||
|
// itList := NewListIterator(list, []any{1, 3, 1})
|
||||||
|
// it, err = NewIterator(nil, itList, nil)
|
||||||
|
// if err != nil {
|
||||||
|
// t.Errorf("error: %v", err)
|
||||||
|
// } else {
|
||||||
|
// if item, err := it.Next(); err != nil {
|
||||||
|
// t.Errorf("error: %v", err)
|
||||||
|
// } else if item != "b" {
|
||||||
|
// t.Errorf("expected %q, got %q", "b", item)
|
||||||
|
// } else {
|
||||||
|
// t.Logf("Next: %v", item)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
+6
-6
@@ -61,7 +61,7 @@ func TestNewIterList2(t *testing.T) {
|
|||||||
|
|
||||||
func TestNewIterList3(t *testing.T) {
|
func TestNewIterList3(t *testing.T) {
|
||||||
list := []any{"a", "b", "c", "d"}
|
list := []any{"a", "b", "c", "d"}
|
||||||
it, _ := NewIterator(list)
|
it, _ := NewIterator(nil, list, nil)
|
||||||
if item, err := it.Next(); err != nil {
|
if item, err := it.Next(); err != nil {
|
||||||
t.Errorf("error: %v", err)
|
t.Errorf("error: %v", err)
|
||||||
} else if item != "a" {
|
} else if item != "a" {
|
||||||
@@ -73,7 +73,7 @@ func TestNewIterList3(t *testing.T) {
|
|||||||
|
|
||||||
func TestNewIterList4(t *testing.T) {
|
func TestNewIterList4(t *testing.T) {
|
||||||
list := any(nil)
|
list := any(nil)
|
||||||
it, _ := NewIterator(list)
|
it, _ := NewIterator(nil, list, nil)
|
||||||
if _, err := it.Next(); err != io.EOF {
|
if _, err := it.Next(); err != io.EOF {
|
||||||
t.Errorf("error: %v", err)
|
t.Errorf("error: %v", err)
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@ func TestNewIterList4(t *testing.T) {
|
|||||||
|
|
||||||
func TestNewIterList5(t *testing.T) {
|
func TestNewIterList5(t *testing.T) {
|
||||||
list := "123"
|
list := "123"
|
||||||
it, _ := NewIterator(list)
|
it, _ := NewIterator(nil, list, nil)
|
||||||
if item, err := it.Next(); err != nil {
|
if item, err := it.Next(); err != nil {
|
||||||
t.Errorf("error: %v", err)
|
t.Errorf("error: %v", err)
|
||||||
} else if item != "123" {
|
} else if item != "123" {
|
||||||
@@ -93,8 +93,8 @@ func TestNewIterList5(t *testing.T) {
|
|||||||
|
|
||||||
func TestNewIterList6(t *testing.T) {
|
func TestNewIterList6(t *testing.T) {
|
||||||
list := kern.NewListA("a", "b", "c", "d")
|
list := kern.NewListA("a", "b", "c", "d")
|
||||||
it1, _ := NewIterator(list)
|
it1, _ := NewIterator(nil, list, nil)
|
||||||
it, _ := NewIterator(it1)
|
it, _ := NewIterator(nil, it1, nil)
|
||||||
if item, err := it.Next(); err != nil {
|
if item, err := it.Next(); err != nil {
|
||||||
t.Errorf("error: %v", err)
|
t.Errorf("error: %v", err)
|
||||||
} else if item != "a" {
|
} else if item != "a" {
|
||||||
@@ -106,7 +106,7 @@ func TestNewIterList6(t *testing.T) {
|
|||||||
|
|
||||||
func TestNewString(t *testing.T) {
|
func TestNewString(t *testing.T) {
|
||||||
list := "123"
|
list := "123"
|
||||||
it, _ := NewIterator(list)
|
it, _ := NewIterator(nil, list, nil)
|
||||||
if s := it.String(); s != "$([#1])" {
|
if s := it.String(); s != "$([#1])" {
|
||||||
t.Errorf("expected $([#1]), got %s", s)
|
t.Errorf("expected $([#1]), got %s", s)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user