Permalink
Browse files

added virtual function, plain_fsm:current_function()

  • Loading branch information...
uwiger committed Mar 23, 2013
1 parent 2f3099f commit 7c1d0bcbaf93f1897b8256966d8c810d6ba75dcd
Showing with 46 additions and 13 deletions.
  1. +3 −3 README.md
  2. +16 −1 doc/plain_fsm.md
  3. +12 −9 src/fsm_example.erl
  4. +10 −0 src/plain_fsm.erl
  5. +5 −0 src/plain_fsm_xform.erl
View
@@ -7,7 +7,7 @@
<table width="100%" border="0" summary="list of modules">
-<tr><td><a href="http://github.com/esl/plain_fsm/blob/docfix/doc/fsm_example.md" class="module">fsm_example</a></td></tr>
-<tr><td><a href="http://github.com/esl/plain_fsm/blob/docfix/doc/plain_fsm.md" class="module">plain_fsm</a></td></tr>
-<tr><td><a href="http://github.com/esl/plain_fsm/blob/docfix/doc/plain_fsm_xform.md" class="module">plain_fsm_xform</a></td></tr></table>
+<tr><td><a href="http://github.com/esl/plain_fsm/blob/master/doc/fsm_example.md" class="module">fsm_example</a></td></tr>
+<tr><td><a href="http://github.com/esl/plain_fsm/blob/master/doc/plain_fsm.md" class="module">plain_fsm</a></td></tr>
+<tr><td><a href="http://github.com/esl/plain_fsm/blob/master/doc/plain_fsm_xform.md" class="module">plain_fsm_xform</a></td></tr></table>
View
@@ -228,7 +228,7 @@ See [behaviour_info/1](#behaviour_info-1) for details.<a name="index"></a>
<table width="100%" border="1" cellspacing="0" cellpadding="2" summary="function index"><tr><td valign="top"><a href="#behaviour_info-1">behaviour_info/1</a></td><td>Defines which functions this behaviour expects to be exported from
-the user's callback module.</td></tr><tr><td valign="top"><a href="#extended_receive-1">extended_receive/1</a></td><td>Virtual function used to wrap receive clauses.</td></tr><tr><td valign="top"><a href="#handle_msg-3">handle_msg/3</a></td><td>Called in a "catch-all" clause within a receive statement.</td></tr><tr><td valign="top"><a href="#handle_system_msg-4">handle_system_msg/4</a></td><td>Called when the process receives a system message.</td></tr><tr><td valign="top"><a href="#hibernate-3">hibernate/3</a></td><td>Virtual function used to wrap a call to the BIF erlang:hibernate/3.</td></tr><tr><td valign="top"><a href="#info-1">info/1</a></td><td>retrieves meta-data for the plain_fsm process.</td></tr><tr><td valign="top"><a href="#parent_EXIT-2">parent_EXIT/2</a></td><td>Handles parent termination properly.</td></tr><tr><td valign="top"><a href="#spawn-2">spawn/2</a></td><td>Equivalent to <code>proc_lib:spawn(StartF)</code>.</td></tr><tr><td valign="top"><a href="#spawn_link-2">spawn_link/2</a></td><td>Equivalent to <code>proc_lib:spawn_link(StartF)</code>.</td></tr><tr><td valign="top"><a href="#spawn_opt-3">spawn_opt/3</a></td><td>Equivalent to <code>proc_lib:spawn_opt(StartF, Opts)</code>.</td></tr><tr><td valign="top"><a href="#spawn_opt-4">spawn_opt/4</a></td><td>Equivalent to <code>proc_lib:spawn_opt(Node, StartF, Opts)</code>.</td></tr><tr><td valign="top"><a href="#start_opt-4">start_opt/4</a></td><td>Similar to <code>proc_lib:start(M,F,A, Timeout, Opts)</code>.</td></tr><tr><td valign="top"><a href="#store_name-1">store_name/1</a></td><td>stores an internal name for the FSM
+the user's callback module.</td></tr><tr><td valign="top"><a href="#current_function-0">current_function/0</a></td><td>Virtual function for extracting the current function.</td></tr><tr><td valign="top"><a href="#extended_receive-1">extended_receive/1</a></td><td>Virtual function used to wrap receive clauses.</td></tr><tr><td valign="top"><a href="#handle_msg-3">handle_msg/3</a></td><td>Called in a "catch-all" clause within a receive statement.</td></tr><tr><td valign="top"><a href="#handle_system_msg-4">handle_system_msg/4</a></td><td>Called when the process receives a system message.</td></tr><tr><td valign="top"><a href="#hibernate-3">hibernate/3</a></td><td>Virtual function used to wrap a call to the BIF erlang:hibernate/3.</td></tr><tr><td valign="top"><a href="#info-1">info/1</a></td><td>retrieves meta-data for the plain_fsm process.</td></tr><tr><td valign="top"><a href="#parent_EXIT-2">parent_EXIT/2</a></td><td>Handles parent termination properly.</td></tr><tr><td valign="top"><a href="#spawn-2">spawn/2</a></td><td>Equivalent to <code>proc_lib:spawn(StartF)</code>.</td></tr><tr><td valign="top"><a href="#spawn_link-2">spawn_link/2</a></td><td>Equivalent to <code>proc_lib:spawn_link(StartF)</code>.</td></tr><tr><td valign="top"><a href="#spawn_opt-3">spawn_opt/3</a></td><td>Equivalent to <code>proc_lib:spawn_opt(StartF, Opts)</code>.</td></tr><tr><td valign="top"><a href="#spawn_opt-4">spawn_opt/4</a></td><td>Equivalent to <code>proc_lib:spawn_opt(Node, StartF, Opts)</code>.</td></tr><tr><td valign="top"><a href="#start_opt-4">start_opt/4</a></td><td>Similar to <code>proc_lib:start(M,F,A, Timeout, Opts)</code>.</td></tr><tr><td valign="top"><a href="#store_name-1">store_name/1</a></td><td>stores an internal name for the FSM
(for <code>sys:get_status()</code>).</td></tr><tr><td valign="top"><a href="#tail_apply-5">tail_apply/5</a></td><td>Helper function to dispatch blocking calls as tail calls.</td></tr><tr><td valign="top"><a href="#wake_up-5">wake_up/5</a></td><td></td></tr></table>
@@ -270,6 +270,21 @@ modules during a code change.
another continuation (point of entry into your own code after the
code change.)
+<a name="current_function-0"></a>
+
+###current_function/0##
+
+
+<pre>current_function() -&gt; {Module, Function, Arity}</pre>
+<br></br>
+
+
+Virtual function for extracting the current function.
+
+
+This function call is expanded by the `plain_fsm` parse transform
+into the name and arity (`{Module, Function, Arity}`) of the current
+function. It cannot be used from code that hasn't been transformed.
<a name="extended_receive-1"></a>
###extended_receive/1##
View
@@ -47,6 +47,9 @@
%% needed because they are called via hibernate()
-export([a/1, b/1]).
+-define(cur, plain_fsm:current_function()).
+-define(dbg(F, A), io:fwrite("[~p]~p: " ++ F, [?LINE,?cur|A])).
+
data_vsn() ->
5.
@@ -64,40 +67,40 @@ idle(S) ->
plain_fsm:extended_receive(
receive
a ->
- io:format("going to state a~n", []),
+ ?dbg("going to state a~n", []),
plain_fsm:hibernate(?MODULE,a,[S]);
b ->
- io:format("going to state b~n", []),
+ ?dbg("going to state b~n", []),
b(S)
after 10000 ->
- io:format("timeout in idle~n", []),
+ ?dbg("timeout in idle~n", []),
idle(S)
end).
a(S) ->
receive
b ->
- io:format("going to state b~n", []),
+ ?dbg("going from to state b~n", []),
eventually_b(S);
idle ->
- io:format("going to state idle~n", []),
+ ?dbg("going to state idle~n", []),
idle(S)
% after 10000 ->
-% io:format("timeout in a~n", []),
+% ?dbg("timeout in a~n", []),
% idle(S)
end.
b(S) ->
receive
a ->
- io:format("going to state a~n", []),
+ ?dbg("going to state a~n", []),
a(S);
idle ->
- io:format("going to state idle~n", []),
+ ?dbg("going to state idle~n", []),
idle(S)
after 10000 ->
- io:format("timeout in b~n", []),
+ ?dbg("timeout in b~n", []),
idle(S)
end.
View
@@ -208,6 +208,7 @@
handle_msg/3,
parent_EXIT/2,
store_name/1,
+ current_function/0,
info/1]).
@@ -345,6 +346,15 @@ store_name(Name) ->
put({?MODULE,info}, I#info{sys = Sys#sys{name = Name}}),
ok.
+%% @spec current_function() -> {Module, Function, Arity}
+%% @doc Virtual function for extracting the current function.
+%% <p>This function call is expanded by the `plain_fsm' parse transform
+%% into the name and arity (`{Module, Function, Arity}') of the current
+%% function. It cannot be used from code that hasn't been transformed.
+%% </p>
+%% @end
+current_function() ->
+ exit(cannot_be_called_directly).
%% @spec info(What::atom()) -> term()
%% What = debug | name | mod | parent
View
@@ -84,6 +84,11 @@ xform_plainfsm(Forms) ->
{?PLAIN_FSM, {hibernate, 3}} ->
#context{module = Module} = Context,
{hibernate(Module, Form), Acc};
+ {?PLAIN_FSM, {current_function, 0}} ->
+ #context{module = Mo,
+ function = Fn,
+ arity = Ay} = Context,
+ {erl_parse:abstract({Mo, Fn, Ay}), Acc};
_ ->
{Form, Acc}
end;

0 comments on commit 7c1d0bc

Please sign in to comment.