Skip to content

Instantly share code, notes, and snippets.

@alganet
Created January 8, 2017 03:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alganet/537cd770e31ce41ac20129f7f90c08aa to your computer and use it in GitHub Desktop.
Save alganet/537cd770e31ce41ac20129f7f90c08aa to your computer and use it in GitHub Desktop.
Prefix-notation calculator in portable shell
calc ()
{
local cursor=0
local reference=0
local stack=0
local queue=''
local current=''
set -- $(echo ${@})
while test "${#}" -gt 0
do
local token="${1}"
cursor=$((cursor + 1))
if test "${token%\)})" = "${token}"
then
atom="${token%\)}"
local postf=''
while test "${atom%\)})" = "${atom}"
do
postf="${postf})"
atom="${atom%\)}"
done
shift
$(echo "${current#\(}" "${atom}")
set -- $(echo "${queue}" "${atom}${postf}" "${@:-}")
queue=''
stack="${stack% *}"
reference="${stack##* }"
cursor="${reference}"
while test "${reference}" -gt 1
do
queue="${queue} ${1}"
reference=$((reference - 1))
shift
done
current="${1}"
shift
reference="${stack##* }"
continue
elif test "(${token#\(}" = "${token}"
then
queue="${queue} ${current}"
current="${token}"
reference=${cursor}
stack="${stack} ${reference}"
else
current="${current} ${token}"
fi
shift
done
echo "${atom:-$token}"
}
add () { atom=$((${1} + ${2})); }
mul () { atom=$((${1} * ${2})); }
sub () { atom=$((${1} - ${2})); }
div () { atom=$((${1} / ${2})); }
calc '(div (add 2 (mul (add 1 (add 1 1)) 5)) 2)'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment