Current section

Files

Jump to
per lib mix tasks per.base.ex
Raw

lib/mix/tasks/per.base.ex

defmodule Mix.Tasks.Per.Base do
use Mix.Task
@shortdoc "Compile Per standard library"
def run(args) do
{opts, _, _} = OptionParser.parse(args, switches: [check_only: :boolean, syntax: :string])
check_only = Keyword.get(opts, :check_only, false)
syntax_str = Keyword.get(opts, :syntax, "lean")
syntax = String.to_atom(syntax_str)
if check_only do
IO.puts("Typechecking Per base library [#{syntax_str}]...")
else
IO.puts("Compiling Per base library [#{syntax_str}]...")
end
# Order matters for the base library
base_dir = if syntax == :agda, do: "priv/agda/", else: "priv/per/"
base_files = [
Path.join(base_dir, "foundations/mltt.per"),
Path.join(base_dir, "foundations/inductive.per"),
Path.join(base_dir, "foundations/univalent.per")
]
# Also check for .agda extension
base_files = Enum.flat_map(base_files, fn f ->
if File.exists?(f) do
[f]
else
agda_f = String.replace(f, ".per", ".agda")
if File.exists?(agda_f), do: [agda_f], else: [f]
end
end)
out_dir = "ebin"
File.mkdir_p!(out_dir)
results = Enum.map(base_files, fn file ->
if File.exists?(file) do
action_str = if check_only, do: "Checking", else: "Compiling"
IO.write(" #{action_str} #{file}... ")
source = File.read!(file)
case Per.Compiler.compile_module(source, [source_path: file, syntax: syntax] ++ opts) do
{:ok, _mod, :check_only} ->
IO.puts("OK (Checked)")
:ok
{:ok, mod, bin} ->
beam_path = Path.join(out_dir, "#{mod}.beam")
File.write!(beam_path, bin)
IO.puts("OK")
:ok
{:error, reason} ->
IO.puts("FAILED: #{inspect(reason, pretty: true)}")
:error
{:error, reason, details} ->
IO.puts("FAILED: #{inspect(reason, pretty: true)} -> #{inspect(details, pretty: true)}")
:error
end
else
IO.puts("SKIPPED: #{file} not found")
:ok
end
end)
failures = Enum.count(results, &(&1 == :error))
finished_str = if check_only, do: "verification", else: "compilation"
if failures > 0 do
IO.puts("\nPer base library #{finished_str} FAILED with #{failures} errors.")
System.halt(1)
else
IO.puts("\nPer base library #{finished_str} finished successfully.")
end
end
end