Subject: [proto] How to determine sign of a factor in an arithmetic expression?
From: Ole Svensson (o.svensson_at_[hidden])
Date: 2013-08-28 12:22:36
I am implementing a DSL that allows to write arithmetic expressions that involve vectors and operators. For simplicity assume the following Grammar:
struct MVGrammar : proto::or_<
proto::terminal< Vector >
, proto::plus< MVGrammar, MVGrammar >
, proto::minus< MVGrammar, MVGrammar >
, proto::multiplies< proto::terminal< Matrix >, proto::terminal< Vector > >
In order to evaluate an assignment of such an expression to a vector I plan to execute two transforms: the first one evaluates the right hand side of the statement for one component of the vectors and inserts zero for every operator application node (i.e. *-nodes that have an operator as their left child). In the assignment operator function I then simply iterate over all indices and call this transform with the respective index. The second transform does nothing for all nodes except for operator application nodes. For the latter it issues a function call that applies the operator at runtime and adds it to the left hand side of the assignment which is passed to the transform in the _data argument.
The only problem is how to detect whether the result of the operator application is to be added or subtracted from the left hand side. The answer to this problem is of course easy (if no nested matrix multiplications are allowed) but I do not understand how I can implement it with Proto: While walking the AST I want to pass along an integer that counts minus/negate nodes. If I encounter a minus node I evaluate the left child with the number passed unmodified and the right child with the number incremented by one. For a negate node the child is evaluated with the number incremented by one. When I encounter a multiply node with an operator I calculate my counting integer modulo 2. If the modulus is 0, I call the function for addition, if it is 1, I call the function for subtraction.
How can I implement this behavior? I thought I could maybe abuse the _state parameter for this but got not very far by trying that. Or is there a more clever way to achieve what I want to do?
Proto list run by eric at boostpro.com