-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcompile_to_wasm.exs
More file actions
82 lines (63 loc) · 2.1 KB
/
Copy pathcompile_to_wasm.exs
File metadata and controls
82 lines (63 loc) · 2.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# Firebird: Compile Elixir to WebAssembly Example
#
# Run: mix run examples/compile_to_wasm.exs
#
# This script demonstrates:
# 1. Writing Elixir code with @wasm annotations
# 2. Compiling it to WebAssembly
# 3. Loading and executing the compiled WASM
# 4. Comparing results with native BEAM execution
IO.puts("🔥 Firebird: Elixir to WebAssembly Compilation Demo\n")
# Step 1: Define Elixir source with @wasm annotations
source = """
defmodule DemoMath do
@wasm true
def add(a, b), do: a + b
@wasm true
def multiply(a, b), do: a * b
@wasm true
def factorial(0), do: 1
def factorial(n), do: n * factorial(n - 1)
@wasm true
def fibonacci(0), do: 0
def fibonacci(1), do: 1
def fibonacci(n), do: fibonacci(n - 1) + fibonacci(n - 2)
@wasm true
def gcd(a, 0), do: a
def gcd(a, b), do: gcd(b, rem(a, b))
@wasm true
def power(_, 0), do: 1
def power(base, exp), do: base * power(base, exp - 1)
end
"""
IO.puts("📝 Source code:")
IO.puts(source)
# Step 2: Compile to WASM
IO.puts("⚙️ Compiling to WebAssembly...")
{:ok, result} = Firebird.Compiler.compile_source(source, optimize: true)
IO.puts(" Module: #{result.module}")
IO.puts(" WAT size: #{byte_size(result.wat)} bytes")
IO.puts(" WASM size: #{byte_size(result.wasm)} bytes")
IO.puts(
" Compression: #{Float.round(byte_size(result.wasm) / byte_size(result.wat) * 100, 1)}%"
)
IO.puts("")
# Step 3: Load and execute
IO.puts("🚀 Loading and executing WASM module...")
{:ok, instance} = Firebird.load(result.wasm)
tests = [
{"add(5, 3)", "add", [5, 3], 8},
{"multiply(6, 7)", "multiply", [6, 7], 42},
{"factorial(10)", "factorial", [10], 3_628_800},
{"fibonacci(20)", "fibonacci", [20], 6765},
{"gcd(12, 18)", "gcd", [12, 18], 6},
{"power(2, 10)", "power", [2, 10], 1024}
]
for {label, func, args, expected} <- tests do
{:ok, [result]} = Firebird.call(instance, func, args)
status = if result == expected, do: "✅", else: "❌"
IO.puts(" #{status} #{label} = #{result} (expected #{expected})")
end
Firebird.stop(instance)
IO.puts("")
IO.puts("✨ All tests passed! Your Elixir code is running as WebAssembly.")