Add support for variadic functions
This commit is contained in:
parent
25037db86a
commit
9bf56b50a4
23
salix.go
23
salix.go
@ -475,7 +475,10 @@ func (t *Template) execMethodCall(mc ast.MethodCall, local map[string]any) (any,
|
|||||||
// execFunc executes a function call
|
// execFunc executes a function call
|
||||||
func (t *Template) execFunc(fn reflect.Value, node ast.Node, args []ast.Node, local map[string]any) (any, error) {
|
func (t *Template) execFunc(fn reflect.Value, node ast.Node, args []ast.Node, local map[string]any) (any, error) {
|
||||||
fnType := fn.Type()
|
fnType := fn.Type()
|
||||||
if fnType.NumIn() != len(args) {
|
lastIndex := fnType.NumIn() - 1
|
||||||
|
isVariadic := fnType.IsVariadic()
|
||||||
|
|
||||||
|
if !isVariadic && fnType.NumIn() != len(args) {
|
||||||
return nil, ast.PosError(node, "%s: invalid parameter amount: %d (expected %d)", valueToString(node), len(args), fnType.NumIn())
|
return nil, ast.PosError(node, "%s: invalid parameter amount: %d (expected %d)", valueToString(node), len(args), fnType.NumIn())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,7 +486,7 @@ func (t *Template) execFunc(fn reflect.Value, node ast.Node, args []ast.Node, lo
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
params := make([]reflect.Value, fnType.NumIn())
|
params := make([]reflect.Value, 0, fnType.NumIn())
|
||||||
for i, arg := range args {
|
for i, arg := range args {
|
||||||
if _, ok := arg.(ast.Assignment); ok {
|
if _, ok := arg.(ast.Assignment); ok {
|
||||||
return nil, ast.PosError(arg, "%s: an assignment cannot be used as a function argument", valueToString(node))
|
return nil, ast.PosError(arg, "%s: an assignment cannot be used as a function argument", valueToString(node))
|
||||||
@ -492,11 +495,19 @@ func (t *Template) execFunc(fn reflect.Value, node ast.Node, args []ast.Node, lo
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
params[i] = reflect.ValueOf(paramVal)
|
params = append(params, reflect.ValueOf(paramVal))
|
||||||
if params[i].CanConvert(fnType.In(i)) {
|
if isVariadic && i >= lastIndex {
|
||||||
params[i] = params[i].Convert(fnType.In(i))
|
if params[i].CanConvert(fnType.In(lastIndex).Elem()) {
|
||||||
|
params[i] = params[i].Convert(fnType.In(lastIndex).Elem())
|
||||||
|
} else {
|
||||||
|
return nil, ast.PosError(node, "%s: invalid parameter type: %T (expected %s)", valueToString(node), paramVal, fnType.In(i))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return nil, ast.PosError(node, "%s: invalid parameter type: %T (expected %s)", valueToString(node), paramVal, fnType.In(i))
|
if params[i].CanConvert(fnType.In(i)) {
|
||||||
|
params[i] = params[i].Convert(fnType.In(i))
|
||||||
|
} else {
|
||||||
|
return nil, ast.PosError(node, "%s: invalid parameter type: %T (expected %s)", valueToString(node), paramVal, fnType.In(i))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
vars.go
1
vars.go
@ -19,6 +19,7 @@ var globalVars = map[string]any{
|
|||||||
"count": strings.Count,
|
"count": strings.Count,
|
||||||
"split": strings.Split,
|
"split": strings.Split,
|
||||||
"join": strings.Join,
|
"join": strings.Join,
|
||||||
|
"sprintf": fmt.Sprintf,
|
||||||
}
|
}
|
||||||
|
|
||||||
func tmplLen(v any) (int, error) {
|
func tmplLen(v any) (int, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user