2
0
mirror of https://github.com/boostorg/phoenix.git synced 2026-02-13 12:42:11 +00:00
Files
phoenix/doc/reference.qbk
Thomas Heller abbc19cd0a documentation work
[SVN r68222]
2011-01-18 09:13:32 +00:00

500 lines
15 KiB
Plaintext

[/==============================================================================
Copyright (C) 2001-2010 Joel de Guzman
Copyright (C) 2001-2005 Dan Marsden
Copyright (C) 2001-2010 Thomas Heller
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
===============================================================================/]
[def __unspecified__ /unspecified/]
[template expression[type] expression::[type]]
[template rule[type] expression::[type]]
[section Reference]
While the previous section gave a brief overview on how to use the Phoenix
library, this section will provide as the reference to the interfaces defined in
phoenix.
With Phoenix being a domain specific embedded language this reference manual is
different than most references to C++ libraries.
Phoenix is designed in a way that the language constructs are clearly separated
from how they are evaluated. This follows the design principles of the C++
standard library.
This design also allows us to see the code (i.e. Phoenix Actors) as data, and the
different evaluation schemes, which act as the algorithms.
The remainder of this section is structured as following:
[variablelist
[
[
The Language
]
[
Definition of the Phoenix grammar
]
[
Reference to the mechanisms used to generate Phoenix actors
]
[
Extension mechanism of the Phoenix grammar
]
]
[
[
Evaluation
]
[
How Phoenix actors get evaluated
]
[
Reference to the predefined evaluators
]
[
Extension mechanism of the evaluation process
]
]
[
[
Advanced Tutorials
]
[
In depth discussion of the advertised features in the previous
sections
]
]
]
[heading Concepts]
Throughout this reference section various concepts are used. To disambiguate
their meanings consider the following definitions.
[heading Phoenix Actor]
A Phoenix Actor is the C++ Expression that is generated by the Phoenix
Generators.
[heading Phoenix Generator]
The Generator is a C++ Expression that results in a Phoenix Actor.
This Generator is:
* A function (can be a free function, operator, or member function)
* An instance of a Phoenix Actor
[section The Language]
The definition of the language is split into the following parts:
* formal language definition of the Phoenix Generators in EBNF notation
* Synopsis of the C++ expressions
[section Terminal]
terminal := value | reference | placeholder
value := "val" "(" expression ")"
reference := "ref" "(" C++ expression ")"
| "cref" "(" C++ expression ")"
placeholder := _1 | _2 | _3 | ... | _PHOENIX_ARG_LIMIT
Terminals are the core building blocks. Phoenix, by default distinguishes
between 3 types of terminals:
# Value Terminals
# Reference Terminals
# Placeholders
The last two terminal types are handled by the terminal customization points.
[section Value]
Whenever we see a constant in a partially applied function, an
expression::value<T>::type
(where T is the type of the constant) is automatically created for
us. For instance:
add(arg1, 6)
Passing a second argument, `6`, an `expression::value<int>::type` is implicitly created
behind the scenes. This is also equivalent to:
add(arg1, val(6))
`val(x)` generates an `expression::value<T>::type` where `T` is the type of `x`. In most
cases, there's no need to explicitly use `val`, but, as we'll see later on,
there are situations where this is unavoidable.
[heading Synopsis]
namespace expression
{
template <typename T>
struct value
{
typedef __unspecified__ type;
static type make(T t);
};
}
namespace rule
{
struct value : proto::terminal<proto::_> {};
}
template <typename T>
typename expression::value<T>::type
val(T t);
[heading Parameters]
[table
[[Parameter] [Requirement] [Description]]
[[`T`] [Model of Copy Constructible] [Operation's Argument]]
[[`t`] [Object of type T] [Operation's Argument]]
]
[heading Expression Semantics]
expression::value<T>::type
[*Return type]: Returns a Phoenix Actor representing a terminal expression
[*Semantics]: A metafunction for generating a Phoenix value expression type
expression::value<T>::make(t);
[*Return type]: `expression::value<T>::type`
[*Semantics]: Creates a Phoenix Value expression initialized with a copy of of
the supplied argument
val(t);
[*Return type]: `expression::value<T>::type`
[*Semantics]: Calls `expression::value<T>::make(t)`, Automatically deduces type T
[header Header]
#include <boost/phoenix/core/value.hpp>
[header Example]
TODO
[endsect]
[section Reference]
Values are immutable constants. Attempting to modify a value will result in a
compile time error. When we want the function to modify the parameter, we use a
reference instead. For instance, imagine a lazy function `add_assign`:
void add_assign(T& x, T y) { x += y; } // pseudo code
Here, we want the first function argument, x, to be mutable. Obviously, we
cannot write:
add_assign(1, 2) // error first argument is immutable
In C++, we can pass in a reference to a variable as the first argument in our
example above. Yet, by default, the library forces arguments passed to partially
applied functions functions to be immutable values (see [link __phoenix_reference_value__]
). To achieve our intent, we use:
expression::reference<T>::type
This is similar to `expression::value<T>::type` before but instead holds a reference to a
variable.
We normally don't instantiate `expression::reference<T>::type` objects directly. Instead we
use `ref`. For example (where `i` is an `int` variable):
add_assign(ref(i), 2)
Another free function `cref(cv)` may also be used. `cref(cv)` creates an
`expression::reference<T const>::type` object. This is similar to `expression::value<T>::type` but
when the data to be passed as argument to a function is heavy and expensive to
copy by value, the `cref(cv)` offers a lighter alternative.
[heading Synopsis]
namespace expression
{
template <typename T>
struct reference
{
typedef __unspecified__ type;
static type make(T &t);
};
}
template <typename T>
typename expression::reference<T>::type
ref(T & t);
template <typename T>
typename expression::reference<T const>::type
cref(T const & t);
[heading Parameters]
[table
[[Parameter] [Requirement] [Description]]
[[T] [] [Operation's Argument]]
[[t] [Object of type T] [Operation's Argument]]
]
[heading Expression Semantics]
expression::reference<T>::type
[*Return type]: Returns a Phoenix Actor representing a terminal expression
[*Semantics]: A metafunction for generating a Phoenix reference expression type
expression::reference<T>::make(t);
[*Return type]: `expression::reference<T>::type`
[*Semantics]: Creates a Phoenix reference expression initialized with the supplied argument
ref(t);
[*Return type]: `expression::reference<T>::type`
[*Semantics]: Calls `expression::reference<T>::make(t)`, Automatically deduces type T
cref(t);
[*Return type]: `expression::reference<T const>::type`
[*Semantics]: Calls `expression::reference<T const>::make(t)`, Automatically deduces type T
[heading Header]
#include <boost/phoenix/core/reference.hpp>
[heading Example]
TODO
[endsect]
[section Placeholder]
[heading Synopsis]
template <int I>
struct argument
: mpl::int_<I>
{
bool operator==(argument) const;
template <int I2>
bool operator==(argument<I2>) const;
};
namespace placeholders
{
}
[endsect]
[section Customization Points]
[endsect]
[endsect]
[section Actor]
bla
[endsect]
[endsect]
[endsect]
[section EBNF]
[teletype]
[def __phoenix_peg__ [link phoenix.reference.phoenix_expressions.phoenix_ast phoenix]]
[def __phoenix_peg_terminals__ [link phoenix.reference.phoenix_expressions.phoenix_ast.terminals terminals]]
[def __phoenix_peg_operator__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator operator]]
[def __phoenix_peg_operator_arithmetic__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator.arithmetic arithmetic]]
[def __phoenix_peg_operator_bitwise__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator bitwise]]
[def __phoenix_peg_operator_comparision__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator comparision]]
[def __phoenix_peg_operator_if_else__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator if_else]]
[def __phoenix_peg_operator_io__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator io]]
[def __phoenix_peg_operator_logical__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator logical]]
[def __phoenix_peg_operator_member__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator member]]
[def __phoenix_peg_operator_self__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator self]]
[def __phoenix_peg_statement__ [link phoenix.reference.phoenix_expressions.phoenix_ast.operator statement]]
[def __phoenix_peg_object__ [link phoenix.reference.phoenix_expressions.phoenix_ast.object object]]
[def __phoenix_peg_function__ [link phoenix.reference.phoenix_expressions.phoenix_ast.function function]]
[def __phoenix_peg_bind__ [link phoenix.reference.phoenix_expressions.phoenix_ast.bind bind]]
[def __phoenix_peg_scope__ [link phoenix.reference.phoenix_expressions.phoenix_ast.scope scope]]
[def __phoenix_peg_fusion__ [link phoenix.reference.phoenix_expressions.phoenix_ast.fusion fusion]]
phoenix := statement ( "," statement )*
statement := expression | loops | if_statement | exception | switch
expression := operator
primary_expr := terminal
| "if_else(" expression "," expression "," expression ")"
| cast
| construction
| bind
| scope
| ( "(" expression ")" )
terminal := value | reference | placeholder
cast := ( "static_cast_" | "dynamic_cast_" | "reinterpret_cast_" | "const_cast_" ) "<" T ">(" expression ")"
construction := ( ( "construct" | "new_" ) "<" T ">(" [ expression ( "," expression )* ] ")" ) |
( "delete_(" expression ")" )
bind := "bind(" ( expression | function_pointer ) ( "," expression )* ")"
scope := let | lambda
local_var_def := local_var "=" expression
let := "let(" [ local_var_def ( "," local_var_def )* ] ")[" ( phoenix | local_var )* "]"
lambda := "lambda" [ "(" [ local_var_def ( "," local_var_def )* ] ")" ] "[" ( phoenix | local_var )* "]"
loops := for_loop | while_loop | do_while_loop
for_loop := "for_(" expression "," expression "," expression ")[" phoenix "]"
while_loop := "while_(" expression ")[" phoenix "]"
do_while_loop := "do_[" phoenix "].while_(" expression ")"
if_statement := "if_(" expression ")[" statement "]" [ ".else_[" phoenix "]" ]
exception := throw | try_catch
throw := "throw_(" [ expression ] ")"
try_catch := "try_[" phoenix "]"
( ".catch_<" E ">()[" phoenix "]" )*
[ ".catch_all[" phoenix "]" ]
switch := "switch_(" expression ")[" (
( case_statement ( "," case_statement )* [ "," default_statement ] ) |
default_statement
)
case_statement := "case_<" N ">(" phoenix ")"
default_statement := "default_(" phoenix ")"
operator := logical_or_op (
( "=" logical_or_op )* |
( "+=" logical_or_op )* |
( "-=" logical_or_op )* |
( "*=" logical_or_op )* |
( "/=" logical_or_op )* |
( "%=" logical_or_op )* |
( "&=" logical_or_op )* |
( "^=" logical_or_op )* |
( "|=" logical_or_op )* |
( "<<=" logical_or_op )* |
( ">>=" logical_or_op )*
)
logical_or_op := logical_and_op ( "||" logical_and_op )*
logical_and_op := bitwise_or_op ( "&&" bitwise_or_op )*
bitwise_or_op := bitwise_xor_op ( "|" bitwise_xor_op )*
bitwise_xor_op := bitwise_and_op ( "^" bitwise_and_op )*
bitwise_and_op := equality_op ( "&" equality_op )*
equality_op := relational_op (
( "==" relational_op )* |
( "!=" relational_op )*
)
relational_op := shift_op (
( "<" shift_op )* |
( ">" shift_op )* |
( "<=" shift_op )* |
( ">=" shift_op )*
)
shift_op := additive_op (
( "<<" additive_op )* |
( ">>" additive_op )*
)
additive_op := multiplicative_op (
( "+" multiplicative_op )* |
( "-" multiplicative_op )*
)
multiplicative_op := member_pointer_op (
( "*" member_pointer_op )* |
( "/" member_pointer_op )*
)
member_pointer_op := unary_op ( "->*" unary_op )*
unary_op := unary_postfix_op
| ( "*" unary_postfix_op )
| ( "&" unary_postfix_op )
| ( "+" unary_postfix_op )
| ( "-" unary_postfix_op )
| ( "~" unary_postfix_op )
| ( "!" unary_postfix_op )
| ( "++" unary_postfix_op )
| ( "--" unary_postfix_op )
unary_postfix_op := primary_expr
| ( primary_expr "[" expression "]" )
| ( primary_expr "()" )
| ( primary_expr "(" expression ( "," expression )* ")" )
| ( primary_expr "++" )
| ( primary_expr "--" )
[/include reference/basics.qbk]
[/include reference/organisation.qbk]
[/include reference/concepts.qbk]
[/include reference/actor.qbk]
[/include reference/composite.qbk]
[/section Modules]
[/include reference/core.qbk]
[/include reference/function.qbk]
[/include reference/operator.qbk]
[/include reference/statement.qbk]
[/include reference/object.qbk]
[/include reference/scope.qbk]
[/include reference/bind.qbk]
[/include reference/stl.qbk]
[/endsect]
[endsect]