lecture 05

This commit is contained in:
SowinskiBraeden committed 2026-10-14 16:26:51 -07:00
1 parent cda6101a3d
commit 6c54e7a49b
7 files changed
+175

No files matched your search

+32
View File
@@ -0,0 +1,32 @@
defmodule M do
def if_fun(predicate, do: do_block, else: else_block) do
cond do
predicate -> do_block
true -> else_block
end
end
defmacro inspect(x) do
IO.inspect(x)
end
defmacro if_macro(predicate, do: do_block, else: else_block) do
quote do
cond do
unquote(predicate) -> unquote(do_block)
true -> unquote(else_block)
end
end
end
defmacro while(condition, do: do_block) do
quote do
try do
for _ <- Stream.cycle [:ok] do
if unquote(condition), do: unquote(do_block),
else: throw :break
end
catch :throw, :break -> :ok end
end
end
end
+31
View File
@@ -0,0 +1,31 @@
defmodule M do
defmacro context() do
# macro's context
IO.inspect(__MODULE__)
quote do
# caller's context
IO.inspect(unquote(__MODULE__))
IO.inspect(__MODULE__)
end
end
defmacro twice(x) do
quote do
unquote(x) + unquote(x)
end
end
defmacro twice_v2(x) do
quote bind_quoted: [x: x] do
x + x
end
end
end
defmodule Test do
import M
def test() do
context()
end
end
+16
View File
@@ -0,0 +1,16 @@
defmodule M do
defmacro say(msg) do
name = String.to_atom("say_#{msg}")
quote do
def name() do
IO.puts(unquote(msg))
end
end
end
end
defmodule Test do
import M
say("hello")
end
+9
View File
@@ -0,0 +1,9 @@
# unquote fragments
defmodule M do
for {k, v} <- [homer: 55, bart: 76] do
def unquote(k)(), do: unquote(v)
end
end
M.homer()
M.bart()
+8
View File
@@ -0,0 +1,8 @@
#include <stdio.h>
#define CHECK(pred) printf("%s ... %s\n", pred ? "passed" : "FAILED", #pred)
int main(void) {
CHECK(1 + 1 == 2);
CHECK(1 + 2 == 4);
}
+23
View File
@@ -0,0 +1,23 @@
# see abstract syntax tree (ast)
quote do: 1 + 2
# {:+, [context: Elixir, imports: [{1, Kernel}, {2, Kernel}]], [1, 2]}
#
# +
# / \
# 1 2
#
alias String, as: S
# {:__aliases__, [alias: String], [:S]}
### Abstract literal
quote do: 1 # -> 1
quote do: "hello" # -> "hello"
quote do: [1, 2, 3] # -> [1, 2, 3] # a list of ast literals is an ast literal
quote do: {1, 2} # -> {1, 2} # doubles are ast literals but not triples
### Macro - something that takes an AST and returns an AST
x = 2
quote do: x # -> {:x, [], Elixir} # doesnt evaluate it, just ast of expression
quote do: unquote(x) # -> 2
+56
View File
@@ -0,0 +1,56 @@
defmodule Testing do
defmacro check(predicate) do
test = Macro.to_string(predicate)
quote do
cond do
unquote(predicate) -> IO.puts("passed ... #{unquote(test)}")
true -> IO.puts("FAILED ... #{unquote(test)}")
end
end
end
defmacro test(description, do: block) do
name = "test_#{description}"
fn_name = String.to_atom(name)
quote do
@tests [unquote(fn_name) | @tests]
def unquote(fn_name)() do
IO.puts(unquote(name) <> ":")
unquote(block)
end
end
end
defmacro __before_compile__(_env) do
# defmacro make_run_tests() do
quote do
def run_tests() do
Enum.each(Enum.reverse(@tests), fn f -> apply(__MODULE__, f, []) end)
end
end
end
defmacro __using__(_opts) do
quote do
import unquote(__MODULE__)
@tests []
@before_compile unquote(__MODULE__)
end
end
end
defmodule Tests do
use Testing # this requires Testing and call Testing.__using__
test "equality" do
check(1 + 1 == 2)
check(1 + 2 == 4)
end
test "greater" do
check(1 > 2)
check(1 < 2)
end
# make_run_tests()
end