From aa1d984db18333d89b6bb2b1fa9852f85edba2de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?William=20Herg=C3=A8s?= Date: Sat, 8 Nov 2025 21:31:48 +0100 Subject: feat(calc): strengthen reducing --- lib/elixir_math_parser.ex | 56 ++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 22 deletions(-) (limited to 'lib/elixir_math_parser.ex') diff --git a/lib/elixir_math_parser.ex b/lib/elixir_math_parser.ex index 1f147aa..91f67f9 100644 --- a/lib/elixir_math_parser.ex +++ b/lib/elixir_math_parser.ex @@ -4,46 +4,58 @@ defmodule ElixirMathParser do """ defp reduce_to_value({:int, _line, value}, _state) do - value + {:ok, value} + end + + defp reduce_to_value({:atom, _line, atom}, state) do + if !Map.has_key?(state, atom) do + {:error, "value not found for " <> to_string(atom)} + else + {:ok, state[atom]} + end end defp reduce_to_value({:add_op, lhs, rhs}, state) do - reduce_to_value(lhs, state) + reduce_to_value(rhs, state) + {:ok, op1} = reduce_to_value(lhs, state) + {:ok, op2} = reduce_to_value(rhs, state) + {:ok, op1 + op2} end defp reduce_to_value({:sub_op, lhs, rhs}, state) do - reduce_to_value(lhs, state) - reduce_to_value(rhs, state) + {:ok, op1} = reduce_to_value(lhs, state) + {:ok, op2} = reduce_to_value(rhs, state) + {:ok, op1 - op2} end defp reduce_to_value({:mul_op, lhs, rhs}, state) do - reduce_to_value(lhs, state) * reduce_to_value(rhs, state) + {:ok, op1} = reduce_to_value(lhs, state) + {:ok, op2} = reduce_to_value(rhs, state) + {:ok, op1 / op2} end defp reduce_to_value({:div_op, lhs, rhs}, state) do - reduce_to_value(lhs, state) / reduce_to_value(rhs, state) + {:ok, op1} = reduce_to_value(lhs, state) + {:ok, op2} = reduce_to_value(rhs, state) + {:ok, op1 / op2} end - defp reduce_to_value({:atom, _line, atom}, state) do - state[atom] - end - defp evaluate_tree([{:assign, {:atom, _line, lhs}, rhs} | tail], state) do - rhs_value = reduce_to_value(rhs, state) + {:ok, rhs_value} = reduce_to_value(rhs, state) evaluate_tree(tail, Map.merge(state, %{lhs => rhs_value})) end - defp evaluate_tree([], state) do - state - end + defp evaluate_tree([], state) do + state + end - def process_tree(tree) do - evaluate_tree(tree, %{}) - end + def process_tree(tree) do + evaluate_tree(tree, %{}) + end - def parse_file(filename) do - text = File.read!(filename) - {:ok, tokens, _line} = :elixir_math_parser_lexer.string(String.to_charlist(text)) - {:ok, tree} = :elixir_math_parser.parse(tokens) - process_tree(tree) - end + def parse_file(filename) do + text = File.read!(filename) + {:ok, tokens, _line} = :elixir_math_parser_lexer.string(String.to_charlist(text)) + {:ok, tree} = :elixir_math_parser.parse(tokens) + process_tree(tree) + end end -- cgit v1.2.3