about summary refs log tree commit diff
path: root/Functions/Misc/zmathfuncdef
diff options
context:
space:
mode:
Diffstat (limited to 'Functions/Misc/zmathfuncdef')
-rw-r--r--Functions/Misc/zmathfuncdef45
1 files changed, 45 insertions, 0 deletions
diff --git a/Functions/Misc/zmathfuncdef b/Functions/Misc/zmathfuncdef
new file mode 100644
index 000000000..9ecfcdd82
--- /dev/null
+++ b/Functions/Misc/zmathfuncdef
@@ -0,0 +1,45 @@
+# Define a mathematical function with its definition and smart(ish)
+# guessing of the number of arguments.  Doesn't overload for different
+# numbers of arguments, but that could be done.  Type overloading would be
+# more fraught.
+
+emulate -L zsh
+setopt extendedglob
+
+if (( $# < 1 || $# > 2 )); then
+  print "Usage: $0 name [body]" >&2
+  return 1
+fi
+
+local mname=$1
+local fname="zsh_math_func_$1"
+
+if (( $# == 1 )); then
+  functions +M $mname && unfunction $fname
+  return 0
+fi
+
+integer iarg=0 ioptarg
+local body=$2
+
+# count compulsory arguments
+while [[ $body = *'$'$((iarg+1))(|[^[:digit:]]*) ]]; do
+  (( iarg++ ))
+done
+
+# count optional arguments
+(( ioptarg = iarg ))
+while [[ $body = *'${'$((ioptarg+1))':-'* ]]; do
+  (( ioptarg++ ))
+done
+
+functions -M $mname $iarg $ioptarg $fname || return 1
+
+{
+  eval "$fname() { (( $body )) }"
+} always {
+  # Remove math function if shell function definition failed.
+  if (( TRY_BLOCK_ERROR )); then
+    functions +M $mname
+  fi
+}