]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [/============================================================================== |
2 | Copyright (C) 2001-2010 Joel de Guzman | |
3 | Copyright (C) 2001-2005 Dan Marsden | |
4 | Copyright (C) 2001-2010 Thomas Heller | |
5 | ||
6 | Distributed under the Boost Software License, Version 1.0. (See accompanying | |
7 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
8 | ===============================================================================/] | |
9 | ||
10 | [section:actions More on Actions] | |
11 | ||
12 | As you know from the [link phoenix.inside.actor Actors in Detail] section, | |
13 | Actions are what brings life to a Phoenix expression tree. | |
14 | ||
15 | When dealing with a Phoenix expression tree, it gets evaluated top-down. | |
16 | Example: | |
17 | ||
18 | _1 + 3 * _2 | |
19 | ||
20 | Can be visualized as an AST in the following way: | |
21 | ||
22 | [$images/simple_ast.png] | |
23 | ||
24 | In terms of actions this means: | |
25 | ||
26 | * `rule::plus` is matched | |
27 | * evaluate left: | |
28 | * `rule::placeholder` is matched | |
29 | * evaluate right: | |
30 | * `rule::multiplies` is matched | |
31 | * evaluate left: | |
32 | * `rule::value` is matched | |
33 | * evaluate right: | |
34 | * `rule::placeholder` is matched | |
35 | ||
36 | Every time a rule is matched, an action will be called. The action determines | |
37 | how the Phoenix AST will be traversed. | |
38 | ||
39 | [heading Writing an Action] | |
40 | ||
41 | As mentioned in [link phoenix.inside.actor Actors in Detail] actions are | |
42 | __proto_primitive_transforms__ for convenience Phoenix provides an abstraction | |
43 | to this: | |
44 | ||
45 | template <typename Fun> | |
46 | struct call; | |
47 | ||
48 | This is similar to __proto_call__ but does more. It calls the `Fun` function | |
49 | object passed as template parameter with the `Context` and the children of the | |
50 | expression associated with the rule. | |
51 | ||
52 | Lets have an (simplified) example on how to write an evaluation action for | |
53 | `rule::plus`: | |
54 | ||
55 | struct plus_eval | |
56 | { | |
57 | typedef int result_type; | |
58 | ||
59 | template <typename Lhs, typename Rhs, typename Context> | |
60 | result_type operator()(Lhs const& lhs, Rhs const &rhs, Context & ctx) | |
61 | { | |
62 | return eval(lhs, ctx) + eval(rhs, ctx); | |
63 | } | |
64 | }; | |
65 | ||
66 | template <> | |
67 | struct default_actions::when<rule::plus> | |
68 | : call<plus_eval> | |
69 | {}; | |
70 | ||
71 | That's it. When evaluating a `plus` expression, the `plus_eval` callable gets | |
72 | called with the left hand side and right hand side expression and the associated | |
73 | Context. | |
74 | ||
75 | [*But there is more:] As Actions /can/ be full fletched __proto_transforms__, you can | |
76 | in fact use any proto expression you can imagine as the action. Phoenix predifines a | |
77 | set of callables and transform to deal with the Context information passed along and | |
78 | of course every Phoenix expression can be used as a Phoenix grammar or | |
79 | __proto_pass_through_transform__. | |
80 | ||
81 | [variablelist | |
82 | [ | |
83 | [`functional::context(Env, Actions)`] | |
84 | [A __proto_callable__ that creates a new context out of the `Env` and `Actions` parameter] | |
85 | ] | |
86 | [ | |
87 | [`functional::env(Context)`] | |
88 | [A __proto_callable__ that returns the environment out of the `Context` parameter] | |
89 | ] | |
90 | [ | |
91 | [`functional::actions(Context)`] | |
92 | [A __proto_callable__ that returns the actions out of the `Context` parameter] | |
93 | ] | |
94 | [ | |
95 | [`_context`] | |
96 | [A __proto_primitive_transform__ that returns the current context] | |
97 | ] | |
98 | [ | |
99 | [`_env`] | |
100 | [A __proto_primitive_transform__ that returns the current environment] | |
101 | ] | |
102 | [ | |
103 | [`_actions`] | |
104 | [A __proto_primitive_transform__ that returns the current actions] | |
105 | ] | |
106 | [ | |
107 | [`context(env, actions)`] | |
108 | [A regular function that creates a context] | |
109 | ] | |
110 | [ | |
111 | [`env(ctx)`] | |
112 | [A regular function that returns the environment from the given context] | |
113 | ] | |
114 | [ | |
115 | [`actions(ctx)`] | |
116 | [A regular function that returns the actions from the given context] | |
117 | ] | |
118 | ] | |
119 | ||
120 | Phoenix is equipped with a predefined set of expressions, rules and actions to | |
121 | make all the stuff work you learned in the __phoenix_starter_kit__ and __phoenix_modules__ | |
122 | sections. See the [link phoenix.inside.rules next section] for more details! | |
123 | ||
124 | [endsect] |