diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..7a78bcc --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,58 @@ +name: CI + +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + +jobs: + test: + name: Test (Elixir ${{matrix.elixir}} / OTP ${{matrix.otp}}) + runs-on: ubuntu-latest + strategy: + matrix: + # elixir: ['1.16', '1.17', '1.18', '1.19'] + # otp: ['26', '27', '28', '29'] + elixir: ['1.16'] + otp: ['26'] + steps: + - uses: actions/checkout@v4 + + - name: Setup Elixir + uses: erlef/setup-beam@v1 + with: + elixir-version: ${{matrix.elixir}} + otp-version: ${{matrix.otp}} + + - name: Cache deps + uses: actions/cache@v4 + with: + path: deps + key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }} + restore-keys: ${{ runner.os }}-mix- + + - name: Cache build + uses: actions/cache@v4 + with: + path: _build + key: ${{ runner.os }}-build-${{ matrix.elixir }}-${{ matrix.otp }}-${{ hashFiles('**/mix.lock') }} + restore-keys: ${{ runner.os }}-build- + + - name: Install dependencies + run: mix deps.get + + - name: Compile + run: mix compile + + - name: Run mix test + run: mix test + + - name: Run compile_stdlib + run: mix compile_stdlib + + - name: Run compile_all.exs + run: mix run compile_all.exs + + # - name: Run phi.test + # run: mix phi.test diff --git a/compile_all.exs b/compile_all.exs index 0426723..028388d 100644 --- a/compile_all.exs +++ b/compile_all.exs @@ -1,6 +1,8 @@ defmodule CompileAll do def run do - all_files = Path.wildcard("lib/**/*.hm") + lib_files = Path.wildcard("stdlib/**/*.phi") + test_files = Path.wildcard("tests/**/*.phi") + all_files = lib_files ++ test_files IO.puts "Found #{length(all_files)} files." File.mkdir_p!("ebin") diff --git a/lib/mix/tasks/compile_stdlib.ex b/lib/mix/tasks/compile_stdlib.ex index e1e2389..872576a 100644 --- a/lib/mix/tasks/compile_stdlib.ex +++ b/lib/mix/tasks/compile_stdlib.ex @@ -8,16 +8,16 @@ defmodule Mix.Tasks.CompileStdlib do """ use Mix.Task - @shortdoc "Compile all Hamler stdlib .hm files in dependency order" + @shortdoc "Compile all Phi stdlib .phi files in dependency order" def run(_args) do Mix.Task.run("compile", []) - files = Path.wildcard("lib/**/*.hm") |> Enum.sort() + files = Path.wildcard("stdlib/**/*.phi") |> Enum.sort() total = length(files) IO.puts("\n#{IO.ANSI.bright()}=== Phi Stdlib Compilation Report ===#{IO.ANSI.reset()}") - IO.puts("Found #{total} .hm files\n") + IO.puts("Found #{total} .phi files\n") # Build dependency graph and sort topologically module_infos = Enum.map(files, &extract_module_info/1) diff --git a/lib/mix/tasks/phi.compile.ex b/lib/mix/tasks/phi.compile.ex index 1bce9ef..faf345a 100644 --- a/lib/mix/tasks/phi.compile.ex +++ b/lib/mix/tasks/phi.compile.ex @@ -89,8 +89,6 @@ defmodule Mix.Tasks.Phi.Compile do if stdlib_only do IO.puts("Stdlib written to #{out_dir}/. Done.") else - keys = Phi.Typechecker.Env.all_keys(stdlib_env) - IO.puts("\nDEBUG: Before multi_pass, stdlib_env has #{length(keys)} keys") IO.puts("Compiling #{length(files)} user file(s)...") {_user_env, compiled_mods} = multi_pass(files, stdlib_env, out_dir, 1) summarise(compiled_mods, out_dir) @@ -102,10 +100,7 @@ defmodule Mix.Tasks.Phi.Compile do # --------------------------------------------------------------------------- defp load_stdlib(stdlib_files, out_dir) do - env = do_passes(stdlib_files, Phi.Typechecker.Env.new(), out_dir, 1) - keys = Phi.Typechecker.Env.all_keys(env) - IO.puts("DEBUG: load_stdlib returning env with #{length(keys)} keys") - env + do_passes(stdlib_files, Phi.Typechecker.Env.new(), out_dir, 1) end defp do_passes(files, env, out_dir, pass, successful_files \\ %{}) do @@ -142,8 +137,6 @@ defmodule Mix.Tasks.Phi.Compile do new_env successes == 0 -> - IO.puts("Pass #{pass}: stuck with #{length(failures)} failing files") - IO.puts("DEBUG: returning env with #{map_size(new_env.bindings)} keys after being stuck") new_env true -> diff --git a/lib/mix/tasks/phi.test.ex b/lib/mix/tasks/phi.test.ex index fa1c18d..824b30a 100644 --- a/lib/mix/tasks/phi.test.ex +++ b/lib/mix/tasks/phi.test.ex @@ -1,14 +1,14 @@ defmodule Mix.Tasks.Phi.Test do @moduledoc """ - Compiles the Hamler stdlib (lib/**/*.hm) and then the Hamler test suite - (tests/**/*.hm) using the same multi-pass environment accumulation strategy, + Compiles the Phi stdlib (lib/**/*.phi) and then the Phi test suite + (tests/**/*.phi) using the same multi-pass environment accumulation strategy, then executes the test main function. Usage: mix phi.test """ use Mix.Task - @shortdoc "Run Hamler native QuickCheck tests" + @shortdoc "Run Phi native QuickCheck tests" def run(_args) do Mix.Task.run("compile", []) @@ -18,14 +18,14 @@ defmodule Mix.Tasks.Phi.Test do IO.puts("\n=== Phi Native Test Runner ===\n") # Step 1: compile stdlib - IO.puts("--- Compiling stdlib (lib/**/*.hm) ---") - lib_files = Path.wildcard("lib/**/*.hm") + IO.puts("--- Compiling stdlib (lib/**/*.phi) ---") + lib_files = Path.wildcard("lib/**/*.phi") IO.puts("Found #{length(lib_files)} stdlib files.") stdlib_env = multi_pass_compile(lib_files, Phi.Typechecker.Env.new(), 1, "lib") # Step 2: compile test suite - IO.puts("\n--- Compiling test suite (tests/**/*.hm) ---") - test_files = Path.wildcard("tests/**/*.hm") + IO.puts("\n--- Compiling test suite (tests/**/*.phi) ---") + test_files = Path.wildcard("tests/**/*.phi") IO.puts("Found #{length(test_files)} test files.") _test_env = multi_pass_compile(test_files, stdlib_env, 1, "tests") diff --git a/lib/phi/ast.ex b/lib/phi/ast.ex index 2ec7f27..e88b5bd 100644 --- a/lib/phi/ast.ex +++ b/lib/phi/ast.ex @@ -131,6 +131,18 @@ defmodule Phi.AST do defstruct [:name] end + defmodule BinderAs do + defstruct [:name, :binder] + end + + defmodule BinderAtom do + defstruct [:value] + end + + defmodule BinderBinary do + defstruct [:binder] + end + defmodule BinderConstructor do defstruct [:name, :args] end @@ -146,4 +158,12 @@ defmodule Phi.AST do defmodule ExprRecordUpdate do defstruct [:base, :fields] # base is an expression, fields is [{name_string, expr}, ...] end + + defmodule ExprBinary do + defstruct [:value] # for binary values like <<111, 122>> or <<"binary">> + end + + defmodule ExprReceive do + defstruct [:clauses, :after_clause] + end end diff --git a/lib/phi/codegen.ex b/lib/phi/codegen.ex index 69a4ffb..1c2bbbf 100644 --- a/lib/phi/codegen.ex +++ b/lib/phi/codegen.ex @@ -361,7 +361,19 @@ defmodule Phi.Codegen do {mod, scheme, real_name, base_name} :error -> - throw({:unresolved_any_name, real_name}) + if constructor_name?(real_name) do + base_name = real_name |> String.split(".") |> List.last() + {nil, nil, real_name, base_name} + else + if String.contains?(real_name, ".") do + parts = String.split(real_name, ".") + {mod_parts, [base_name]} = Enum.split(parts, length(parts) - 1) + mod = Enum.join(mod_parts, ".") |> String.to_atom() + {mod, nil, real_name, base_name} + else + throw({:unresolved_any_name, real_name}) + end + end end end @@ -417,6 +429,47 @@ defmodule Phi.Codegen do defp generate_expr(%AST.ExprAtom{value: v}, _, _, _, _, _), do: {:atom, 1, String.to_atom(v)} + defp generate_expr(%AST.ExprBinary{value: values}, _, _, _, _, _) do + bin_elements = Enum.map(values, fn + {:number, val} -> {:bin_element, 1, {:integer, 1, val}, :default, :default} + {:string, val} -> {:bin_element, 1, {:string, 1, String.to_charlist(val)}, :default, :default} + end) + {:bin, 1, bin_elements} + end + + defp generate_expr( + %AST.ExprReceive{clauses: clauses, after_clause: after_clause}, + local_env, + global_env, + current_mod, + name, + fix_env + ) do + # Generate receive clauses + erl_clauses = + Enum.map(clauses, fn {pattern, expr} -> + pattern_erl = generate_pattern(pattern) + clause_locals = MapSet.union(local_env, find_bound_vars(pattern, MapSet.new())) + expr_erl = generate_expr(expr, clause_locals, global_env, current_mod, name, fix_env) + {:clause, 1, [pattern_erl], [], [expr_erl]} + end) + + # Generate after clause if present + case after_clause do + :none -> + {:receive, 1, erl_clauses} + + {:ok, after_body} -> + after_erl = generate_expr(after_body, local_env, global_env, current_mod, name, fix_env) + {:receive, 1, erl_clauses, {:integer, 1, 0}, [after_erl]} + + {:ok, timeout_expr, after_body} -> + timeout_erl = generate_expr(timeout_expr, local_env, global_env, current_mod, name, fix_env) + after_erl = generate_expr(after_body, local_env, global_env, current_mod, name, fix_env) + {:receive, 1, erl_clauses, timeout_erl, [after_erl]} + end + end + defp generate_expr(%AST.ExprVar{name: "num_" <> ns}, _, _, _, _, _), do: {:integer, 1, String.to_integer(ns)} @@ -437,6 +490,18 @@ defmodule Phi.Codegen do do: {:call, 1, {:remote, 1, {:atom, 1, :erlang}, {:atom, 1, :error}}, [{:atom, 1, :undefined}]} + defp generate_expr( + %AST.ExprDo{statements: statements}, + local_env, + global_env, + current_mod, + name, + fix_env + ) do + desugared = desugar_do(statements) + generate_expr(desugared, local_env, global_env, current_mod, name, fix_env) + end + defp generate_expr(%AST.ExprVar{name: name}, local_env, global_env, current_mod, _name, fix_env) do if Map.has_key?(fix_env, name) do Map.get(fix_env, name) @@ -572,12 +637,6 @@ defmodule Phi.Codegen do class_name = global_env.member_to_class[real_name] || extract_class_name(scheme) dict_arg_name = find_dictionary(class_name, local_env) - if base_name == "quickCheck" do - IO.puts( - "DEBUG quickCheck: num_dicts: \#{num_dicts}, class_name: \#{class_name}, dict_arg_name: \#{dict_arg_name}, num_args: \#{num_args}, total_arity: \#{total_arity}" - ) - end - if class_name do is_method = Map.has_key?(global_env.member_to_class, real_name) @@ -607,24 +666,31 @@ defmodule Phi.Codegen do ) end else - if base_name == "quickCheck" do - IO.puts("DEBUG quickCheck: FALLING INTO generate_dispatch_call") + if is_method do + generate_dispatch_call( + real_name, + mod, + erl_args, + class_name, + global_env, + current_mod + ) + else + # Constrained non-method with no dict in scope. + # Preserve dict-first calling convention by wrapping: + # fun(D1..Dn) -> f(D1..Dn, args...) end + dict_vars = + Enum.map(1..num_dicts, fn i -> + {:var, 1, String.to_atom("D#{i}")} + end) + + call = + generate_static_call(base_name, mod, total_arity, dict_vars ++ erl_args, current_mod) + + {:fun, 1, {:clauses, [{:clause, 1, dict_vars, [], [call]}]}} end - - generate_dispatch_call( - real_name, - mod, - erl_args, - class_name, - global_env, - current_mod - ) end else - if base_name == "quickCheck" do - IO.puts("DEBUG quickCheck: FALLING INTO static_call (class_name is nil)") - end - final_args = if dict_arg_name, do: [{:var, 1, String.to_atom(dict_arg_name)} | erl_args], @@ -793,6 +859,26 @@ defmodule Phi.Codegen do defp generate_expr(nil, _, _, _, _, _), do: {:atom, 1, :undefined} defp generate_expr(expr, _, _, _, _, _), do: raise("Unsupported: #{inspect(expr)}") + defp desugar_do([]), do: %AST.ExprVar{name: "unit"} + + defp desugar_do([{:expr, expr}]), do: expr + + defp desugar_do([{:bind, binder, expr}]), + do: %AST.ExprApp{func: %AST.ExprVar{name: "bind"}, arg: %AST.ExprTuple{elems: [expr, %AST.ExprLam{binder: binder, body: %AST.ExprVar{name: "unit"}}]}} + + defp desugar_do([{:let, decls} | rest]) do + %AST.ExprLet{bindings: decls, body: desugar_do(rest)} + end + + defp desugar_do([{:bind, binder, expr} | rest]) do + lam = %AST.ExprLam{binder: binder, body: desugar_do(rest)} + %AST.ExprApp{func: %AST.ExprApp{func: %AST.ExprVar{name: "bind"}, arg: expr}, arg: lam} + end + + defp desugar_do([{:expr, expr} | rest]) do + %AST.ExprApp{func: %AST.ExprApp{func: %AST.ExprVar{name: "discard"}, arg: expr}, arg: desugar_do(rest)} + end + defp constructor_name?(name) when is_binary(name) do last_part = name |> String.split(".") |> List.last() match?(<> when first >= ?A and first <= ?Z, last_part) @@ -816,6 +902,13 @@ defmodule Phi.Codegen do defp generate_pattern(%AST.BinderVar{name: "char_" <> cs}), do: {:integer, 1, String.to_integer(cs)} + defp generate_pattern(%AST.BinderAtom{value: v}), do: {:atom, 1, String.to_atom(v)} + + defp generate_pattern(%AST.BinderBinary{binder: b}) do + inner = generate_pattern(b) + {:bin, 1, [{:bin_element, 1, inner, :default, :default}]} + end + defp generate_pattern(%AST.BinderVar{name: name}), do: {:var, 1, String.capitalize(name) |> String.to_atom()} @@ -828,6 +921,10 @@ defmodule Phi.Codegen do defp generate_pattern(%AST.BinderTuple{elems: es}), do: {:tuple, 1, Enum.map(es, &generate_pattern/1)} + defp generate_pattern(%AST.BinderAs{name: name, binder: binder}) do + {:match, 1, {:var, 1, String.capitalize(name) |> String.to_atom()}, generate_pattern(binder)} + end + defp generate_pattern(%AST.BinderConstructor{name: name, args: args}), do: {:tuple, 1, [{:atom, 1, String.to_atom(name)} | Enum.map(args, &generate_pattern/1)]} @@ -884,6 +981,13 @@ defmodule Phi.Codegen do defp find_bound_vars(%AST.BinderVar{name: "char_" <> _}, acc), do: acc defp find_bound_vars(%AST.BinderVar{name: n}, acc), do: MapSet.put(acc, n) + defp find_bound_vars(%AST.BinderAtom{}, acc), do: acc + + defp find_bound_vars(%AST.BinderBinary{binder: b}, acc), do: find_bound_vars(b, acc) + + defp find_bound_vars(%AST.BinderAs{name: n, binder: b}, acc), + do: find_bound_vars(b, MapSet.put(acc, n)) + defp find_bound_vars(%AST.BinderConstructor{args: as}, acc), do: Enum.reduce(as, acc, &find_bound_vars/2) @@ -991,12 +1095,6 @@ defmodule Phi.Codegen do if base_name == "map" and n > 1 and is_method, do: 1, else: 0 end - if base_name == "<$>" or base_name == "map" do - IO.puts( - "DEBUG DISPATCH #{base_name} -> preferred_idx: #{preferred_idx}, scheme_present: #{scheme != nil}" - ) - end - dispatch_order = cond do n == 0 -> @@ -1032,9 +1130,12 @@ defmodule Phi.Codegen do %Type.TConstrained{class_name: cn, args: [%Type.TVar{id: vn} | _]} -> {:var, 1, String.to_atom("Dict_#{cn}_#{vn}")} + %Type.TConstrained{class_name: cn, args: [%Type.TCon{name: tn} | _]} -> + {:var, 1, String.to_atom("Dict_#{cn}_#{tn}")} + _ -> - # Fallback, might crash if unresolved but better than arity 0 - {:var, 1, :Dict_K} + # Fallback: keep Erlang compilation working; will likely crash at runtime + {:atom, 1, :undefined_dict} end) else [] @@ -1143,9 +1244,6 @@ defmodule Phi.Codegen do result || ( - if base_name == "quickCheck" do - IO.puts("DEBUG quickCheck: FALLING INTO generate_dispatch_call result=nil fallback") - end is_method = Map.has_key?(global_env.member_to_class, real_name) @@ -1278,5 +1376,30 @@ defmodule Phi.Codegen do defp find_used_vars(%AST.ExprIf{cond: c, then_br: t, else_br: e}, acc), do: find_used_vars(e, find_used_vars(t, find_used_vars(c, acc))) + defp find_used_vars(%AST.ExprDo{statements: stats}, acc) do + Enum.reduce(stats, acc, fn + {:bind, _binder, expr}, a -> find_used_vars(expr, a) + {:expr, expr}, a -> find_used_vars(expr, a) + {:let, decls}, a -> + Enum.reduce(decls, a, fn + %AST.DeclValue{expr: r}, a2 -> find_used_vars(r, a2) + _, a2 -> a2 + end) + end) + end + + defp find_used_vars(%AST.ExprReceive{clauses: clauses, after_clause: after_clause}, acc) do + acc1 = + Enum.reduce(clauses, acc, fn {_pat, body}, a -> + find_used_vars(body, a) + end) + + case after_clause do + :none -> acc1 + {:ok, after_body} -> find_used_vars(after_body, acc1) + {:ok, timeout_expr, after_body} -> find_used_vars(after_body, find_used_vars(timeout_expr, acc1)) + end + end + defp find_used_vars(_, acc), do: acc end diff --git a/lib/phi/compiler.ex b/lib/phi/compiler.ex index e3b744e..46cc9c8 100644 --- a/lib/phi/compiler.ex +++ b/lib/phi/compiler.ex @@ -16,7 +16,7 @@ defmodule Phi.Compiler do foreign_mod = if source_path do :code.add_patha(~c"ebin") - erl_path = String.replace(source_path, ".hm", ".erl") + erl_path = String.replace(source_path, ".phi", ".erl") if File.exists?(erl_path) do erl_content = File.read!(erl_path) @@ -74,6 +74,12 @@ defmodule Phi.Compiler do {:error, _} = err -> err end + else + {:error, _reason} = err when tuple_size(err) == 2 -> + err + + err -> + {:error, err} end end diff --git a/lib/phi/layout.ex b/lib/phi/layout.ex index d014ef9..33137ea 100644 --- a/lib/phi/layout.ex +++ b/lib/phi/layout.ex @@ -29,6 +29,12 @@ defmodule Phi.Layout do [{layout_type, layout_col, layout_depth} | ctx_rest] -> cond do + # Close `do`/`of`/`receive` blocks on `where` at the same indentation. + # This prevents injecting `; where` inside the block. + elem(token, 0) == :where and layout_type in [:do, :of, :receive] and col == layout_col and + depth == layout_depth -> + do_resolve(tokens, [{:right_brace, line, col} | acc], ctx_rest, depth) + # 1. Indentation outdent takes priority col < layout_col and depth <= layout_depth -> do_resolve(tokens, [{:right_brace, line, col} | acc], ctx_rest, depth) @@ -59,11 +65,15 @@ defmodule Phi.Layout do [{:left_brace, _, _} | _] -> do_resolve_token(tokens, acc, ctx, depth) - _ when elem(token, 0) in [:in, :else_kw, :then_kw, :of] -> + _ when elem(token, 0) in [:in, :else_kw, :then_kw, :of, :receive, :after] -> do_resolve_token(tokens, acc, ctx, depth) _ -> - do_resolve_token(tokens, [{:semicolon, line, col} | acc], ctx, depth) + if elem(token, 0) == :var_ident and is_function_definition?(tokens) do + do_resolve_token(tokens, [{:semicolon, line, col} | acc], ctx, depth) + else + do_resolve_token(tokens, [{:semicolon, line, col} | acc], ctx, depth) + end end true -> @@ -77,6 +87,25 @@ defmodule Phi.Layout do defp is_delimiter?({:right_brace, _, _}), do: true defp is_delimiter?(_), do: false + # Check if tokens represent a function definition: pattern = expr + defp is_function_definition?([{:var_ident, _, _, _} | rest]) do + # Look for := in the rest of the tokens (function definition) + Enum.any?(rest, fn + {:=, _, _} -> true + _ -> false + end) + end + + defp is_function_definition?([{:proper_name, _, _, _} | rest]) do + # Look for := in the rest of the tokens (function definition) + Enum.any?(rest, fn + {:=, _, _} -> true + _ -> false + end) + end + + defp is_function_definition?(_), do: false + defp do_resolve_token([{:left_paren, line, col} | rest], acc, ctx, depth) do do_resolve(rest, [{:left_paren, line, col} | acc], ctx, depth + 1) end @@ -186,6 +215,26 @@ defmodule Phi.Layout do end end + defp do_resolve_token([{:receive, line, col} | rest], acc, ctx, depth) do + acc = [{:receive, line, col} | acc] + + case rest do + [] -> + do_resolve([], acc, ctx, depth) + + [next | _] -> + next_line = elem(next, 1) + next_col = elem(next, 2) + + do_resolve( + rest, + [{:left_brace, next_line, next_col} | acc], + [{:receive, next_col, depth} | ctx], + depth + ) + end + end + defp do_resolve_token([token | rest], acc, ctx, depth) do do_resolve(rest, [token | acc], ctx, depth) end diff --git a/lib/phi/lexer.ex b/lib/phi/lexer.ex index fc2af04..9700a46 100644 --- a/lib/phi/lexer.ex +++ b/lib/phi/lexer.ex @@ -75,6 +75,8 @@ defmodule Phi.Lexer do lex(rest2, line, col + 1 + String.length(ident), [{:atom, line, col, ident} | acc]) end + defp lex([?:, ?" | rest], line, col, acc), do: lex_quoted_atom(rest, line, col + 2, acc, []) + defp lex([?: | rest], line, col, acc), do: lex(rest, line, col + 1, [{:operator, line, col, ":"} | acc]) @@ -101,6 +103,7 @@ defmodule Phi.Lexer do ident = List.to_string(ident_chars) case ident do + "_" -> lex(rest2, line, col + String.length(ident), [{:wildcard, line, col} | acc]) "module" -> lex(rest2, line, col + String.length(ident), [{:module, line, col} | acc]) "where" -> lex(rest2, line, col + String.length(ident), [{:where, line, col} | acc]) "import" -> lex(rest2, line, col + String.length(ident), [{:import, line, col} | acc]) @@ -123,6 +126,8 @@ defmodule Phi.Lexer do "case" -> lex(rest2, line, col + String.length(ident), [{:case, line, col} | acc]) "of" -> lex(rest2, line, col + String.length(ident), [{:of, line, col} | acc]) "do" -> lex(rest2, line, col + String.length(ident), [{:do, line, col} | acc]) + "receive" -> lex(rest2, line, col + String.length(ident), [{:receive, line, col} | acc]) + "after" -> lex(rest2, line, col + String.length(ident), [{:after, line, col} | acc]) "forall" -> lex(rest2, line, col + String.length(ident), [{:forall, line, col} | acc]) _ -> lex(rest2, line, col + String.length(ident), [{:var_ident, line, col, ident} | acc]) end @@ -220,4 +225,21 @@ defmodule Phi.Lexer do end defp take_string([]), do: {[], []} + + defp lex_quoted_atom([?" | rest], line, col, outer_acc, atom_acc) do + atom_str = List.to_string(Enum.reverse(atom_acc)) + start_col = col - String.length(atom_str) - 2 + lex(rest, line, col + 1, [{:atom, line, start_col, atom_str} | outer_acc]) + end + + defp lex_quoted_atom([?\\, c | rest], line, col, outer_acc, atom_acc) do + lex_quoted_atom(rest, line, col + 1, outer_acc, [c, ?\\ | atom_acc]) + end + + defp lex_quoted_atom([c | rest], line, col, outer_acc, atom_acc) do + lex_quoted_atom(rest, line, col + 1, outer_acc, [c | atom_acc]) + end + + defp lex_quoted_atom([], _line, _col, _outer_acc, _atom_acc), + do: {:error, "Unterminated quoted atom"} end diff --git a/lib/phi/parser.ex b/lib/phi/parser.ex index 0d2b5a2..f0736ac 100644 --- a/lib/phi/parser.ex +++ b/lib/phi/parser.ex @@ -70,6 +70,71 @@ defmodule Phi.Parser do defp parse_module(tokens), do: {:error, :invalid_module, tokens} + defp parse_expr_no_where([{:right_brace, _, _} | rest]), do: parse_expr_no_where(rest) + + defp parse_expr_no_where(tokens) do + case tokens do + [{:backslash, _, _} | rest] -> + case parse_binder_args(rest, []) do + {:ok, args, [{:arrow, _, _} | rest2]} -> + case parse_expr_no_where(rest2) do + {:ok, body, rest3} -> + lam = + Enum.reduce(Enum.reverse(args), body, fn b, acc -> + %AST.ExprLam{binder: b, body: acc} + end) + + {:ok, lam, rest3} + + err -> + err + end + + err -> + err + end + + [{:let, _, _}, {:left_brace, _, _} | rest] -> + case parse_decls(rest, []) do + {:ok, decls, [{:in, _, _} | rest2]} -> + case parse_expr_no_where(rest2) do + {:ok, body, rest3} -> {:ok, %AST.ExprLet{bindings: decls, body: body}, rest3} + err -> err + end + + {:ok, _decls, rest2} -> + {:error, :expected_in, rest2} + + err -> + err + end + + [{:if_kw, _, _} | rest] -> + parse_if_expression(rest) + + [{:case, _, _} | rest] -> + case parse_expr_no_where(rest) do + {:ok, case_expr, [{:of, _, _}, {:left_brace, _, _} | rest2]} -> + case parse_case_branches(rest2, []) do + {:ok, branches, rest3} -> {:ok, %AST.ExprCase{exprs: [case_expr], branches: branches}, rest3} + err -> err + end + + err -> + err + end + + [{:do, _, _}, {:left_brace, _, _} | rest] -> + case parse_do_statements(rest, []) do + {:ok, stats, rest2} -> {:ok, %AST.ExprDo{statements: stats}, rest2} + err -> err + end + + _ -> + parse_expr_infix(tokens) + end + end + defp parse_body(name, tokens) do case parse_decls(tokens, []) do {:ok, decls, rest} -> @@ -614,7 +679,12 @@ defmodule Phi.Parser do {:ok, t, [{:double_arrow, _, _} | rest]} -> case parse_type(rest) do - {:ok, t2, rest2} -> {:ok, %AST.TypeConstrained{constraints: [t], type: t2}, rest2} + {:ok, %AST.TypeConstrained{constraints: cs, type: inner}, rest2} -> + {:ok, %AST.TypeConstrained{constraints: [t | cs], type: inner}, rest2} + + {:ok, t2, rest2} -> + {:ok, %AST.TypeConstrained{constraints: [t], type: t2}, rest2} + err -> err end @@ -772,7 +842,7 @@ defmodule Phi.Parser do %AST.ExprLam{binder: b, body: acc} end) - {:ok, lam, rest3} + parse_expr_where(lam, rest3) err -> err @@ -798,24 +868,9 @@ defmodule Phi.Parser do end [{:if_kw, _, _} | rest] -> - case parse_expr(rest) do - {:ok, cond, [{:then_kw, _, _} | rest2]} -> - case parse_expr(rest2) do - {:ok, then_br, [{:else_kw, _, _} | rest3]} -> - case parse_expr(rest3) do - {:ok, else_br, rest4} -> - {:ok, %AST.ExprIf{cond: cond, then_br: then_br, else_br: else_br}, rest4} - - err -> - err - end - - err -> - err - end - - err -> - err + case parse_if_expression(rest) do + {:ok, if_expr, rest2} -> parse_expr_where(if_expr, rest2) + err -> err end [{:case, _, _} | rest] -> @@ -835,15 +890,52 @@ defmodule Phi.Parser do [{:do, _, _}, {:left_brace, _, _} | rest] -> case parse_do_statements(rest, []) do - {:ok, stats, rest2} -> {:ok, %AST.ExprDo{statements: stats}, rest2} + {:ok, stats, rest2} -> parse_expr_where(%AST.ExprDo{statements: stats}, rest2) err -> err end _ -> - parse_expr_infix(tokens) + case parse_expr_infix(tokens) do + {:ok, expr, rest} -> parse_expr_where(expr, rest) + err -> err + end + end + end + + defp parse_if_expression(tokens) do + case parse_expr_no_where(tokens) do + {:ok, cond_expr, [{:then_kw, _, _} | rest_then]} -> + case parse_expr_no_where(rest_then) do + {:ok, then_expr, [{:else_kw, _, _} | rest_else]} -> + case parse_expr_no_where(rest_else) do + {:ok, else_expr, rest2} -> + {:ok, %AST.ExprIf{cond: cond_expr, then_br: then_expr, else_br: else_expr}, rest2} + + err -> + err + end + + err -> + err + end + + {:ok, _cond_expr, [{tok, line, col} | _] = rest} -> + {:error, :expected_then, {tok, line, col, rest}} + + err -> + err + end + end + + defp parse_expr_where(expr, [{:where, _, _}, {:left_brace, _, _} | rest]) do + case parse_decls(rest, []) do + {:ok, decls, rest2} -> {:ok, %AST.ExprLet{bindings: decls, body: expr}, rest2} + err -> err end end + defp parse_expr_where(expr, rest), do: {:ok, expr, rest} + defp parse_expr_infix(tokens) do case parse_expr_atom_or_app(tokens) do {:ok, left, rest} -> @@ -963,6 +1055,7 @@ defmodule Phi.Parser do :right_paren, :right_square, :in, + :where, :else_kw, :then_kw, :of, @@ -974,6 +1067,16 @@ defmodule Phi.Parser do ], do: {:ok, func_expr, tokens} + defp parse_expr_app_tail(func_expr, [{:operator, _, _, "<<"} | _] = tokens) do + case parse_expr_atom(tokens) do + {:ok, arg_expr, rest} -> + parse_expr_app_tail(%AST.ExprApp{func: func_expr, arg: arg_expr}, rest) + + _ -> + {:ok, func_expr, tokens} + end + end + defp parse_expr_app_tail(func_expr, [{:operator, _, _, _} | _] = tokens), do: {:ok, func_expr, tokens} @@ -1038,8 +1141,20 @@ defmodule Phi.Parser do defp parse_expr_atom_base([{:atom, _, _, val} | rest]), do: {:ok, %AST.ExprAtom{value: val}, rest} + defp parse_expr_atom_base([{:wildcard, _, _} | rest]), + do: {:ok, %AST.ExprAtom{value: "_"}, rest} + defp parse_expr_atom_base([{:unit, _, _} | rest]), do: {:ok, %AST.ExprVar{name: "unit"}, rest} + defp parse_expr_atom_base([{:operator, _, _, "<<"} | rest]) do + case parse_binary_content(rest) do + {:ok, content, [{:operator, _, _, ">>"} | rest2]} -> + {:ok, content, rest2} + {:ok, _content, _rest} -> + {:error, :expected_right_double_angle} + end + end + defp parse_expr_atom_base([{:left_paren, _, _} | rest]) do case rest do [{:operator, _, _, op}, {:right_paren, _, _} | rest2] -> @@ -1070,36 +1185,40 @@ defmodule Phi.Parser do {:ok, exprs, [ {:pipe, _, _} - | [{:var_ident, _, _, var_name}, {:operator, _, _, "<-"} | rest_gen] = _rest_p + | rest_p ]} -> - # List comprehension: [expr | var <- list] - case parse_expr(rest_gen) do - {:ok, gen_list, [{:right_square, _, _} | rest2]} -> - body = - case exprs do - [single] -> single - multi -> %AST.ExprTuple{elems: multi} - end + # Either list comprehension: [expr | binder <- list] + # or list with tail: [exprs | tail] + case parse_binder(rest_p) do + {:ok, binder, [{:operator, _, _, "<-"} | rest_gen]} -> + case parse_expr(rest_gen) do + {:ok, gen_list, [{:right_square, _, _} | rest2]} -> + body = + case exprs do + [single] -> single + multi -> %AST.ExprTuple{elems: multi} + end - lambda = %AST.ExprLam{binder: %AST.ExprVar{name: var_name}, body: body} + lambda = %AST.ExprLam{binder: binder, body: body} - {:ok, - %AST.ExprApp{ - func: %AST.ExprApp{func: %AST.ExprVar{name: "mapListImpl"}, arg: lambda}, - arg: gen_list - }, rest2} + {:ok, + %AST.ExprApp{ + func: %AST.ExprApp{func: %AST.ExprVar{name: "Data.Functor.mapListImpl"}, arg: lambda}, + arg: gen_list + }, rest2} - err -> - err - end + err -> + err + end - {:ok, exprs, [{:pipe, _, _} | rest_p]} -> - case parse_expr(rest_p) do - {:ok, tail, [{:right_square, _, _} | rest2]} -> - {:ok, %AST.ExprList{elems: exprs, tail: tail}, rest2} + _ -> + case parse_expr(rest_p) do + {:ok, tail, [{:right_square, _, _} | rest2]} -> + {:ok, %AST.ExprList{elems: exprs, tail: tail}, rest2} - err -> - err + err -> + err + end end {:ok, @@ -1112,7 +1231,7 @@ defmodule Phi.Parser do # [start..end] range syntax - desugar to enumIntegerRange start end {:ok, %AST.ExprApp{ - func: %AST.ExprApp{func: %AST.ExprVar{name: "enumIntegerRange"}, arg: start_e}, + func: %AST.ExprApp{func: %AST.ExprVar{name: "Data.Enum.enumIntegerRange"}, arg: start_e}, arg: end_e }, rest2} @@ -1129,11 +1248,18 @@ defmodule Phi.Parser do defp parse_expr_atom_base([{:operator, _, _, "-"} | rest]) do case parse_expr_atom_base(rest) do - {:ok, expr, rest2} -> {:ok, %AST.ExprApp{func: %AST.ExprVar{name: "-"}, arg: expr}, rest2} - err -> err + {:ok, expr, rest2} -> + {:ok, %AST.ExprApp{func: %AST.ExprVar{name: "negate"}, arg: expr}, rest2} + + _ -> + {:error, :invalid_negation} end end + defp parse_expr_atom_base([{:receive, _, _} | rest]) do + parse_receive_expression(rest) + end + defp parse_expr_atom_base(_), do: {:error, :invalid_expression_atom} defp parse_expr_atom_tail(expr, [{:dot, _line, _col}, {:var_ident, _, _, field} | rest]) do @@ -1236,6 +1362,12 @@ defmodule Phi.Parser do err -> err end + [{:let, _, _} | rest] -> + case parse_decl(rest) do + {:ok, decl, rest2} -> {:ok, {:let, [decl]}, rest2} + err -> err + end + _ -> case parse_expr(tokens) do {:ok, expr, rest} -> {:ok, {:expr, expr}, rest} @@ -1294,25 +1426,58 @@ defmodule Phi.Parser do end end + defp parse_binder([{:var_ident, _, _, name}, {:operator, _, _, "@"} | rest]) do + case parse_binder(rest) do + {:ok, binder, rest2} -> {:ok, %AST.BinderAs{name: name, binder: binder}, rest2} + err -> err + end + end + defp parse_binder([{:var_ident, _, _, name} | rest]), do: {:ok, %AST.BinderVar{name: name}, rest} defp parse_binder([{:proper_name, _, _, name} | rest]) do - case parse_binder_args(rest, []) do - {:ok, args, rest2} -> {:ok, %AST.BinderConstructor{name: name, args: args}, rest2} - err -> err + case rest do + [{:dot, _, _}, {:proper_name, _, _, constructor_name} | rest_after] -> + case parse_binder_args(rest_after, []) do + {:ok, args, rest2} -> + qualified_name = "#{name}.#{constructor_name}" + {:ok, %AST.BinderConstructor{name: qualified_name, args: args}, rest2} + + err -> + err + end + + _ -> + case parse_binder_args(rest, []) do + {:ok, args, rest2} -> {:ok, %AST.BinderConstructor{name: name, args: args}, rest2} + err -> err + end end end defp parse_binder([{:number, _, _, val} | rest]), do: {:ok, %AST.BinderVar{name: "num_#{val}"}, rest} + defp parse_binder([{:atom, _, _, val} | rest]), + do: {:ok, %AST.BinderAtom{value: val}, rest} + defp parse_binder([{:string, _, _, val} | rest]), do: {:ok, %AST.BinderVar{name: "str_" <> val}, rest} defp parse_binder([{:char, _, _, val} | rest]), do: {:ok, %AST.BinderVar{name: "char_#{val}"}, rest} + defp parse_binder([{:left_paren, _, _}, {:var_ident, _, _, name}, {:double_colon, _, _} | rest]) do + case parse_type(rest) do + {:ok, _type, [{:right_paren, _, _} | rest2]} -> + {:ok, %AST.BinderVar{name: name}, rest2} + + err -> + err + end + end + defp parse_binder([{:left_paren, _, _} | rest]) do case rest do [{:operator, _, _, op}, {:right_paren, _, _} | rest2] -> @@ -1356,6 +1521,17 @@ defmodule Phi.Parser do defp parse_binder([{:unit, _, _} | rest]), do: {:ok, %AST.BinderVar{name: "unit"}, rest} defp parse_binder([{:wildcard, _, _} | rest]), do: {:ok, %AST.BinderVar{name: "_"}, rest} + + defp parse_binder([{:operator, _, _, "<<"} | rest]) do + case parse_binder(rest) do + {:ok, inner, [{:operator, _, _, ">>"} | rest2]} -> + {:ok, %AST.BinderBinary{binder: inner}, rest2} + + err -> + err + end + end + defp parse_binder(_), do: {:error, :invalid_binder} defp parse_guards([{:pipe, _, _} | rest], acc) do @@ -1388,4 +1564,138 @@ defmodule Phi.Parser do {:ok, [], tokens} end end + + # Parse content inside << >> - binary values (comma-separated numbers or strings) + defp parse_binary_content(tokens) do + case parse_comma_separated(tokens, &parse_binary_value/1) do + {:ok, values, rest} -> {:ok, %AST.ExprBinary{value: values}, rest} + {:error, _, _} = err -> err + end + end + + # Parse individual binary values (numbers or strings) + defp parse_binary_value([{:number, _, _, val} | rest]) do + {:ok, {:number, val}, rest} + end + + defp parse_binary_value([{:string, _, _, val} | rest]) do + {:ok, {:string, val}, rest} + end + + defp parse_binary_value(tokens) do + {:error, :invalid_binary_value, tokens} + end + + # Parse receive expressions: receive pattern1 -> expr1 pattern2 -> expr2 after timeout -> expr + defp parse_receive_expression(tokens) do + case tokens do + [{:left_brace, _, _} | rest] -> + case parse_receive_block(rest, []) do + {:ok, clauses, rest2} -> + parse_receive_after(%AST.ExprReceive{clauses: clauses, after_clause: :none}, rest2) + + err -> + err + end + + _ -> + case parse_receive_clauses(tokens) do + {:ok, clauses, rest} -> + parse_receive_after(%AST.ExprReceive{clauses: clauses, after_clause: :none}, rest) + + err -> + err + end + end + end + + defp parse_receive_block([{:right_brace, _, _} | rest], acc), + do: {:ok, Enum.reverse(acc), rest} + + defp parse_receive_block(tokens, acc) do + case parse_receive_clause(tokens) do + {:ok, clause, rest} -> + case rest do + [{:semicolon, _, _} | rest2] -> + parse_receive_block(rest2, [clause | acc]) + + [{:after, _, _} | _] -> + {:ok, Enum.reverse([clause | acc]), rest} + + [{:right_brace, _, _} | _] -> + parse_receive_block(rest, [clause | acc]) + + _ -> + {:ok, Enum.reverse([clause | acc]), rest} + end + + err -> + err + end + end + + defp parse_receive_after(%AST.ExprReceive{} = recv, [{:after, _, _} | rest_after]) do + case rest_after do + [{:number, _, _, timeout_val}, {:arrow, _, _} | after_rest] -> + timeout_expr = %AST.ExprVar{name: "num_#{timeout_val}"} + + case parse_expr(after_rest) do + {:ok, after_body, rest_after2} -> + {:ok, %AST.ExprReceive{recv | after_clause: {:ok, timeout_expr, after_body}}, rest_after2} + + err -> + err + end + + _ -> + case parse_expr(rest_after) do + {:ok, after_body, rest_after2} -> + {:ok, %AST.ExprReceive{recv | after_clause: {:ok, after_body}}, rest_after2} + + err -> + err + end + end + end + + defp parse_receive_after(%AST.ExprReceive{} = recv, rest), do: {:ok, recv, rest} + + # Parse receive clauses: pattern -> expr (no commas, just sequential) + defp parse_receive_clauses(tokens) do + case parse_receive_clause(tokens) do + {:ok, clause, rest} -> + # Check if next token is 'after' - if so, this is the last clause + case rest do + [{:after, _, _} | _] -> + {:ok, [clause], rest} + _ -> + # For now, assume single clause (can extend later for multiple clauses) + {:ok, [clause], rest} + end + err -> + err + end + end + + # Parse single receive clause: pattern -> expr + defp parse_receive_clause(tokens) do + case parse_binder(tokens) do + {:ok, pattern, [{:arrow, _, _} | rest]} -> + case parse_expr(rest) do + {:ok, expr, rest2} -> + {:ok, {pattern, expr}, rest2} + err -> + err + end + {:ok, pattern, [{:operator, _, _, "->"} | rest]} -> + case parse_expr(rest) do + {:ok, expr, rest2} -> + {:ok, {pattern, expr}, rest2} + err -> + err + end + err -> + err + end + end end diff --git a/lib/phi/typechecker.ex b/lib/phi/typechecker.ex index 9cfda6e..8953308 100644 --- a/lib/phi/typechecker.ex +++ b/lib/phi/typechecker.ex @@ -39,10 +39,10 @@ defmodule Phi.Typechecker do } end - def extend(%Env{bindings: b} = env, module, name, scheme, hamler_mod \\ nil) do + def extend(%Env{bindings: b} = env, module, name, scheme, mod \\ nil) do # Store as {module, scheme} b1 = Map.put(b, name, {module, scheme}) - b2 = if hamler_mod, do: Map.put(b1, "#{hamler_mod}.#{name}", {module, scheme}), else: b1 + b2 = if mod, do: Map.put(b1, "#{mod}.#{name}", {module, scheme}), else: b1 %{env | bindings: b2} end @@ -59,15 +59,20 @@ defmodule Phi.Typechecker do end def resolve_term_alias(%Env{term_aliases: ta, module_aliases: ma}, name) do - case String.split(name, ".", parts: 2) do - [mod, member] -> + parts = String.split(name, ".") + + case parts do + [_single] -> + Map.get(ta, name, name) + + _ -> + {member_parts, [member]} = Enum.split(parts, length(parts) - 1) + mod = Enum.join(member_parts, ".") + case Map.get(ma, mod) do nil -> Map.get(ta, name, name) full_mod -> "#{full_mod}.#{member}" end - - _ -> - Map.get(ta, name, name) end end end @@ -122,7 +127,18 @@ defmodule Phi.Typechecker do %AST.DeclTypeAlias{name: name, type: ast_type}, acc -> type = ast_to_type(ast_type, acc) - Env.add_alias(acc, name, type) + acc2 = Env.add_alias(acc, name, type) + + case ast_type do + %AST.TypeRecord{fields: fields} -> + Enum.reduce(fields, acc2, fn field_name, e -> + acc_name = "access_#{field_name}" + Env.extend(e, erl_mod, acc_name, nil, mod_name) + end) + + _ -> + acc2 + end %AST.DeclClass{name: name, args: args, members: members}, acc -> # args here are [%AST.TypeVar{name: "a"}] etc. @@ -609,6 +625,53 @@ defmodule Phi.Typechecker do {:ok, t_binder, %{name => t_binder}, state2} end + defp infer_binder(env, state, %AST.BinderAtom{value: _v}) do + # Atom literal pattern binds no variables. + # If Atom type alias exists in env, use it; otherwise fall back to TCon("Atom"). + t_atom = + case Env.lookup_alias(env, "Atom") do + {:ok, t} -> t + :error -> %TCon{name: "Atom"} + end + + {:ok, t_atom, %{}, state} + end + + defp infer_binder(env, state, %AST.BinderBinary{binder: binder}) do + case infer_binder(env, state, binder) do + {:ok, _t_inner, bound_vars, state2} -> + t_bin = + case Env.lookup_alias(env, "Binary") do + {:ok, t} -> t + :error -> %TCon{name: "Binary"} + end + + {:ok, t_bin, bound_vars, state2} + + err -> + err + end + end + + defp infer_binder(env, state, %AST.BinderAs{name: name, binder: binder}) do + case infer_binder(env, state, binder) do + {:ok, t_inner, bound_vars, state2} -> + t_as = %TVar{id: state2.next_id} + state3 = %{state2 | next_id: state2.next_id + 1} + + case unify(t_as, t_inner, state3) do + {:ok, state4} -> + {:ok, apply_subst(state4.subst, t_as), Map.put(bound_vars, name, t_as), state4} + + err -> + err + end + + err -> + err + end + end + defp infer_binder(env, state, %AST.BinderConstructor{name: name, args: args}) do # 1. Lookup the constructor's type lookup_result = diff --git a/lib/Control/Application.erl b/stdlib/Control/Application.erl similarity index 100% rename from lib/Control/Application.erl rename to stdlib/Control/Application.erl diff --git a/lib/Control/Application.hm b/stdlib/Control/Application.phi similarity index 100% rename from lib/Control/Application.hm rename to stdlib/Control/Application.phi diff --git a/lib/Control/Application/Callback.erl b/stdlib/Control/Application/Callback.erl similarity index 100% rename from lib/Control/Application/Callback.erl rename to stdlib/Control/Application/Callback.erl diff --git a/lib/Control/Application/Callback.hm b/stdlib/Control/Application/Callback.phi similarity index 100% rename from lib/Control/Application/Callback.hm rename to stdlib/Control/Application/Callback.phi diff --git a/lib/Control/Application/Config.erl b/stdlib/Control/Application/Config.erl similarity index 100% rename from lib/Control/Application/Config.erl rename to stdlib/Control/Application/Config.erl diff --git a/lib/Control/Application/Config.hm b/stdlib/Control/Application/Config.phi similarity index 100% rename from lib/Control/Application/Config.hm rename to stdlib/Control/Application/Config.phi diff --git a/lib/Control/Application/Resource.erl b/stdlib/Control/Application/Resource.erl similarity index 100% rename from lib/Control/Application/Resource.erl rename to stdlib/Control/Application/Resource.erl diff --git a/lib/Control/Application/Resource.hm b/stdlib/Control/Application/Resource.phi similarity index 100% rename from lib/Control/Application/Resource.hm rename to stdlib/Control/Application/Resource.phi diff --git a/lib/Control/Application/Types.hm b/stdlib/Control/Application/Types.phi similarity index 100% rename from lib/Control/Application/Types.hm rename to stdlib/Control/Application/Types.phi diff --git a/lib/Control/Behaviour/GenEvent.erl b/stdlib/Control/Behaviour/GenEvent.erl similarity index 100% rename from lib/Control/Behaviour/GenEvent.erl rename to stdlib/Control/Behaviour/GenEvent.erl diff --git a/lib/Control/Behaviour/GenEvent.hm b/stdlib/Control/Behaviour/GenEvent.phi similarity index 100% rename from lib/Control/Behaviour/GenEvent.hm rename to stdlib/Control/Behaviour/GenEvent.phi diff --git a/lib/Control/Behaviour/GenEvent/Proxy.erl b/stdlib/Control/Behaviour/GenEvent/Proxy.erl similarity index 100% rename from lib/Control/Behaviour/GenEvent/Proxy.erl rename to stdlib/Control/Behaviour/GenEvent/Proxy.erl diff --git a/lib/Control/Behaviour/GenEvent/Proxy.hm b/stdlib/Control/Behaviour/GenEvent/Proxy.phi similarity index 100% rename from lib/Control/Behaviour/GenEvent/Proxy.hm rename to stdlib/Control/Behaviour/GenEvent/Proxy.phi diff --git a/lib/Control/Behaviour/GenEvent/Types.hm b/stdlib/Control/Behaviour/GenEvent/Types.phi similarity index 100% rename from lib/Control/Behaviour/GenEvent/Types.hm rename to stdlib/Control/Behaviour/GenEvent/Types.phi diff --git a/lib/Control/Behaviour/GenServer.erl b/stdlib/Control/Behaviour/GenServer.erl similarity index 100% rename from lib/Control/Behaviour/GenServer.erl rename to stdlib/Control/Behaviour/GenServer.erl diff --git a/lib/Control/Behaviour/GenServer.hm b/stdlib/Control/Behaviour/GenServer.phi similarity index 100% rename from lib/Control/Behaviour/GenServer.hm rename to stdlib/Control/Behaviour/GenServer.phi diff --git a/lib/Control/Behaviour/GenServer/Proxy.erl b/stdlib/Control/Behaviour/GenServer/Proxy.erl similarity index 100% rename from lib/Control/Behaviour/GenServer/Proxy.erl rename to stdlib/Control/Behaviour/GenServer/Proxy.erl diff --git a/lib/Control/Behaviour/GenServer/Proxy.hm b/stdlib/Control/Behaviour/GenServer/Proxy.phi similarity index 100% rename from lib/Control/Behaviour/GenServer/Proxy.hm rename to stdlib/Control/Behaviour/GenServer/Proxy.phi diff --git a/lib/Control/Behaviour/GenServer/Types.hm b/stdlib/Control/Behaviour/GenServer/Types.phi similarity index 100% rename from lib/Control/Behaviour/GenServer/Types.hm rename to stdlib/Control/Behaviour/GenServer/Types.phi diff --git a/lib/Control/Behaviour/GenStatem.erl b/stdlib/Control/Behaviour/GenStatem.erl similarity index 100% rename from lib/Control/Behaviour/GenStatem.erl rename to stdlib/Control/Behaviour/GenStatem.erl diff --git a/lib/Control/Behaviour/GenStatem.hm b/stdlib/Control/Behaviour/GenStatem.phi similarity index 100% rename from lib/Control/Behaviour/GenStatem.hm rename to stdlib/Control/Behaviour/GenStatem.phi diff --git a/lib/Control/Behaviour/GenStatem/Proxy.erl b/stdlib/Control/Behaviour/GenStatem/Proxy.erl similarity index 100% rename from lib/Control/Behaviour/GenStatem/Proxy.erl rename to stdlib/Control/Behaviour/GenStatem/Proxy.erl diff --git a/lib/Control/Behaviour/GenStatem/Proxy.hm b/stdlib/Control/Behaviour/GenStatem/Proxy.phi similarity index 100% rename from lib/Control/Behaviour/GenStatem/Proxy.hm rename to stdlib/Control/Behaviour/GenStatem/Proxy.phi diff --git a/lib/Control/Behaviour/GenStatem/Types.hm b/stdlib/Control/Behaviour/GenStatem/Types.phi similarity index 100% rename from lib/Control/Behaviour/GenStatem/Types.hm rename to stdlib/Control/Behaviour/GenStatem/Types.phi diff --git a/lib/Control/Behaviour/GenTypes.hm b/stdlib/Control/Behaviour/GenTypes.phi similarity index 100% rename from lib/Control/Behaviour/GenTypes.hm rename to stdlib/Control/Behaviour/GenTypes.phi diff --git a/lib/Control/Behaviour/Supervisor.erl b/stdlib/Control/Behaviour/Supervisor.erl similarity index 100% rename from lib/Control/Behaviour/Supervisor.erl rename to stdlib/Control/Behaviour/Supervisor.erl diff --git a/lib/Control/Behaviour/Supervisor.hm b/stdlib/Control/Behaviour/Supervisor.phi similarity index 100% rename from lib/Control/Behaviour/Supervisor.hm rename to stdlib/Control/Behaviour/Supervisor.phi diff --git a/lib/Control/Behaviour/Supervisor/Impl.erl b/stdlib/Control/Behaviour/Supervisor/Impl.erl similarity index 100% rename from lib/Control/Behaviour/Supervisor/Impl.erl rename to stdlib/Control/Behaviour/Supervisor/Impl.erl diff --git a/lib/Control/Behaviour/Supervisor/Impl.hrl b/stdlib/Control/Behaviour/Supervisor/Impl.hrl similarity index 100% rename from lib/Control/Behaviour/Supervisor/Impl.hrl rename to stdlib/Control/Behaviour/Supervisor/Impl.hrl diff --git a/lib/Control/Behaviour/Supervisor/Impl.hm b/stdlib/Control/Behaviour/Supervisor/Impl.phi similarity index 100% rename from lib/Control/Behaviour/Supervisor/Impl.hm rename to stdlib/Control/Behaviour/Supervisor/Impl.phi diff --git a/lib/Control/Behaviour/Supervisor/Proxy.erl b/stdlib/Control/Behaviour/Supervisor/Proxy.erl similarity index 100% rename from lib/Control/Behaviour/Supervisor/Proxy.erl rename to stdlib/Control/Behaviour/Supervisor/Proxy.erl diff --git a/lib/Control/Behaviour/Supervisor/Proxy.hm b/stdlib/Control/Behaviour/Supervisor/Proxy.phi similarity index 100% rename from lib/Control/Behaviour/Supervisor/Proxy.hm rename to stdlib/Control/Behaviour/Supervisor/Proxy.phi diff --git a/lib/Control/Behaviour/Supervisor/Types.hm b/stdlib/Control/Behaviour/Supervisor/Types.phi similarity index 100% rename from lib/Control/Behaviour/Supervisor/Types.hm rename to stdlib/Control/Behaviour/Supervisor/Types.phi diff --git a/lib/Control/Behaviour/Terminate.hm b/stdlib/Control/Behaviour/Terminate.phi similarity index 100% rename from lib/Control/Behaviour/Terminate.hm rename to stdlib/Control/Behaviour/Terminate.phi diff --git a/lib/Control/Distributed/Global.erl b/stdlib/Control/Distributed/Global.erl similarity index 100% rename from lib/Control/Distributed/Global.erl rename to stdlib/Control/Distributed/Global.erl diff --git a/lib/Control/Distributed/Global.hm b/stdlib/Control/Distributed/Global.phi similarity index 100% rename from lib/Control/Distributed/Global.hm rename to stdlib/Control/Distributed/Global.phi diff --git a/lib/Control/Distributed/GlobalGroup.erl b/stdlib/Control/Distributed/GlobalGroup.erl similarity index 100% rename from lib/Control/Distributed/GlobalGroup.erl rename to stdlib/Control/Distributed/GlobalGroup.erl diff --git a/lib/Control/Distributed/GlobalGroup.hm b/stdlib/Control/Distributed/GlobalGroup.phi similarity index 100% rename from lib/Control/Distributed/GlobalGroup.hm rename to stdlib/Control/Distributed/GlobalGroup.phi diff --git a/lib/Control/Distributed/NetAdm.erl b/stdlib/Control/Distributed/NetAdm.erl similarity index 100% rename from lib/Control/Distributed/NetAdm.erl rename to stdlib/Control/Distributed/NetAdm.erl diff --git a/lib/Control/Distributed/NetAdm.hm b/stdlib/Control/Distributed/NetAdm.phi similarity index 100% rename from lib/Control/Distributed/NetAdm.hm rename to stdlib/Control/Distributed/NetAdm.phi diff --git a/lib/Control/Distributed/NetKernel.erl b/stdlib/Control/Distributed/NetKernel.erl similarity index 100% rename from lib/Control/Distributed/NetKernel.erl rename to stdlib/Control/Distributed/NetKernel.erl diff --git a/lib/Control/Distributed/NetKernel.hm b/stdlib/Control/Distributed/NetKernel.phi similarity index 100% rename from lib/Control/Distributed/NetKernel.hm rename to stdlib/Control/Distributed/NetKernel.phi diff --git a/lib/Control/Distributed/Node.erl b/stdlib/Control/Distributed/Node.erl similarity index 100% rename from lib/Control/Distributed/Node.erl rename to stdlib/Control/Distributed/Node.erl diff --git a/lib/Control/Distributed/Node.hm b/stdlib/Control/Distributed/Node.phi similarity index 100% rename from lib/Control/Distributed/Node.hm rename to stdlib/Control/Distributed/Node.phi diff --git a/lib/Control/Distributed/PG.erl b/stdlib/Control/Distributed/PG.erl similarity index 100% rename from lib/Control/Distributed/PG.erl rename to stdlib/Control/Distributed/PG.erl diff --git a/lib/Control/Distributed/PG.hm b/stdlib/Control/Distributed/PG.phi similarity index 100% rename from lib/Control/Distributed/PG.hm rename to stdlib/Control/Distributed/PG.phi diff --git a/lib/Control/Distributed/Port.erl b/stdlib/Control/Distributed/Port.erl similarity index 100% rename from lib/Control/Distributed/Port.erl rename to stdlib/Control/Distributed/Port.erl diff --git a/lib/Control/Distributed/Port.hm b/stdlib/Control/Distributed/Port.phi similarity index 100% rename from lib/Control/Distributed/Port.hm rename to stdlib/Control/Distributed/Port.phi diff --git a/lib/Control/Distributed/README b/stdlib/Control/Distributed/README similarity index 100% rename from lib/Control/Distributed/README rename to stdlib/Control/Distributed/README diff --git a/lib/Control/Distributed/RPC.erl b/stdlib/Control/Distributed/RPC.erl similarity index 100% rename from lib/Control/Distributed/RPC.erl rename to stdlib/Control/Distributed/RPC.erl diff --git a/lib/Control/Distributed/RPC.hm b/stdlib/Control/Distributed/RPC.phi similarity index 100% rename from lib/Control/Distributed/RPC.hm rename to stdlib/Control/Distributed/RPC.phi diff --git a/lib/Control/Distributed/Slave.erl b/stdlib/Control/Distributed/Slave.erl similarity index 100% rename from lib/Control/Distributed/Slave.erl rename to stdlib/Control/Distributed/Slave.erl diff --git a/lib/Control/Distributed/Slave.hm b/stdlib/Control/Distributed/Slave.phi similarity index 100% rename from lib/Control/Distributed/Slave.hm rename to stdlib/Control/Distributed/Slave.phi diff --git a/lib/Control/Monad.erl b/stdlib/Control/Monad.erl similarity index 100% rename from lib/Control/Monad.erl rename to stdlib/Control/Monad.erl diff --git a/lib/Control/Monad.hm b/stdlib/Control/Monad.phi similarity index 100% rename from lib/Control/Monad.hm rename to stdlib/Control/Monad.phi diff --git a/lib/Control/Monad/Reader.hm b/stdlib/Control/Monad/Reader.phi similarity index 100% rename from lib/Control/Monad/Reader.hm rename to stdlib/Control/Monad/Reader.phi diff --git a/lib/Control/Monad/State.hm b/stdlib/Control/Monad/State.phi similarity index 100% rename from lib/Control/Monad/State.hm rename to stdlib/Control/Monad/State.phi diff --git a/lib/Control/Monad/Writer.hm b/stdlib/Control/Monad/Writer.phi similarity index 100% rename from lib/Control/Monad/Writer.hm rename to stdlib/Control/Monad/Writer.phi diff --git a/lib/Control/Process.erl b/stdlib/Control/Process.erl similarity index 100% rename from lib/Control/Process.erl rename to stdlib/Control/Process.erl diff --git a/lib/Control/Process.hm b/stdlib/Control/Process.phi similarity index 100% rename from lib/Control/Process.hm rename to stdlib/Control/Process.phi diff --git a/lib/Control/Process/Dict.erl b/stdlib/Control/Process/Dict.erl similarity index 100% rename from lib/Control/Process/Dict.erl rename to stdlib/Control/Process/Dict.erl diff --git a/lib/Control/Process/Dict.hm b/stdlib/Control/Process/Dict.phi similarity index 100% rename from lib/Control/Process/Dict.hm rename to stdlib/Control/Process/Dict.phi diff --git a/lib/Control/Process/Flags.erl b/stdlib/Control/Process/Flags.erl similarity index 100% rename from lib/Control/Process/Flags.erl rename to stdlib/Control/Process/Flags.erl diff --git a/lib/Control/Process/Flags.hm b/stdlib/Control/Process/Flags.phi similarity index 100% rename from lib/Control/Process/Flags.hm rename to stdlib/Control/Process/Flags.phi diff --git a/lib/Control/Process/GC.erl b/stdlib/Control/Process/GC.erl similarity index 100% rename from lib/Control/Process/GC.erl rename to stdlib/Control/Process/GC.erl diff --git a/lib/Control/Process/GC.hm b/stdlib/Control/Process/GC.phi similarity index 100% rename from lib/Control/Process/GC.hm rename to stdlib/Control/Process/GC.phi diff --git a/lib/Control/Process/Infos.erl b/stdlib/Control/Process/Infos.erl similarity index 100% rename from lib/Control/Process/Infos.erl rename to stdlib/Control/Process/Infos.erl diff --git a/lib/Control/Process/Infos.hm b/stdlib/Control/Process/Infos.phi similarity index 100% rename from lib/Control/Process/Infos.hm rename to stdlib/Control/Process/Infos.phi diff --git a/lib/Control/Process/Proxy.erl b/stdlib/Control/Process/Proxy.erl similarity index 100% rename from lib/Control/Process/Proxy.erl rename to stdlib/Control/Process/Proxy.erl diff --git a/lib/Control/Process/Proxy.hm b/stdlib/Control/Process/Proxy.phi similarity index 100% rename from lib/Control/Process/Proxy.hm rename to stdlib/Control/Process/Proxy.phi diff --git a/lib/Control/Process/Spawn.erl b/stdlib/Control/Process/Spawn.erl similarity index 100% rename from lib/Control/Process/Spawn.erl rename to stdlib/Control/Process/Spawn.erl diff --git a/lib/Control/Process/Spawn.hm b/stdlib/Control/Process/Spawn.phi similarity index 100% rename from lib/Control/Process/Spawn.hm rename to stdlib/Control/Process/Spawn.phi diff --git a/lib/Control/Process/Types.hm b/stdlib/Control/Process/Types.phi similarity index 100% rename from lib/Control/Process/Types.hm rename to stdlib/Control/Process/Types.phi diff --git a/lib/Data/Array.erl b/stdlib/Data/Array.erl similarity index 100% rename from lib/Data/Array.erl rename to stdlib/Data/Array.erl diff --git a/lib/Data/Array.hm b/stdlib/Data/Array.phi similarity index 96% rename from lib/Data/Array.hm rename to stdlib/Data/Array.phi index 0fdd002..4675443 100644 --- a/lib/Data/Array.hm +++ b/stdlib/Data/Array.phi @@ -31,8 +31,6 @@ import Control.Monad (liftA1, class Monad, class Applicative, apply, bind) import Foreign (ffi1, ffi2, ffi3) -import Test.QuickCheck (arbitrary, class Arbitrary) - foreign import data Array :: Type -> Type instance Eq t => Eq (Array t) where @@ -76,9 +74,6 @@ instance Applicative Array where instance Monad Array where bind xs f = fromList (bind (toList xs) (\x -> toList (f x))) -instance Arbitrary v => Arbitrary (Array v) where - arbitrary = fromList <$> arbitrary - {- TODO: functions is_array/1 Why a strong type system language need this? -} diff --git a/lib/Data/Atom.hm b/stdlib/Data/Atom.phi similarity index 100% rename from lib/Data/Atom.hm rename to stdlib/Data/Atom.phi diff --git a/lib/Data/Atomics.erl b/stdlib/Data/Atomics.erl similarity index 100% rename from lib/Data/Atomics.erl rename to stdlib/Data/Atomics.erl diff --git a/lib/Data/Atomics.hm b/stdlib/Data/Atomics.phi similarity index 100% rename from lib/Data/Atomics.hm rename to stdlib/Data/Atomics.phi diff --git a/lib/Data/Binary.erl b/stdlib/Data/Binary.erl similarity index 100% rename from lib/Data/Binary.erl rename to stdlib/Data/Binary.erl diff --git a/lib/Data/Binary.hm b/stdlib/Data/Binary.phi similarity index 100% rename from lib/Data/Binary.hm rename to stdlib/Data/Binary.phi diff --git a/lib/Data/Binary/Base64.hm b/stdlib/Data/Binary/Base64.phi similarity index 100% rename from lib/Data/Binary/Base64.hm rename to stdlib/Data/Binary/Base64.phi diff --git a/lib/Data/Bits.erl b/stdlib/Data/Bits.erl similarity index 100% rename from lib/Data/Bits.erl rename to stdlib/Data/Bits.erl diff --git a/lib/Data/Bits.hm b/stdlib/Data/Bits.phi similarity index 100% rename from lib/Data/Bits.hm rename to stdlib/Data/Bits.phi diff --git a/lib/Data/Bool.hm b/stdlib/Data/Bool.phi similarity index 100% rename from lib/Data/Bool.hm rename to stdlib/Data/Bool.phi diff --git a/lib/Data/Char.erl b/stdlib/Data/Char.erl similarity index 100% rename from lib/Data/Char.erl rename to stdlib/Data/Char.erl diff --git a/lib/Data/Char.hm b/stdlib/Data/Char.phi similarity index 100% rename from lib/Data/Char.hm rename to stdlib/Data/Char.phi diff --git a/lib/Data/Counters.erl b/stdlib/Data/Counters.erl similarity index 100% rename from lib/Data/Counters.erl rename to stdlib/Data/Counters.erl diff --git a/lib/Data/Counters.hm b/stdlib/Data/Counters.phi similarity index 100% rename from lib/Data/Counters.hm rename to stdlib/Data/Counters.phi diff --git a/lib/Data/DateTime.hm b/stdlib/Data/DateTime.phi similarity index 100% rename from lib/Data/DateTime.hm rename to stdlib/Data/DateTime.phi diff --git a/lib/Data/Digraph.erl b/stdlib/Data/Digraph.erl similarity index 100% rename from lib/Data/Digraph.erl rename to stdlib/Data/Digraph.erl diff --git a/lib/Data/Digraph.hm b/stdlib/Data/Digraph.phi similarity index 100% rename from lib/Data/Digraph.hm rename to stdlib/Data/Digraph.phi diff --git a/lib/Data/EVal.erl b/stdlib/Data/EVal.erl similarity index 100% rename from lib/Data/EVal.erl rename to stdlib/Data/EVal.erl diff --git a/lib/Data/EVal.hrl b/stdlib/Data/EVal.hrl similarity index 100% rename from lib/Data/EVal.hrl rename to stdlib/Data/EVal.hrl diff --git a/lib/Data/EVal.hm b/stdlib/Data/EVal.phi similarity index 100% rename from lib/Data/EVal.hm rename to stdlib/Data/EVal.phi diff --git a/lib/Data/Either.hm b/stdlib/Data/Either.phi similarity index 100% rename from lib/Data/Either.hm rename to stdlib/Data/Either.phi diff --git a/lib/Data/Enum.erl b/stdlib/Data/Enum.erl similarity index 100% rename from lib/Data/Enum.erl rename to stdlib/Data/Enum.erl diff --git a/lib/Data/Enum.hm b/stdlib/Data/Enum.phi similarity index 100% rename from lib/Data/Enum.hm rename to stdlib/Data/Enum.phi diff --git a/lib/Data/Eq.erl b/stdlib/Data/Eq.erl similarity index 100% rename from lib/Data/Eq.erl rename to stdlib/Data/Eq.erl diff --git a/lib/Data/Eq.hm b/stdlib/Data/Eq.phi similarity index 100% rename from lib/Data/Eq.hm rename to stdlib/Data/Eq.phi diff --git a/lib/Data/Float.hm b/stdlib/Data/Float.phi similarity index 100% rename from lib/Data/Float.hm rename to stdlib/Data/Float.phi diff --git a/lib/Data/Foldable.erl b/stdlib/Data/Foldable.erl similarity index 100% rename from lib/Data/Foldable.erl rename to stdlib/Data/Foldable.erl diff --git a/lib/Data/Foldable.hm b/stdlib/Data/Foldable.phi similarity index 100% rename from lib/Data/Foldable.hm rename to stdlib/Data/Foldable.phi diff --git a/lib/Data/Function.erl b/stdlib/Data/Function.erl similarity index 100% rename from lib/Data/Function.erl rename to stdlib/Data/Function.erl diff --git a/lib/Data/Function.hm b/stdlib/Data/Function.phi similarity index 100% rename from lib/Data/Function.hm rename to stdlib/Data/Function.phi diff --git a/lib/Data/Functor.erl b/stdlib/Data/Functor.erl similarity index 100% rename from lib/Data/Functor.erl rename to stdlib/Data/Functor.erl diff --git a/lib/Data/Functor.hm b/stdlib/Data/Functor.phi similarity index 100% rename from lib/Data/Functor.hm rename to stdlib/Data/Functor.phi diff --git a/lib/Data/Functor/Identity.hm b/stdlib/Data/Functor/Identity.phi similarity index 100% rename from lib/Data/Functor/Identity.hm rename to stdlib/Data/Functor/Identity.phi diff --git a/lib/Data/Functor/Utils.hm b/stdlib/Data/Functor/Utils.phi similarity index 100% rename from lib/Data/Functor/Utils.hm rename to stdlib/Data/Functor/Utils.phi diff --git a/lib/Data/Int.erl b/stdlib/Data/Int.erl similarity index 100% rename from lib/Data/Int.erl rename to stdlib/Data/Int.erl diff --git a/lib/Data/Int.hm b/stdlib/Data/Int.phi similarity index 100% rename from lib/Data/Int.hm rename to stdlib/Data/Int.phi diff --git a/lib/Data/List.erl b/stdlib/Data/List.erl similarity index 100% rename from lib/Data/List.erl rename to stdlib/Data/List.erl diff --git a/lib/Data/List.hm b/stdlib/Data/List.phi similarity index 100% rename from lib/Data/List.hm rename to stdlib/Data/List.phi diff --git a/lib/Data/List/Utils.hm b/stdlib/Data/List/Utils.phi similarity index 100% rename from lib/Data/List/Utils.hm rename to stdlib/Data/List/Utils.phi diff --git a/lib/Data/Map.erl b/stdlib/Data/Map.erl similarity index 100% rename from lib/Data/Map.erl rename to stdlib/Data/Map.erl diff --git a/lib/Data/Map.hm b/stdlib/Data/Map.phi similarity index 68% rename from lib/Data/Map.hm rename to stdlib/Data/Map.phi index 845a036..353d170 100644 --- a/lib/Data/Map.hm +++ b/stdlib/Data/Map.phi @@ -15,57 +15,10 @@ module Data.Map where import Data.Maybe (Maybe) -import Control.Monad ((<$>), liftA1) import Foreign (ffi0, ffi1, ffi2, ffi3, ffi4) -import Test.QuickCheck (arbitrary, class Arbitrary) -import Data.Eq (class Eq) -import Data.Ord (class Ord, compare) -import Data.Show (class Show, show) -import Data.Read (class Read, read) -import Data.Semigroup (class Semigroup, (<>)) -import Data.Monoid (class Monoid, mempty) -import Data.Functor (class Functor, map) -import Data.Foldable (class Foldable, foldl, foldr) -import Data.Traversable (class Traversable, sequence) foreign import data Map :: Type -> Type -> Type -instance (Show a, Show b) => Show (Map a b) where - show x = show (toList x) - -instance (Read a, Read b) => Read (Map a b) where - read x = fromList (read x) - -instance (Ord a, Ord b) => Ord (Map a b) where - compare x y = compare (toList x) (toList y) - -instance (Arbitrary k, Arbitrary v) => Arbitrary (Map k v) where - arbitrary = fromList <$> arbitrary - -instance Eq (Map a b) where - eq = eqMapImpl - -instance Functor (Map k) where - map f x = fromList (map (\(k, v) -> (k, f v)) (toList x)) - -instance Foldable (Map k) where - foldl f init x = foldl (\acc (k, v) -> f acc v) init (toList x) - foldr f init x = foldr (\(k, v) acc -> f v acc) init (toList x) - foldMap f = foldr (\x acc -> f x <> acc) mempty - -instance Traversable (Map k) where - traverse f ta = sequence (f <$> ta) - sequence x = liftA1 fromList (sequence (map lifting (toList x))) - where lifting (k, v) = liftA1 (\a -> (k, a)) v - -foreign import eqMapImpl :: forall a b. Map a b -> Map a b -> Boolean - -instance Semigroup (Map a b) where - append = merge - -instance Monoid (Map a b) where - mempty = empty - -- | Returns a new empty map. empty :: forall k v. Map k v empty = ffi0 :maps :new @@ -80,14 +33,13 @@ foreign import isEmpty :: forall k v. Map k v -> Boolean isKey :: forall k v. k -> Map k v -> Boolean isKey = ffi2 :maps :is_key --- | Same to `put` function. -insert :: forall k v. k -> v -> Map k v -> Map k v -insert = put - -- | Insert the key-value pair into a map. put :: forall k v. k -> v -> Map k v -> Map k v put = ffi3 :maps :put +insert :: forall k v. k -> v -> Map k v -> Map k v +insert = put + -- | Return the `Value` associated with `Key`. Throw exception if the `Key` does not exist. get :: forall k v. k -> Map k v -> v get = ffi2 :maps :get @@ -95,10 +47,6 @@ get = ffi2 :maps :get -- | Return the `Value` associated with `Key`. foreign import lookup :: forall k v. k -> Map k v -> Maybe v --- | TODO: docs later... -foreign import mapWithKey :: forall k v. ((k, v) -> v) -> Map k v -> Map k v --- map = ffi2 :maps :map - -- | Test if a key is a member of a Map. member :: forall k v. k -> Map k v -> Boolean member = ffi2 :maps :is_key @@ -109,6 +57,9 @@ foreign import notMember :: forall k v. k -> Map k v -> Boolean fold :: forall k v acc. ((k, v, acc) -> acc) -> acc -> Map k v -> acc fold = ffi3 :maps :fold +mapWithKey :: forall k a b. (k -> a -> b) -> Map k a -> Map k b +mapWithKey = ffi2 :maps :map + -- | Update an existed key-value pair. update :: forall k v. k -> v -> Map k v -> Map k v update = ffi3 :maps :update diff --git a/lib/Data/Maybe.hm b/stdlib/Data/Maybe.phi similarity index 100% rename from lib/Data/Maybe.hm rename to stdlib/Data/Maybe.phi diff --git a/lib/Data/Monoid.hm b/stdlib/Data/Monoid.phi similarity index 100% rename from lib/Data/Monoid.hm rename to stdlib/Data/Monoid.phi diff --git a/lib/Data/Ord.erl b/stdlib/Data/Ord.erl similarity index 100% rename from lib/Data/Ord.erl rename to stdlib/Data/Ord.erl diff --git a/lib/Data/Ord.hm b/stdlib/Data/Ord.phi similarity index 100% rename from lib/Data/Ord.hm rename to stdlib/Data/Ord.phi diff --git a/lib/Data/OrdDict.erl b/stdlib/Data/OrdDict.erl similarity index 100% rename from lib/Data/OrdDict.erl rename to stdlib/Data/OrdDict.erl diff --git a/lib/Data/OrdDict.hm b/stdlib/Data/OrdDict.phi similarity index 100% rename from lib/Data/OrdDict.hm rename to stdlib/Data/OrdDict.phi diff --git a/lib/Data/OrdSets.erl b/stdlib/Data/OrdSets.erl similarity index 100% rename from lib/Data/OrdSets.erl rename to stdlib/Data/OrdSets.erl diff --git a/lib/Data/OrdSets.hm b/stdlib/Data/OrdSets.phi similarity index 100% rename from lib/Data/OrdSets.hm rename to stdlib/Data/OrdSets.phi diff --git a/lib/Data/Ordering.hm b/stdlib/Data/Ordering.phi similarity index 100% rename from lib/Data/Ordering.hm rename to stdlib/Data/Ordering.phi diff --git a/lib/Data/Pid.erl b/stdlib/Data/Pid.erl similarity index 100% rename from lib/Data/Pid.erl rename to stdlib/Data/Pid.erl diff --git a/lib/Data/Pid.hm b/stdlib/Data/Pid.phi similarity index 100% rename from lib/Data/Pid.hm rename to stdlib/Data/Pid.phi diff --git a/lib/Data/Queue.erl b/stdlib/Data/Queue.erl similarity index 100% rename from lib/Data/Queue.erl rename to stdlib/Data/Queue.erl diff --git a/lib/Data/Queue.hm b/stdlib/Data/Queue.phi similarity index 100% rename from lib/Data/Queue.hm rename to stdlib/Data/Queue.phi diff --git a/lib/Data/Read.erl b/stdlib/Data/Read.erl similarity index 100% rename from lib/Data/Read.erl rename to stdlib/Data/Read.erl diff --git a/lib/Data/Read.hm b/stdlib/Data/Read.phi similarity index 100% rename from lib/Data/Read.hm rename to stdlib/Data/Read.phi diff --git a/lib/Data/Record.hm b/stdlib/Data/Record.phi similarity index 100% rename from lib/Data/Record.hm rename to stdlib/Data/Record.phi diff --git a/lib/Data/Ref.erl b/stdlib/Data/Ref.erl similarity index 100% rename from lib/Data/Ref.erl rename to stdlib/Data/Ref.erl diff --git a/lib/Data/Ref.hm b/stdlib/Data/Ref.phi similarity index 100% rename from lib/Data/Ref.hm rename to stdlib/Data/Ref.phi diff --git a/lib/Data/Regex.erl b/stdlib/Data/Regex.erl similarity index 100% rename from lib/Data/Regex.erl rename to stdlib/Data/Regex.erl diff --git a/lib/Data/Regex.hm b/stdlib/Data/Regex.phi similarity index 100% rename from lib/Data/Regex.hm rename to stdlib/Data/Regex.phi diff --git a/lib/Data/Result.hm b/stdlib/Data/Result.phi similarity index 100% rename from lib/Data/Result.hm rename to stdlib/Data/Result.phi diff --git a/lib/Data/Ring.erl b/stdlib/Data/Ring.erl similarity index 100% rename from lib/Data/Ring.erl rename to stdlib/Data/Ring.erl diff --git a/lib/Data/Ring.hm b/stdlib/Data/Ring.phi similarity index 100% rename from lib/Data/Ring.hm rename to stdlib/Data/Ring.phi diff --git a/lib/Data/Semigroup.erl b/stdlib/Data/Semigroup.erl similarity index 100% rename from lib/Data/Semigroup.erl rename to stdlib/Data/Semigroup.erl diff --git a/lib/Data/Semigroup.hm b/stdlib/Data/Semigroup.phi similarity index 100% rename from lib/Data/Semigroup.hm rename to stdlib/Data/Semigroup.phi diff --git a/lib/Data/Semiring.erl b/stdlib/Data/Semiring.erl similarity index 100% rename from lib/Data/Semiring.erl rename to stdlib/Data/Semiring.erl diff --git a/lib/Data/Semiring.hm b/stdlib/Data/Semiring.phi similarity index 100% rename from lib/Data/Semiring.hm rename to stdlib/Data/Semiring.phi diff --git a/lib/Data/Set.erl b/stdlib/Data/Set.erl similarity index 100% rename from lib/Data/Set.erl rename to stdlib/Data/Set.erl diff --git a/lib/Data/Set.hm b/stdlib/Data/Set.phi similarity index 100% rename from lib/Data/Set.hm rename to stdlib/Data/Set.phi diff --git a/lib/Data/Show.erl b/stdlib/Data/Show.erl similarity index 100% rename from lib/Data/Show.erl rename to stdlib/Data/Show.erl diff --git a/lib/Data/Show.hm b/stdlib/Data/Show.phi similarity index 100% rename from lib/Data/Show.hm rename to stdlib/Data/Show.phi diff --git a/lib/Data/String.erl b/stdlib/Data/String.erl similarity index 100% rename from lib/Data/String.erl rename to stdlib/Data/String.erl diff --git a/lib/Data/String.hm b/stdlib/Data/String.phi similarity index 100% rename from lib/Data/String.hm rename to stdlib/Data/String.phi diff --git a/lib/Data/Term.hm b/stdlib/Data/Term.phi similarity index 95% rename from lib/Data/Term.hm rename to stdlib/Data/Term.phi index d7eade2..7af6e08 100644 --- a/lib/Data/Term.hm +++ b/stdlib/Data/Term.phi @@ -17,7 +17,7 @@ module Data.Term where import Unsafe.Coerce (unsafeCoerce) -- | A piece of data of any datatype is called a Term in Erlang. --- we use Term as top type of Hamler +-- we use Term as top type of Phi foreign import data Term :: Type toTerm :: forall a. a -> Term diff --git a/lib/Data/Term/Persistent.hm b/stdlib/Data/Term/Persistent.phi similarity index 100% rename from lib/Data/Term/Persistent.hm rename to stdlib/Data/Term/Persistent.phi diff --git a/lib/Data/Time.erl b/stdlib/Data/Time.erl similarity index 100% rename from lib/Data/Time.erl rename to stdlib/Data/Time.erl diff --git a/lib/Data/Time.hrl b/stdlib/Data/Time.hrl similarity index 100% rename from lib/Data/Time.hrl rename to stdlib/Data/Time.hrl diff --git a/lib/Data/Time.hm b/stdlib/Data/Time.phi similarity index 100% rename from lib/Data/Time.hm rename to stdlib/Data/Time.phi diff --git a/lib/Data/Timeout.hm b/stdlib/Data/Timeout.phi similarity index 100% rename from lib/Data/Timeout.hm rename to stdlib/Data/Timeout.phi diff --git a/lib/Data/Traversable.hm b/stdlib/Data/Traversable.phi similarity index 100% rename from lib/Data/Traversable.hm rename to stdlib/Data/Traversable.phi diff --git a/lib/Data/Tuple.erl b/stdlib/Data/Tuple.erl similarity index 100% rename from lib/Data/Tuple.erl rename to stdlib/Data/Tuple.erl diff --git a/lib/Data/Tuple.hm b/stdlib/Data/Tuple.phi similarity index 100% rename from lib/Data/Tuple.hm rename to stdlib/Data/Tuple.phi diff --git a/lib/Data/Unit.erl b/stdlib/Data/Unit.erl similarity index 100% rename from lib/Data/Unit.erl rename to stdlib/Data/Unit.erl diff --git a/lib/Data/Unit.hm b/stdlib/Data/Unit.phi similarity index 100% rename from lib/Data/Unit.hm rename to stdlib/Data/Unit.phi diff --git a/lib/Data/Void.hm b/stdlib/Data/Void.phi similarity index 100% rename from lib/Data/Void.hm rename to stdlib/Data/Void.phi diff --git a/lib/Database/DETS.erl b/stdlib/Database/DETS.erl similarity index 100% rename from lib/Database/DETS.erl rename to stdlib/Database/DETS.erl diff --git a/lib/Database/DETS.hm b/stdlib/Database/DETS.phi similarity index 100% rename from lib/Database/DETS.hm rename to stdlib/Database/DETS.phi diff --git a/lib/Database/ETS.erl b/stdlib/Database/ETS.erl similarity index 100% rename from lib/Database/ETS.erl rename to stdlib/Database/ETS.erl diff --git a/lib/Database/ETS.hm b/stdlib/Database/ETS.phi similarity index 100% rename from lib/Database/ETS.hm rename to stdlib/Database/ETS.phi diff --git a/lib/Database/Mnesia.erl b/stdlib/Database/Mnesia.erl similarity index 100% rename from lib/Database/Mnesia.erl rename to stdlib/Database/Mnesia.erl diff --git a/lib/Database/Mnesia.hm b/stdlib/Database/Mnesia.phi similarity index 100% rename from lib/Database/Mnesia.hm rename to stdlib/Database/Mnesia.phi diff --git a/lib/Foreign.erl b/stdlib/Foreign.erl similarity index 100% rename from lib/Foreign.erl rename to stdlib/Foreign.erl diff --git a/lib/Foreign.hrl b/stdlib/Foreign.hrl similarity index 100% rename from lib/Foreign.hrl rename to stdlib/Foreign.hrl diff --git a/lib/Foreign.hm b/stdlib/Foreign.phi similarity index 100% rename from lib/Foreign.hm rename to stdlib/Foreign.phi diff --git a/lib/Foreign/Curry.erl b/stdlib/Foreign/Curry.erl similarity index 100% rename from lib/Foreign/Curry.erl rename to stdlib/Foreign/Curry.erl diff --git a/lib/Foreign/Curry.hrl b/stdlib/Foreign/Curry.hrl similarity index 100% rename from lib/Foreign/Curry.hrl rename to stdlib/Foreign/Curry.hrl diff --git a/lib/Foreign/Maybe.erl b/stdlib/Foreign/Maybe.erl similarity index 100% rename from lib/Foreign/Maybe.erl rename to stdlib/Foreign/Maybe.erl diff --git a/lib/Foreign/Maybe.hrl b/stdlib/Foreign/Maybe.hrl similarity index 100% rename from lib/Foreign/Maybe.hrl rename to stdlib/Foreign/Maybe.hrl diff --git a/lib/Network/DTLS.erl b/stdlib/Network/DTLS.erl similarity index 100% rename from lib/Network/DTLS.erl rename to stdlib/Network/DTLS.erl diff --git a/lib/Network/DTLS.hm b/stdlib/Network/DTLS.phi similarity index 100% rename from lib/Network/DTLS.hm rename to stdlib/Network/DTLS.phi diff --git a/lib/Network/Inet.erl b/stdlib/Network/Inet.erl similarity index 100% rename from lib/Network/Inet.erl rename to stdlib/Network/Inet.erl diff --git a/lib/Network/Inet.hm b/stdlib/Network/Inet.phi similarity index 100% rename from lib/Network/Inet.hm rename to stdlib/Network/Inet.phi diff --git a/lib/Network/TCP.erl b/stdlib/Network/TCP.erl similarity index 100% rename from lib/Network/TCP.erl rename to stdlib/Network/TCP.erl diff --git a/lib/Network/TCP.hm b/stdlib/Network/TCP.phi similarity index 100% rename from lib/Network/TCP.hm rename to stdlib/Network/TCP.phi diff --git a/lib/Network/TLS.erl b/stdlib/Network/TLS.erl similarity index 100% rename from lib/Network/TLS.erl rename to stdlib/Network/TLS.erl diff --git a/lib/Network/TLS.hm b/stdlib/Network/TLS.phi similarity index 100% rename from lib/Network/TLS.hm rename to stdlib/Network/TLS.phi diff --git a/lib/Network/UDP.erl b/stdlib/Network/UDP.erl similarity index 100% rename from lib/Network/UDP.erl rename to stdlib/Network/UDP.erl diff --git a/lib/Network/UDP.hm b/stdlib/Network/UDP.phi similarity index 100% rename from lib/Network/UDP.hm rename to stdlib/Network/UDP.phi diff --git a/lib/Prelude.hm b/stdlib/Prelude.phi similarity index 100% rename from lib/Prelude.hm rename to stdlib/Prelude.phi diff --git a/lib/System/Code.erl b/stdlib/System/Code.erl similarity index 100% rename from lib/System/Code.erl rename to stdlib/System/Code.erl diff --git a/lib/System/Code.hm b/stdlib/System/Code.phi similarity index 100% rename from lib/System/Code.hm rename to stdlib/System/Code.phi diff --git a/lib/System/Dir.erl b/stdlib/System/Dir.erl similarity index 100% rename from lib/System/Dir.erl rename to stdlib/System/Dir.erl diff --git a/lib/System/Dir.hm b/stdlib/System/Dir.phi similarity index 100% rename from lib/System/Dir.hm rename to stdlib/System/Dir.phi diff --git a/lib/System/Env.erl b/stdlib/System/Env.erl similarity index 100% rename from lib/System/Env.erl rename to stdlib/System/Env.erl diff --git a/lib/System/Env.hm b/stdlib/System/Env.phi similarity index 100% rename from lib/System/Env.hm rename to stdlib/System/Env.phi diff --git a/lib/System/Error.erl b/stdlib/System/Error.erl similarity index 100% rename from lib/System/Error.erl rename to stdlib/System/Error.erl diff --git a/lib/System/Error.hm b/stdlib/System/Error.phi similarity index 100% rename from lib/System/Error.hm rename to stdlib/System/Error.phi diff --git a/lib/System/File.erl b/stdlib/System/File.erl similarity index 100% rename from lib/System/File.erl rename to stdlib/System/File.erl diff --git a/lib/System/File.hm b/stdlib/System/File.phi similarity index 100% rename from lib/System/File.hm rename to stdlib/System/File.phi diff --git a/lib/System/FilePath.erl b/stdlib/System/FilePath.erl similarity index 100% rename from lib/System/FilePath.erl rename to stdlib/System/FilePath.erl diff --git a/lib/System/FilePath.hm b/stdlib/System/FilePath.phi similarity index 100% rename from lib/System/FilePath.hm rename to stdlib/System/FilePath.phi diff --git a/lib/System/IO.erl b/stdlib/System/IO.erl similarity index 100% rename from lib/System/IO.erl rename to stdlib/System/IO.erl diff --git a/lib/System/IO.hm b/stdlib/System/IO.phi similarity index 100% rename from lib/System/IO.hm rename to stdlib/System/IO.phi diff --git a/lib/System/IO/Printf.erl b/stdlib/System/IO/Printf.erl similarity index 100% rename from lib/System/IO/Printf.erl rename to stdlib/System/IO/Printf.erl diff --git a/lib/System/IO/Printf.hm b/stdlib/System/IO/Printf.phi similarity index 96% rename from lib/System/IO/Printf.hm rename to stdlib/System/IO/Printf.phi index 76da6f3..4f03b8d 100644 --- a/lib/System/IO/Printf.hm +++ b/stdlib/System/IO/Printf.phi @@ -22,7 +22,7 @@ module System.IO.Printf , render ) where {- -`printf` in Hamler is defined like in Haskell. It has type `Printf r => String -> r`. The String argument represent how the format of the output, just like printfs in ohter languages. +`printf` in Phi is defined like in Haskell. It has type `Printf r => String -> r`. The String argument represent how the format of the output, just like printfs in ohter languages. exmaple 1: diff --git a/lib/System/IO/Types.hm b/stdlib/System/IO/Types.phi similarity index 100% rename from lib/System/IO/Types.hm rename to stdlib/System/IO/Types.phi diff --git a/lib/System/Init.erl b/stdlib/System/Init.erl similarity index 100% rename from lib/System/Init.erl rename to stdlib/System/Init.erl diff --git a/lib/System/Init.hm b/stdlib/System/Init.phi similarity index 100% rename from lib/System/Init.hm rename to stdlib/System/Init.phi diff --git a/lib/System/Logger.hm b/stdlib/System/Logger.phi similarity index 100% rename from lib/System/Logger.hm rename to stdlib/System/Logger.phi diff --git a/lib/System/OS.erl b/stdlib/System/OS.erl similarity index 100% rename from lib/System/OS.erl rename to stdlib/System/OS.erl diff --git a/lib/System/OS.hm b/stdlib/System/OS.phi similarity index 100% rename from lib/System/OS.hm rename to stdlib/System/OS.phi diff --git a/lib/System/Random.erl b/stdlib/System/Random.erl similarity index 100% rename from lib/System/Random.erl rename to stdlib/System/Random.erl diff --git a/lib/System/Random.hm b/stdlib/System/Random.phi similarity index 100% rename from lib/System/Random.hm rename to stdlib/System/Random.phi diff --git a/lib/System/Timer.erl b/stdlib/System/Timer.erl similarity index 100% rename from lib/System/Timer.erl rename to stdlib/System/Timer.erl diff --git a/lib/System/Timer.hm b/stdlib/System/Timer.phi similarity index 100% rename from lib/System/Timer.hm rename to stdlib/System/Timer.phi diff --git a/lib/System/Trace.hm b/stdlib/System/Trace.phi similarity index 100% rename from lib/System/Trace.hm rename to stdlib/System/Trace.phi diff --git a/lib/System/VM.erl b/stdlib/System/VM.erl similarity index 100% rename from lib/System/VM.erl rename to stdlib/System/VM.erl diff --git a/lib/System/VM.hm b/stdlib/System/VM.phi similarity index 100% rename from lib/System/VM.hm rename to stdlib/System/VM.phi diff --git a/lib/Test/QuickCheck.erl b/stdlib/Test/QuickCheck.erl similarity index 100% rename from lib/Test/QuickCheck.erl rename to stdlib/Test/QuickCheck.erl diff --git a/lib/Test/QuickCheck.hm b/stdlib/Test/QuickCheck.phi similarity index 98% rename from lib/Test/QuickCheck.hm rename to stdlib/Test/QuickCheck.phi index 81b9826..a3b6c97 100644 --- a/lib/Test/QuickCheck.hm +++ b/stdlib/Test/QuickCheck.phi @@ -37,6 +37,7 @@ import System.IO (printf, println) import System.Random(randomRIO) import Data.Binary (listToBin) import System.Error (catchException) +import Data.Array as Array foreign import data Rand :: Type @@ -164,6 +165,9 @@ instance (Arbitrary a, Arbitrary b) => Arbitrary (a, b) where instance Arbitrary a => Arbitrary [a] where arbitrary = sized (\n -> choose (0,n) >>= vector) +instance Arbitrary v => Arbitrary (Array.Array v) where + arbitrary = Array.fromList <$> arbitrary + instance (Coarbitrary a, Arbitrary b) => Arbitrary (a -> b) where arbitrary = promote (\x -> x `coarbitrary` arbitrary) diff --git a/lib/Text/Json.hm b/stdlib/Text/Json.phi similarity index 100% rename from lib/Text/Json.hm rename to stdlib/Text/Json.phi diff --git a/lib/Text/Parsec.hm b/stdlib/Text/Parsec.phi similarity index 100% rename from lib/Text/Parsec.hm rename to stdlib/Text/Parsec.phi diff --git a/lib/Unsafe/Coerce.erl b/stdlib/Unsafe/Coerce.erl similarity index 100% rename from lib/Unsafe/Coerce.erl rename to stdlib/Unsafe/Coerce.erl diff --git a/lib/Unsafe/Coerce.hm b/stdlib/Unsafe/Coerce.phi similarity index 100% rename from lib/Unsafe/Coerce.hm rename to stdlib/Unsafe/Coerce.phi diff --git a/test.hm b/test.phi similarity index 100% rename from test.hm rename to test.phi diff --git a/test/phi_codegen_test.exs b/test/phi_codegen_test.exs index 05579fc..d3c8a1b 100644 --- a/test/phi_codegen_test.exs +++ b/test/phi_codegen_test.exs @@ -20,17 +20,17 @@ defmodule PhiCodegenTest do # Compile the forms to a BEAM binary to prove they are valid Erlang AST! case :compile.forms(forms, [:return_errors]) do {:ok, mod_name, binary} when is_binary(binary) -> - assert mod_name == :core + assert mod_name == :Core # We can dynamically load the compiled module into the VM! :code.load_binary(mod_name, ~c"#{mod_name}", binary) # Test the compiled Erlang functions! # fortyTwo = 42 compiles to the integer 42 - assert :core.fortyTwo() == 42 + assert :Core.fortyTwo() == 42 # id is a function taking 1 argument (desugared to N-arity) - assert :core.id(99) == 99 + assert :Core.id(99) == 99 # applyId uses let-binding with local function call; currently compiles # `f` as an atom, not a callable. Known limitation. diff --git a/test/phi_stdlib_test.exs b/test/phi_stdlib_test.exs index 160c60a..ad4a423 100644 --- a/test/phi_stdlib_test.exs +++ b/test/phi_stdlib_test.exs @@ -40,7 +40,7 @@ defmodule PhiStdlibTest do # Compile to BEAM binary and load it into VM! assert {:ok, mod, bin} = :compile.forms(forms, [:return_errors]) - assert mod == :data_tuple + assert mod == :"Data.Tuple" assert :code.load_binary(mod, ~c"#{mod}", bin) == {:module, mod} # Try calling the compiled fst and snd! diff --git a/tests/Test.hm b/tests/Test.phi similarity index 100% rename from tests/Test.hm rename to tests/Test.phi diff --git a/tests/Test/Control/Monad.hm b/tests/Test/Control/Monad.phi similarity index 100% rename from tests/Test/Control/Monad.hm rename to tests/Test/Control/Monad.phi diff --git a/tests/Test/Control/Monad/Reader.hm b/tests/Test/Control/Monad/Reader.phi similarity index 100% rename from tests/Test/Control/Monad/Reader.hm rename to tests/Test/Control/Monad/Reader.phi diff --git a/tests/Test/Control/Monad/State.hm b/tests/Test/Control/Monad/State.phi similarity index 100% rename from tests/Test/Control/Monad/State.hm rename to tests/Test/Control/Monad/State.phi diff --git a/tests/Test/Control/Monad/Writer.hm b/tests/Test/Control/Monad/Writer.phi similarity index 100% rename from tests/Test/Control/Monad/Writer.hm rename to tests/Test/Control/Monad/Writer.phi diff --git a/tests/Test/Control/Process.hm b/tests/Test/Control/Process.phi similarity index 100% rename from tests/Test/Control/Process.hm rename to tests/Test/Control/Process.phi diff --git a/tests/Test/Control/ReceiveSyntax.hm b/tests/Test/Control/ReceiveSyntax.phi similarity index 100% rename from tests/Test/Control/ReceiveSyntax.hm rename to tests/Test/Control/ReceiveSyntax.phi diff --git a/tests/Test/Data/Array.hm b/tests/Test/Data/Array.phi similarity index 100% rename from tests/Test/Data/Array.hm rename to tests/Test/Data/Array.phi diff --git a/tests/Test/Data/Atom.hm b/tests/Test/Data/Atom.phi similarity index 100% rename from tests/Test/Data/Atom.hm rename to tests/Test/Data/Atom.phi diff --git a/tests/Test/Data/Atomics.hm b/tests/Test/Data/Atomics.phi similarity index 100% rename from tests/Test/Data/Atomics.hm rename to tests/Test/Data/Atomics.phi diff --git a/tests/Test/Data/Binary.hm b/tests/Test/Data/Binary.phi similarity index 100% rename from tests/Test/Data/Binary.hm rename to tests/Test/Data/Binary.phi diff --git a/tests/Test/Data/Bits.hm b/tests/Test/Data/Bits.phi similarity index 100% rename from tests/Test/Data/Bits.hm rename to tests/Test/Data/Bits.phi diff --git a/tests/Test/Data/Bool.hm b/tests/Test/Data/Bool.phi similarity index 100% rename from tests/Test/Data/Bool.hm rename to tests/Test/Data/Bool.phi diff --git a/tests/Test/Data/Char.hm b/tests/Test/Data/Char.phi similarity index 100% rename from tests/Test/Data/Char.hm rename to tests/Test/Data/Char.phi diff --git a/tests/Test/Data/Counter.hm b/tests/Test/Data/Counter.hm deleted file mode 100644 index 3de2dab..0000000 --- a/tests/Test/Data/Counter.hm +++ /dev/null @@ -1 +0,0 @@ -module Test.Data.Counter where diff --git a/tests/Test/Data/Digraph.hm b/tests/Test/Data/Digraph.phi similarity index 99% rename from tests/Test/Data/Digraph.hm rename to tests/Test/Data/Digraph.phi index 9958170..852c2d1 100644 --- a/tests/Test/Data/Digraph.hm +++ b/tests/Test/Data/Digraph.phi @@ -8,9 +8,6 @@ import Data.Digraph as G emptyGraph :: [G.GraphType] -> IO (G.Graph Integer Integer) emptyGraph = G.new -{- - (1) <-2-1-> (2) --3-> (3) --} getBaseGraph1 :: IO (G.Graph Integer Integer) getBaseGraph1 = do g <- emptyGraph [] diff --git a/tests/Test/Data/Either.hm b/tests/Test/Data/Either.phi similarity index 100% rename from tests/Test/Data/Either.hm rename to tests/Test/Data/Either.phi diff --git a/tests/Test/Data/Enum.hm b/tests/Test/Data/Enum.phi similarity index 100% rename from tests/Test/Data/Enum.hm rename to tests/Test/Data/Enum.phi diff --git a/tests/Test/Data/Function.hm b/tests/Test/Data/Function.phi similarity index 100% rename from tests/Test/Data/Function.hm rename to tests/Test/Data/Function.phi diff --git a/tests/Test/Data/Functor.hm b/tests/Test/Data/Functor.phi similarity index 100% rename from tests/Test/Data/Functor.hm rename to tests/Test/Data/Functor.phi diff --git a/tests/Test/Data/List.hm b/tests/Test/Data/List.phi similarity index 100% rename from tests/Test/Data/List.hm rename to tests/Test/Data/List.phi diff --git a/tests/Test/Data/Map.hm b/tests/Test/Data/Map.phi similarity index 100% rename from tests/Test/Data/Map.hm rename to tests/Test/Data/Map.phi diff --git a/tests/Test/Data/Maybe.hm b/tests/Test/Data/Maybe.phi similarity index 100% rename from tests/Test/Data/Maybe.hm rename to tests/Test/Data/Maybe.phi diff --git a/tests/Test/Data/Monoid.hm b/tests/Test/Data/Monoid.phi similarity index 100% rename from tests/Test/Data/Monoid.hm rename to tests/Test/Data/Monoid.phi diff --git a/tests/Test/Data/Ord.hm b/tests/Test/Data/Ord.phi similarity index 100% rename from tests/Test/Data/Ord.hm rename to tests/Test/Data/Ord.phi diff --git a/tests/Test/Data/OrdDict.hm b/tests/Test/Data/OrdDict.phi similarity index 100% rename from tests/Test/Data/OrdDict.hm rename to tests/Test/Data/OrdDict.phi diff --git a/tests/Test/Data/OrdSets.hm b/tests/Test/Data/OrdSets.phi similarity index 100% rename from tests/Test/Data/OrdSets.hm rename to tests/Test/Data/OrdSets.phi diff --git a/tests/Test/Data/Ordering.hm b/tests/Test/Data/Ordering.phi similarity index 100% rename from tests/Test/Data/Ordering.hm rename to tests/Test/Data/Ordering.phi diff --git a/tests/Test/Data/Queue.hm b/tests/Test/Data/Queue.phi similarity index 100% rename from tests/Test/Data/Queue.hm rename to tests/Test/Data/Queue.phi diff --git a/tests/Test/Data/Read.hm b/tests/Test/Data/Read.phi similarity index 100% rename from tests/Test/Data/Read.hm rename to tests/Test/Data/Read.phi diff --git a/tests/Test/Data/Regex.hm b/tests/Test/Data/Regex.phi similarity index 100% rename from tests/Test/Data/Regex.hm rename to tests/Test/Data/Regex.phi diff --git a/tests/Test/Data/Result.hm b/tests/Test/Data/Result.phi similarity index 100% rename from tests/Test/Data/Result.hm rename to tests/Test/Data/Result.phi diff --git a/tests/Test/Data/Ring.hm b/tests/Test/Data/Ring.phi similarity index 100% rename from tests/Test/Data/Ring.hm rename to tests/Test/Data/Ring.phi diff --git a/tests/Test/Data/Semigroup.hm b/tests/Test/Data/Semigroup.phi similarity index 100% rename from tests/Test/Data/Semigroup.hm rename to tests/Test/Data/Semigroup.phi diff --git a/tests/Test/Data/Semiring.hm b/tests/Test/Data/Semiring.phi similarity index 100% rename from tests/Test/Data/Semiring.hm rename to tests/Test/Data/Semiring.phi diff --git a/tests/Test/Data/Set.hm b/tests/Test/Data/Set.phi similarity index 100% rename from tests/Test/Data/Set.hm rename to tests/Test/Data/Set.phi diff --git a/tests/Test/Data/Show.hm b/tests/Test/Data/Show.phi similarity index 100% rename from tests/Test/Data/Show.hm rename to tests/Test/Data/Show.phi diff --git a/tests/Test/Data/String.hm b/tests/Test/Data/String.phi similarity index 100% rename from tests/Test/Data/String.hm rename to tests/Test/Data/String.phi diff --git a/tests/Test/Data/Term/Persistent.hm b/tests/Test/Data/Term/Persistent.phi similarity index 100% rename from tests/Test/Data/Term/Persistent.hm rename to tests/Test/Data/Term/Persistent.phi diff --git a/tests/Test/Data/Time.hm b/tests/Test/Data/Time.phi similarity index 100% rename from tests/Test/Data/Time.hm rename to tests/Test/Data/Time.phi diff --git a/tests/Test/Data/Timeout.hm b/tests/Test/Data/Timeout.phi similarity index 100% rename from tests/Test/Data/Timeout.hm rename to tests/Test/Data/Timeout.phi diff --git a/tests/Test/Data/Traverable.hm b/tests/Test/Data/Traverable.phi similarity index 100% rename from tests/Test/Data/Traverable.hm rename to tests/Test/Data/Traverable.phi diff --git a/tests/Test/Data/Tuple.hm b/tests/Test/Data/Tuple.phi similarity index 100% rename from tests/Test/Data/Tuple.hm rename to tests/Test/Data/Tuple.phi diff --git a/tests/Test/Data/Void.hm b/tests/Test/Data/Void.phi similarity index 100% rename from tests/Test/Data/Void.hm rename to tests/Test/Data/Void.phi diff --git a/tests/Test/Database/ETS.hm b/tests/Test/Database/ETS.phi similarity index 99% rename from tests/Test/Database/ETS.hm rename to tests/Test/Database/ETS.phi index 700b841..eb4ee36 100644 --- a/tests/Test/Database/ETS.hm +++ b/tests/Test/Database/ETS.phi @@ -104,7 +104,7 @@ p :: Atom p = :"$1" p' :: (Atom, Atom) -p' = (:_, :_) +p' = (:"_", :"_") ematch :: [Integer] -> IO Boolean ematch [] = pure true diff --git a/tests/Test/Database/Mnesia.hm b/tests/Test/Database/Mnesia.phi similarity index 100% rename from tests/Test/Database/Mnesia.hm rename to tests/Test/Database/Mnesia.phi diff --git a/tests/Test/Network/TCP.hm b/tests/Test/Network/TCP.phi similarity index 100% rename from tests/Test/Network/TCP.hm rename to tests/Test/Network/TCP.phi diff --git a/tests/Test/Network/UDP.hm b/tests/Test/Network/UDP.phi similarity index 100% rename from tests/Test/Network/UDP.hm rename to tests/Test/Network/UDP.phi diff --git a/tests/Test/System/Dir.hm b/tests/Test/System/Dir.phi similarity index 100% rename from tests/Test/System/Dir.hm rename to tests/Test/System/Dir.phi diff --git a/tests/Test/System/Env.hm b/tests/Test/System/Env.phi similarity index 76% rename from tests/Test/System/Env.hm rename to tests/Test/System/Env.phi index 4dbcd81..6a21f31 100644 --- a/tests/Test/System/Env.hm +++ b/tests/Test/System/Env.phi @@ -7,19 +7,19 @@ import Data.List (member) setEnv_getEnv :: IO Boolean setEnv_getEnv = do - setEnv "hamlertest" "hamlertest" - v <- getEnv "hamlertest" - pure $ v == "hamlertest" + setEnv "phitest" "phitest" + v <- getEnv "phitest" + pure $ v == "phitest" getAllEnv' :: IO Boolean getAllEnv' = do all <- getAllEnv - pure $ ("hamlertest", "hamlertest") `member` all + pure $ ("phitest", "phitest") `member` all unsetEnv' :: IO Boolean unsetEnv' = do - unsetEnv "hamlertest" - v <- lookupEnv "hamlertest" + unsetEnv "phitest" + v <- lookupEnv "phitest" pure $ v == Nothing test :: TestGroup (Integer -> IO TestResult) diff --git a/tests/Test/System/Error.hm b/tests/Test/System/Error.phi similarity index 100% rename from tests/Test/System/Error.hm rename to tests/Test/System/Error.phi diff --git a/tests/Test/System/File.hm b/tests/Test/System/File.phi similarity index 100% rename from tests/Test/System/File.hm rename to tests/Test/System/File.phi diff --git a/tests/Test/System/FilePath.hm b/tests/Test/System/FilePath.phi similarity index 100% rename from tests/Test/System/FilePath.hm rename to tests/Test/System/FilePath.phi diff --git a/tests/Test/System/IO.hm b/tests/Test/System/IO.phi similarity index 87% rename from tests/Test/System/IO.hm rename to tests/Test/System/IO.phi index 661ee28..dde3788 100644 --- a/tests/Test/System/IO.hm +++ b/tests/Test/System/IO.phi @@ -18,10 +18,10 @@ writeAndReadTest = do appendTest :: IO (Bool) appendTest = do writeFile filepath <<"hello, world">> - appendFile filepath <<" Hamler, Haskell">> + appendFile filepath <<" Phi, Haskell">> rf <- readFile filepath deleteFile filepath - pure $ rf == <<"hello, world Hamler, Haskell">> + pure $ rf == <<"hello, world Phi, Haskell">> test :: TestGroup (Integer -> IO TestResult) test = Exe [ diff --git a/tests/Test/System/Timer.hm b/tests/Test/System/Timer.phi similarity index 100% rename from tests/Test/System/Timer.hm rename to tests/Test/System/Timer.phi diff --git a/tests/Test/Text/Json.hm b/tests/Test/Text/Json.phi similarity index 100% rename from tests/Test/Text/Json.hm rename to tests/Test/Text/Json.phi diff --git a/tests/Test/Text/Parsec.hm b/tests/Test/Text/Parsec.phi similarity index 100% rename from tests/Test/Text/Parsec.hm rename to tests/Test/Text/Parsec.phi