Repository: fika-lang/fika
Pull request #6 (2020-09-25 14:44:32)

Add boolean data type


Patch:
diff --git a/README.md b/README.md
index b480432..1b2d82a 100644
--- a/README.md
+++ b/README.md
@@ -58,7 +58,7 @@ example.sum(40, 2)
 Fika is currently a proof of concept so its data types and operators are quite
 limited.
 
-Data types - integers, strings, lists and records.
+Data types - integers, strings, booleans, lists and records.
 Operators - assignment and arithmetic.
 
 ```elixir
@@ -72,6 +72,9 @@ c = a + b
 # Type: String
 str = "Hello world"
 
+# Type: Bool
+x = true
+
 # Type: List(Int)
 list_of_ints = [1, 2, 3]
 
diff --git a/example.fi b/example.fi
index 1218217..23339c9 100644
--- a/example.fi
+++ b/example.fi
@@ -17,3 +17,7 @@ end
 fn sum_ref : Fn(Int, Int -> Int) do
   &sum(Int, Int)
 end
+
+fn bool : Bool do
+  true
+end
diff --git a/lib/fika/erl_translate.ex b/lib/fika/erl_translate.ex
index ccf18b1..bf4fdec 100644
--- a/lib/fika/erl_translate.ex
+++ b/lib/fika/erl_translate.ex
@@ -50,6 +50,10 @@ defmodule Fika.ErlTranslate do
     {:integer, line, value}
   end
 
+  defp translate_exp({:boolean, {line, _, _}, value}) do
+    {:atom, line, value}
+  end
+
   defp translate_exp({{:=, {line, _, _}}, pattern, exp}) do
     {:match, line, translate_exp(pattern), translate_exp(exp)}
   end
diff --git a/lib/fika/parser.ex b/lib/fika/parser.ex
index c9dfec2..d559549 100644
--- a/lib/fika/parser.ex
+++ b/lib/fika/parser.ex
@@ -64,6 +64,14 @@ defmodule Fika.Parser do
     |> label("integer")
     |> Helper.to_ast(:integer)
 
+  boolean =
+    choice([
+      string("true"),
+      string("false")
+    ])
+    |> label("boolean")
+    |> Helper.to_ast(:boolean)
+
   string_exp =
     ignore(string("\""))
     |> repeat(choice([string("\\\""), utf8_char([not: ?"])]))
@@ -188,6 +196,7 @@ defmodule Fika.Parser do
   factor =
     choice([
       integer,
+      boolean,
       string_exp,
       exp_paren,
       function_call,
diff --git a/lib/fika/parser_helper.ex b/lib/fika/parser_helper.ex
index d072f66..14cd01b 100644
--- a/lib/fika/parser_helper.ex
+++ b/lib/fika/parser_helper.ex
@@ -18,6 +18,10 @@ defmodule Fika.ParserHelper do
     {:integer, line, value}
   end
 
+  def do_to_ast({[value], line}, :boolean) do
+    {:boolean, line, value == "true"}
+  end
+
   def do_to_ast({[left, bin_op, right | rest], line}, :exp_bin_op) when bin_op in ["+", "-", "*", "/"] do
     new_left = {:call, {String.to_atom(bin_op), line}, [left, right], :kernel}
     do_to_ast({[new_left | rest], line}, :exp_bin_op)
diff --git a/lib/fika/type_checker.ex b/lib/fika/type_checker.ex
index 62282c9..bec4559 100644
--- a/lib/fika/type_checker.ex
+++ b/lib/fika/type_checker.ex
@@ -76,6 +76,12 @@ defmodule Fika.TypeChecker do
     {:ok, "Int", env}
   end
 
+  # Booleans
+  def infer_exp(env, {:boolean, _line, boolean}) do
+    Logger.debug "Boolean #{boolean} found. Type: Bool"
+    {:ok, "Bool", env}
+  end
+  
   # Variables
   def infer_exp(env, {:identifier, _line, name}) do
     type = Env.scope_get(env, name)


Test patch:
diff --git a/test/fika/erl_translate_test.exs b/test/fika/erl_translate_test.exs
index 13ef232..b59d06d 100644
--- a/test/fika/erl_translate_test.exs
+++ b/test/fika/erl_translate_test.exs
@@ -94,4 +94,12 @@ defmodule Fika.ErlTranslateTest do
         {:function, :foo, 2}}
     end
   end
+
+  test "boolean" do
+    str = "true"
+    ast = Parser.expression!(str)
+    result = ErlTranslate.translate_expression(ast)
+  
+    assert result == {:atom, 1, true}
+  end
 end
diff --git a/test/fika/parser_test.exs b/test/fika/parser_test.exs
index 70e3d5a..9f2ffb9 100644
--- a/test/fika/parser_test.exs
+++ b/test/fika/parser_test.exs
@@ -11,6 +11,22 @@ defmodule Fika.ParserTest do
     assert result ==  [{:integer, {1, 0, 3}, 123}]
   end
 
+  describe "boolean" do
+    test "true" do
+      str = "true"
+  
+      result = Parser.expression!(str)
+      assert result ==  {:boolean, {1, 0, 4}, true}
+    end
+  
+    test "false" do
+      str = "false"
+  
+      result = Parser.expression!(str)
+      assert result ==  {:boolean, {1, 0, 5}, false}
+    end
+  end
+
   describe "arithmetic" do
     test "arithmetic with add and mult" do
       str = """
diff --git a/test/fika/type_checker_test.exs b/test/fika/type_checker_test.exs
index 209ade9..5c3af09 100644
--- a/test/fika/type_checker_test.exs
+++ b/test/fika/type_checker_test.exs
@@ -209,4 +209,20 @@ defmodule Fika.TypeCheckerTest do
       assert {:ok, "Fn(->Int)", _} = TypeChecker.infer_exp(env, ast)
     end
   end
+  
+  describe "boolean" do
+    test "true" do
+      str = "true"
+      ast = Fika.Parser.expression!(str)
+  
+      assert {:ok, "Bool", _} = TypeChecker.infer_exp(Env.init(), ast)
+    end
+  
+    test "false" do
+      str = "false"
+      ast = Fika.Parser.expression!(str)
+  
+      assert {:ok, "Bool", _} = TypeChecker.infer_exp(Env.init(), ast)
+    end
+  end
 end