func newFnDef(name string, parent *Shell, args []*ast.FnArgNode, body *ast.Tree) (*fnDef, error) {
	fn := fnDef{
		name:   name,
		Parent: parent,
		Body:   body,
		stdin:  parent.stdin,
		stdout: parent.stdout,
		stderr: parent.stderr,
	}
	for i := 0; i < len(args); i++ {
		arg := args[i]
		if i < len(args)-1 && arg.IsVariadic {
			return nil, errors.NewEvalError(parent.filename,
				arg, "Vararg '%s' isn't the last argument",
				arg.String())
		}
		fn.argNames = append(fn.argNames, sh.FnArg{arg.Name, arg.IsVariadic})
	}
	return &fn, nil
}
newFnDef creates a new function definition
package sh
import (
	"io"
	"github.com/madlambda/nash/ast"
	"github.com/madlambda/nash/errors"
	"github.com/madlambda/nash/internal/sh/builtin"
	"github.com/madlambda/nash/sh"
)
type (
	fnDef struct {
		name     string
		Parent   *Shell
		Body     *ast.Tree
		argNames []sh.FnArg
		stdin          io.Reader
		stdout, stderr io.Writer
		environ        []string
	}
	userFnDef struct {
		*fnDef
	}
	builtinFnDef struct {
		*fnDef
		constructor builtin.Constructor
	}
)