The below code is an expansion of an exercise dealing with character lists it is intended to parse a character list submitted as a calculation query.

The original exercise was just two values with one operator, however I expanded it too included multiple operators, powers and brackets.

I am having an issue with the brackets implementation. Everything seems to be working fine, until one of the recursion calls does not pass one of the arguments for the third parameter (the buffer parameter).

I would really appreciate some guidance here, I have not started control flow, however I think I have a good idea of what should be happening so Iāve been quite baffled by the behaviour of my brackets operators implementation.

This code has not been fully cleaned, but I took some steps to make the code more concise and remove some inefficiencies.

Iāve done some troubleshooting, and it seems as though the buffer arg is not updating from the default empty charlist that it is set to when the function is called from within the calculator(ā¦,ā¦,ā¦,?( ) clause titled *###ā(ā, parenthesis operator, ###########*

Below the is the code:

```
defmodule Calc do
def calculator(list, value \\ 0, buffer \\ '', operator \\ ?+)
# def calculator([h|_], _, _, _) when not (h in ?(..?9 or h == ?^) or h == ?, do
# raise "Illegal character in calculation query"
# end
# def calculator([h|t], _, _, _) when h in '^*/+-)' and t != [] and hd(t) in '^*/+-)', do: raise "Illegal consecutive operators '#{[h, hd(t)]}'"
# def calculator([?.|t], value, buffer, operator) do
# cond do
# ?. in buffer ->
# raise ~w"""
# Number #{buffer} already cotains maximum number of decimal points (1).
# Remove any other decimal points and leave only the one intended decimal.
# """
# buffer == '' ->
# calculator(t, value, '0.', operator)
# true ->
# calculator(t, value, buffer ++ [?.], operator)
# end
# end
# def calculator([h|[]], _value, _buffer, _operator) when h in '^*/+-(', do: raise "Improper character '#{[h]}' used to terminate calculation"
# def calculator([?-|t], value, '', operator), do: calculator(t, value, ?-, operator)
def calculator([], value, buffer, operator) do
lsign = ((operator in '*+' && 1) || -1)
v1 = (buffer |> to_number)
v2 = (operator == ?^ && value ** v1) || (operator in '/*' && value * v1 ** lsign) || value + v1 * lsign
{[], v2}
end
def calculator([h|t], value, buffer, operator) when h in ?0..?9 do
calculator(t, value, buffer++[h], operator)
end
###^, power operator, ###########
# def calculator([h|t], value, buffer, ?^) do
# IO.puts "here1"
# cond do
# h in '^*/' ->
# value = value ** (buffer |> to_number)
# calculator(t, value, '', h)
# h in '+-' ->
# {[h|t], value ** (buffer |> to_number)}
# h == ?( ->
# if buffer != '' do
# value = value ** (buffer |> to_number)
# calculator([h|t], value, '', ?*)
# else
# {t, i_val} = calculator(t, 0, '', h)
# value = value ** i_val
# calculator(t, value)
# end
# h == ?) ->
# value = value ** (buffer |> to_number)
# {[h|t], value}
# end
# end
###*/, multiplication operators, ###########
# def calculator([h|t], value, buffer, operator) when operator in '*/' do
# IO.puts "here2"
# IO.inspect value
# pow = (operator == ?* && 1) || -1
# cond do
# h == ?^ ->
# {t, i_val} = calculator(t, buffer |> to_number, '', h)
# {t, value * i_val ** pow}
# h in '*/' ->
# value = value * (buffer |> to_number) ** pow
# calculator(t, value, '', h)
# h in '+-' ->
# {[h|t], value * (buffer |> to_number) ** pow}
# h == ?( ->
# {[h_2|t_2], i_val} = calculator(t, 0, '', h)
# {t, i_val} = (h_2 not in '+-' && calculator(t_2, i_val ** pow, '', h_2)) || {[h_2|t_2], i_val}
# if buffer != '' do
# value = value * (buffer |> to_number) ** pow * i_val
# {t, value}
# else
# value = value * i_val
# {t, value}
# end
# h == ?) ->
# value = value * (buffer |> to_number) ** pow
# {[h|t], value}
# end
# end
###+-, addition operators, ###########
def calculator([h|t], value, buffer, operator) when operator in '+-' do #and h in '^*/+-()'
IO.inspect buffer
s = (operator == ?+ && 1)|| -1
cond do
h == ?( ->
{t, i_val} = calculator(t, 0, '', h)
if t != [] do
[h_2, t_2] = [hd(t), tl(t)]
{t, i_val} = (h_2 not in '+-' && calculator(t_2, i_val, '', h_2)) || {[h_2|t_2], i_val}
if buffer != '' do
value = value + (buffer |> to_number) * s * i_val
calculator(t, value)
else
value = value + s*i_val
calculator(t, value)
end
else
{t, i_val}
end
h == ?) ->
value = value + s*(buffer |> to_number)
{[h|t], value}
h in '^*/+-' ->
{t, i_val} = calculator(t, buffer |> to_number, '' , h)
value = value + s*i_val
calculator(t, value)
end
end
###'(', parenthesis operator, ###########
def calculator(list, _, _, ?() do
{list, value} = calculator(list)
tail = tl list
if tail != [] && hd tail in ?0..?9 do
raise "Number should not follow bracket close"
else
{tail, value}
end
end
def to_number(_number, value\\0, multiplier\\1, point\\false, pow\\0)
def to_number([?-|t], value, _multiplier, _point, _pow), do: to_number(t, value, -1)
def to_number([?.|[]], value, multiplier, _point, _pow), do: to_number([], value, multiplier)
def to_number([?.|t], value, multiplier, _point, _pow), do: to_number(t, value, multiplier, true, -1)
def to_number([h|t], value, multiplier, true, pow), do: to_number(t, value + (h - ?0) * 10 ** pow, multiplier, pow - 1)
def to_number([h|t], value, multiplier, false, _pow), do: to_number(t, 10*value + (h - ?0), multiplier)
def to_number([], value, multiplier, _point, _pow), do: value*multiplier
```

If there is any ambiguity please let me know. This is a somewhat rough implementation, that is, Iām just trying to get it working with some degree of adherence to conventions to aid in my understanding of the language.

Just wanted to add the path that the call should take:

So the below callā¦:

`calculator '(5+2)'`

(output {, 2}, expected output {, 7})

ā¦should take the following path (and it does but the buffer arg is not passed):

- Goes to ###Ā±, addition operators, ########### as the default operator is +
- Within that function body the cond do requirements are met which results in the following call
`calculator(t, 0, '', h)`

, where h = ?( - Goes to ###ā(ā, parenthesis operator, ########### which calls calculate passing the character list with ?( removed
- Goes to the calculate with h in 0?..?9 clause, and concatenates buffer with [h] calls calculate with the tail, t and the new buffer with the concatenation.
- Goes
**once again**to the ###Ā±, addition operators, ########### titled clause, but does not pass the updated buffer, instead the default buffer value is passed!

This path is confirmed with IO.puts/inspect and it does not bounce between any other clauses.

*EDIT:* **Iāve commented out all code that is not relevant to the recursion call exampled and I have added the output for that recursion versus the expected output**

God bless.