Repository: fika-lang/fika (elixir)

Issue:
Type checker sees arguments of function calls in reversed order
If you have a function that accepts multiple arguments of different types
```elixir
fn foo(a1: Type1, ..., an: TypeN)
``` 
and you call it, you'll get
```Elixir
{:error, "Undefined function: <module>.foo(TypeN, ..., Type1) in module <module>"}
```
<br>

**e.g.**
```Elixir
fn foo(a: Int, b: String) : Int do
  a
end

fn bar : Int do
  foo(5, "a")
end
```
results in 
```elixir
{:error, "Undefined function: sandbox.foo(String, Int) in module sandbox"}
```
<br>

**Note:** the call's AST (below) looks good (the order of the args is preserved) so I suppose the problem lies in the type checker

```elixir
{:call, {:foo, _}, [{:integer, _, 5}, {:string, _, ["a"]}], nil}
```

Pull request:
Infer types of call args correctly
Fixes #50 

Patch:
diff --git a/lib/fika/compiler/type_checker.ex b/lib/fika/compiler/type_checker.ex
index a3e8074..5cb21e9 100644
--- a/lib/fika/compiler/type_checker.ex
+++ b/lib/fika/compiler/type_checker.ex
@@ -385,6 +385,13 @@ defmodule Fika.Compiler.TypeChecker do
           {:halt, error}
       end
     end)
+    |> case do
+      {:ok, reversed_types, env} ->
+        {:ok, Enum.reverse(reversed_types), env}
+
+      error ->
+        error
+    end
   end
 
   defp do_infer_args_without_name(env, args) do


Test patch:
diff --git a/test/fika/compiler/type_checker_test.exs b/test/fika/compiler/type_checker_test.exs
index d479a6a..f9ef7e9 100644
--- a/test/fika/compiler/type_checker_test.exs
+++ b/test/fika/compiler/type_checker_test.exs
@@ -135,6 +135,25 @@ defmodule Fika.Compiler.TypeCheckerTest do
     assert {:ok, :Int} = TypeChecker.infer(foo, env)
   end
 
+  test "infer calls with multiple args" do
+    str = """
+    fn foo(a: Int, b: String) : Int do
+      a
+    end
+
+    fn bar : Int do
+      foo(5, "a")
+    end
+    """
+
+    {:ok, ast} = Parser.parse_module(str)
+    [_foo, bar] = ast[:function_defs]
+
+    env = TypeChecker.init_env(ast)
+
+    assert {:ok, :Int} = TypeChecker.infer(bar, env)
+  end
+
   test "infer function with variable assignments which get used in function calls" do
     str = """
     use test2