Skip to content

Commit

Permalink
Fix literal map in local expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
ashton314 committed Aug 1, 2024
1 parent 94790fc commit 632f084
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 8 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,10 @@ If you find any bugs or would like to suggest a feature, please [open an issue o

We will collect change descriptions here until we come up with a more stable format when changes get bigger.

- v0.4.1; 2024-08-01

Bugfix: choreographies can now have literal maps in local expressions.

- v0.4.0; 2024-08-01

Functions can take arbitrary number of arguments from different actors.
Expand Down
12 changes: 5 additions & 7 deletions lib/chorex.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1120,16 +1120,11 @@ defmodule Chorex do
defp do_local_project({funcname, _meta, args} = funcall, acc, _env, label, _ctx)
when is_atom(funcname) and is_list(args) do
num_args = length(args)
variadics = [:{}, :%{}]
builtins = Kernel.__info__(:functions) ++ Kernel.__info__(:macros)

cond do
# The function name :{} is variadic: it constructs a tuple from
# all its arguments; since it doesn't have an arity, we have to
# special-case it here.
:{} == funcname ->
return(funcall, acc)

# Likewise, __aliases__ is a special form and stays as-is.
# __aliases__ is a special form and stays as-is.
:__aliases__ == funcname ->
return(funcall, acc)

Expand All @@ -1138,6 +1133,9 @@ defmodule Chorex do
match?({:., [{:__aliases__, _, _} | _]}, {funcname, args}) ->
return(funcall, acc)

Enum.member?(variadics, funcname) ->
return(funcall, acc)

Enum.member?(builtins, {funcname, num_args}) ->
return(funcall, acc)

Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule Chorex.MixProject do
def project do
[
app: :chorex,
version: "0.4.0",
version: "0.4.1",
elixir: "~> 1.16",
start_permanent: Mix.env() == :prod,
description: description(),
Expand Down
46 changes: 46 additions & 0 deletions test/function_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,50 @@ defmodule FunctionTest do

assert_receive {:chorex_return, CounterClient, 55}
end


defmodule Counter2Test do
defchor [Counter2Server, Counter2Client] do
def loop(Counter2Server.(%{count: i})) do
if Counter2Client.continue?() do
Counter2Client[L] ~> Counter2Server
Counter2Client.bump() ~> Counter2Server.(incr_amt)
loop(Counter2Server.(%{count: incr_amt + i}))
else
Counter2Client[R] ~> Counter2Server
Counter2Server.(i) ~> Counter2Client.(final_result)
Counter2Client.(final_result)
end
end

def run() do
loop(Counter2Server.(%{count: 0}))
end

def run(Counter2Server.(start)) do
loop(Counter2Server.(%{count: start}))
end
end
end

defmodule MyCounter2Server do
use Counter2Test.Chorex, :counter2server
end

defmodule MyCounter2Client do
use Counter2Test.Chorex, :counter2client

def continue?() do
# Process dictionary black magic!! Do not do! Testing only! Only
# used to model getting value to continue from external source!
Process.put(:acc, 1 + Process.get(:acc, 0))
10 >= Process.get(:acc)
end

def bump(), do: Process.get(:acc)
end

test "looping increment with rich state" do
Chorex.start(Counter2Test.Chorex, %{Counter2Server => MyCounter2Server, Counter2Client => MyCounter2Client}, [])
end
end

0 comments on commit 632f084

Please sign in to comment.