summary refs log tree commit diff
path: root/Functions/Misc/zmathfuncdef
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2006-04-20 10:04:30 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2006-04-20 10:04:30 +0000
commit5d9563ab12580aa1d0b20bcfba4af006b46b2a09 (patch)
treef7ad347bd3ffe54727f63b7876f1ad766536cea4 /Functions/Misc/zmathfuncdef
parent6555629356e509afb9872577ecd79e9f20e67289 (diff)
downloadzsh-5d9563ab12580aa1d0b20bcfba4af006b46b2a09.tar.gz
zsh-5d9563ab12580aa1d0b20bcfba4af006b46b2a09.tar.xz
zsh-5d9563ab12580aa1d0b20bcfba4af006b46b2a09.zip
22416: forgot zmathfuncdef
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
+}