I am working on my programming language which compiles into bash 4.3+ code. I am in the final stages of my language, but I have a small issue with recursion functions. Here's the bash code which is supposed to return the fibnacci number given an index.
#!/bin/bash
function fib() {
local a=$1
declare -n ret=$2
if (( $a <= 2 )); then
ret=1
return
fi
fib $((a-1)) fib1
fib $((a-2)) fib2
ret=$((fib1+fib2))
echo "fib($((a-1))) + fib($((a-2))) = $ret"
return
}
num=5
fib $num result
echo
echo "fib($num) = $result"
The problem in this code is that the fib(5) is giving 3 which is clearly wrong. What I think the problem is, when I pass fib1 and fib2 as a way to store the return value, they get overwritten by each call which assigns them. If that was the problem, how can I make fib1 and fib2 local to their execution scope.
Please note that I do not want to use a return statement to return the values, I want to try finding a solution using declare -n namerefs.
Thank you
Yep, and you can see that by printing the value of
fib1between and after the recursive calls:You should see the value of
fib1change during the second call. That's to be expected, since it wasn't declaredlocaland there only is one global copy offib1.If you make them local... it doesn't help much.
Assume you start by calling
fib 4 result. The first iteration will makefib1local, and callfib 3 fib1. Now the second iteration will also makefib1local, but it will also try to assign its return value to a variable of the same name. Since the access is by name, it saves the return value to its own copy offib1.This can be seen with a somewhat simpler script too, this tries to return a fixed value up from the bottom of the recursion:
The workaround I can think of is to have a separate global variable for the return value, and to immediately copy it to a local variable: