Skip to content

Instantly share code, notes, and snippets.

@tony612
Last active May 20, 2017 16:08
Show Gist options
  • Save tony612/720287cc2f8701e2b6bcabe294212a17 to your computer and use it in GitHub Desktop.
Save tony612/720287cc2f8701e2b6bcabe294212a17 to your computer and use it in GitHub Desktop.
defmodule FSM do
defmacro __using__(opts) do
quote do
import FSM.DSL, only: [trans: 3]
Module.register_attribute(__MODULE__, :events, accumulate: true)
@before_compile FSM.DSL
end
end
end
defmodule FSM.DSL do
defmacro trans(name, from, to) do
quote do
@events unquote(name)
def unquote(name)(unquote(from)) do
unquote(to)
end
end
end
defmacro __before_compile__(env) do
fields = Module.get_attribute(env.module, :events)
quote do
def __events__ do
unquote(Enum.reverse(fields))
end
end
end
end
defmodule Door do
use FSM
trans :push, "closed", "opened"
trans :pull, "opened", "closed"
end
state0 = "closed"
state1 = Door.push(state0) # "opened"
state2 = Door.pull(state1) # "closed"
Door.__events__ # [:push, :pull]
defmodule FSM do
defmacro __using__(opts) do
quote do
import FSM.DSL, only: [trans: 3]
end
end
end
defmodule FSM.DSL do
defmacro trans(name, from, to) do
quote do
def unquote(name)(unquote(from)) do
unquote(to)
end
end
end
end
defmodule Door do
use FSM
trans :push, "closed", "opened"
trans :pull, "opened", "closed"
end
state0 = "closed"
state1 = Door.push(state0) # "opened"
state2 = Door.pull(state1) # "closed"
defmodule FSM do
defmacro __using__(opts) do
quote do
import FSM.DSL, only: [trans: 3]
Module.register_attribute(__MODULE__, :events, accumulate: true)
@before_compile FSM.DSL
end
end
end
defmodule FSM.DSL do
defmacro trans(name, from, to) do
quote do
@events unquote(name)
end
end
defmacro __before_compile__(env) do
fields = Module.get_attribute(env.module, :events)
quote do
def __events__ do
unquote(Enum.reverse(fields))
end
end
end
end
defmodule Door do
use FSM
trans :push, "closed", "opened"
trans :pull, "opened", "closed"
end
Door.__events__ # [:push, :pull]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment