function's calling context in zsh: equivalent of bash `caller`

I don't think there's a builtin command equivalent, but some combination of these four variables from the zsh/Parameter module can be used:

funcfiletrace

This array contains the absolute line numbers and corresponding file names for the point where the current function, sourced file, or (if EVAL_LINENO is set) eval command was called. The array is of the same length as funcsourcetrace and functrace, but differs from funcsourcetrace in that the line and file are the point of call, not the point of definition, and differs from functrace in that all values are absolute line numbers in files, rather than relative to the start of a function, if any.

funcsourcetrace

This array contains the file names and line numbers of the points where the functions, sourced files, and (if EVAL_LINENO is set) eval commands currently being executed were defined. The line number is the line where the ‘function name’ or ‘name ()’ started. In the case of an autoloaded function the line number is reported as zero. The format of each element is filename:lineno.

For functions autoloaded from a file in native zsh format, where only the body of the function occurs in the file, or for files that have been executed by the source or ‘.’ builtins, the trace information is shown as filename:0, since the entire file is the definition. The source file name is resolved to an absolute path when the function is loaded or the path to it otherwise resolved.

Most users will be interested in the information in the funcfiletrace array instead.

funcstack

This array contains the names of the functions, sourced files, and (if EVAL_LINENO is set) eval commands. currently being executed. The first element is the name of the function using the parameter.

The standard shell array zsh_eval_context can be used to determine the type of shell construct being executed at each depth: note, however, that is in the opposite order, with the most recent item last, and it is more detailed, for example including an entry for toplevel, the main shell code being executed either interactively or from a script, which is not present in $funcstack.

functrace

This array contains the names and line numbers of the callers corresponding to the functions currently being executed. The format of each element is name:lineno. Callers are also shown for sourced files; the caller is the point where the source or ‘.’ command was executed.

Comparing:

foo.bash:

#! /bin/bash
yelp() {
    caller 0
}

foo () {
    yelp
}

foo

foo.zsh:

#! /bin/zsh
yelp() {
    print -l -- $funcfiletrace - $funcsourcetrace - $funcstack - $functrace
}

foo () {
    yelp
}

foo

The results:

$ bash foo.bash
7 foo foo.bash

$ zsh foo.zsh
foo.zsh:7
foo.zsh:10
-
foo.zsh:2
foo.zsh:6
-
yelp
foo
-
foo:1
foo.zsh:10

So, the corresponding values are in ${funcfiletrace[1]} and ${funcstack[-1]}. Modifying yelp to:

yelp() {
    print -- $funcfiletrace[1] $funcstack[-1]
}

The output is:

foo.zsh:7 foo

which is quite close to bash's

7 foo foo.bash

Based on muru's answer, I implemented the following function which works in both {ba,z}sh:

$ cat yelp
#!/bin/zsh
# Say the file, line number and optional message for debugging
# Inspired by bash's `caller` builtin
# Thanks to https://unix.stackexchange.com/a/453153/143394
function yelp () {
  # shellcheck disable=SC2154  # undeclared zsh variables in bash
  if [[ $BASH_VERSION ]]; then
    local file=${BASH_SOURCE[1]} func=${FUNCNAME[1]} line=${BASH_LINENO[0]}
  else  # zsh
    emulate -L zsh  # because we may be sourced by zsh `emulate bash -c`
    # $funcfiletrace has format:  file:line
    local file=${funcfiletrace[1]%:*} line=${funcfiletrace[1]##*:}
    local func=${funcstack[2]}
    [[ $func =~ / ]] && func=source  # $func may be filename. Use bash behaviour
  fi
  echo "${file##*/}:$func:$line $*" > /dev/tty
}

foo () { yelp; }
yelp
foo

The output is:

$ ./yelp
yelp::20 
yelp:foo:19