summaryrefslogtreecommitdiff
path: root/elixir/ast.ex
diff options
context:
space:
mode:
authorArnaud Bailly <arnaud.bailly@iohk.io>2024-10-11 15:09:29 +0200
committerArnaud Bailly <arnaud.bailly@iohk.io>2024-10-11 15:09:29 +0200
commit3363ab2da764825558c859f4419ff99528ed2274 (patch)
treedb5f1c71a3fe5cea64bc84c34fefe960961d3179 /elixir/ast.ex
parent8094716f7c9a3d9f2886132e7419b377abb97b3b (diff)
downloadlambda-nantes-3363ab2da764825558c859f4419ff99528ed2274.tar.gz
Add elixir code
Diffstat (limited to 'elixir/ast.ex')
-rw-r--r--elixir/ast.ex34
1 files changed, 34 insertions, 0 deletions
diff --git a/elixir/ast.ex b/elixir/ast.ex
new file mode 100644
index 0000000..4305b7b
--- /dev/null
+++ b/elixir/ast.ex
@@ -0,0 +1,34 @@
+defmodule Ast do
+ def var(name), do: {:var, name}
+ def abs(param, body), do: {:abs, param, body}
+ def app(func, param), do: {:app, func, param}
+
+ def pprint(expr) do
+ case expr do
+ {:var, name} -> name
+ {:abs, param, body} -> "(λ #{param} . #{pprint(body)})"
+ {:app, func, param} -> "#{pprint(func)} #{pprint(param)}"
+ end
+ end
+
+ def free_vars(expr) do
+ case expr do
+ {:var, name} -> MapSet.new([name])
+ {:abs, param, body} -> MapSet.delete(free_vars(body), param)
+ {:app, func, param} -> MapSet.union(free_vars(func), free_vars(param))
+ end
+ end
+
+ def subst(expr, old_var, new_expr) do
+ case expr do
+ {:var, name} ->
+ if name == old_var, do: new_expr, else: expr
+
+ {:abs, param, body} ->
+ if param == old_var, do: expr, else: {:abs, param, subst(body, old_var, new_expr)}
+
+ {:app, func, param} ->
+ {:app, subst(func, old_var, new_expr), subst(param, old_var, new_expr)}
+ end
+ end
+end