Skip to content

Commit

Permalink
Type narrow in I32.sum!/1
Browse files Browse the repository at this point in the history
  • Loading branch information
RoyalIcing committed Dec 6, 2023
1 parent 12509d5 commit 94329c5
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 54 deletions.
27 changes: 16 additions & 11 deletions lib/orb/i32.ex
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,24 @@ defmodule Orb.I32 do
end

def sum!(items) when is_list(items) do
Enum.reduce(items, &add/2)
items
|> Enum.map(&Orb.TypeNarrowable.type_narrow_to(&1, Orb.I32))
|> Enum.reduce(&add/2)
end

def in?(value, list) when is_list(list) do
instructions = for {item, index} <- Enum.with_index(list) do
case index do
0 ->
eq(value, item)

_ ->
InstructionSequence.new(:i32, [eq(value, item), Instruction.i32(:or)])
# Instruction.i32(:or, eq(value, item))
instructions =
for {item, index} <- Enum.with_index(list) do
case index do
0 ->
eq(value, item)

_ ->
InstructionSequence.new(:i32, [eq(value, item), Instruction.i32(:or)])
# Instruction.i32(:or, eq(value, item))
end
end
end

InstructionSequence.new(:i32, instructions)
end

Expand Down Expand Up @@ -196,7 +200,8 @@ defmodule Orb.I32 do
def __global_value(false), do: Instruction.wrap_constant!(:i32, 0)
def __global_value(true), do: Instruction.wrap_constant!(:i32, 1)
# TODO: stash away which module so we can do smart stuff like with local types
def __global_value(mod) when is_atom(mod), do: Instruction.wrap_constant!(:i32, mod.initial_i32())
def __global_value(mod) when is_atom(mod),
do: Instruction.wrap_constant!(:i32, mod.initial_i32())

defmacro global(mutability \\ :mutable, list)
when mutability in ~w{readonly mutable}a do
Expand Down
107 changes: 64 additions & 43 deletions test/i32/conveniences_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ defmodule I32ConveniencesTest do
(char >= ?A &&& char <= ?Z) or
(char >= ?0 &&& char <= ?9) or
I32.in?(char, [?~, ?_, ?-, ?.])
# I32.in?(char, ~C{~_-.})

# I32.in?(char, ~C{~_-.})

# I32.in_inclusive_range?(char, ?a, ?z) or
# I32.in_inclusive_range?(char, ?A, ?Z) or
Expand Down Expand Up @@ -61,66 +62,86 @@ defmodule I32ConveniencesTest do

test "attr_writer works" do
assert Attrs.to_wat() === """
(module $Attrs
(global $first (mut i32) (i32.const 7))
(func $first= (export "first=") (param $new_value i32)
(local.get $new_value)
(global.set $first)
)
)
"""
(module $Attrs
(global $first (mut i32) (i32.const 7))
(func $first= (export "first=") (param $new_value i32)
(local.get $new_value)
(global.set $first)
)
)
"""

assert Wasm.call(Attrs, :"first=", 9) == nil
end

test "I32.match output int" do
assert (OrbHelper.module_wat do
use Orb
use Orb

defw get_path(), I32.String, state: I32 do
state = 0
defw get_path(), I32.String, state: I32 do
state = 0

I32.match state do
0 -> 100
1 -> 200
end
end
end) =~ "(i32.const 100)"
I32.match state do
0 -> 100
1 -> 200
end
end
end) =~ "(i32.const 100)"
end

test "I32.match output string constant" do
assert (OrbHelper.module_wat do
use Orb
use Orb

defw get_path(), I32.String, state: I32 do
state = 0
defw get_path(), I32.String, state: I32 do
state = 0

I32.match state do
0 -> ~S[/initial]
1 -> ~S[/disconnected]
end
end
end) =~ "/initial"
I32.match state do
0 -> ~S[/initial]
1 -> ~S[/disconnected]
end
end
end) =~ "/initial"
end

test "can return string constant" do
assert (OrbHelper.module_wat do
use Orb

global do
@method "GET"
end

defw text_html(), I32.String do
if not I32.String.streq(@method, "GET") do
return(~S"""
<!doctype html>
<h1>Method not allowed</h1>
""")
end
use Orb

global do
@method "GET"

Check warning on line 112 in test/i32/conveniences_test.exs

View workflow job for this annotation

GitHub Actions / Build and test (26.0.2, 1.15.2)

module attribute @method was set but never used

Check warning on line 112 in test/i32/conveniences_test.exs

View workflow job for this annotation

GitHub Actions / Build and test (25.3.2, 1.15.2)

module attribute @method was set but never used
end

defw text_html(), I32.String do
if not I32.String.streq(@method, "GET") do
return(~S"""
<!doctype html>
<h1>Method not allowed</h1>
""")
end

"<p>Hello</p>"
end
end) =~ "Method not allowed"
end

"<p>Hello</p>"
end
end) =~ "Method not allowed"
test "I32.sum!" do
assert 30 =
(OrbHelper.module_wat do
use Orb

defwp(ten(), I32, do: 10)

defw sum(), I32 do
I32.sum!([
byte_size("hello"),
byte_size("beautiful"),
byte_size("world"),
if(ten(), do: 1, else: 200),
ten()
])
end
end)
|> Wasm.call(:sum)
end
end

0 comments on commit 94329c5

Please sign in to comment.