SeExpr

ControlSpec.cpp
Go to the documentation of this file.
1 /*
2 Copyright Disney Enterprises, Inc. All rights reserved.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License
6 and the following modification to it: Section 6 Trademarks.
7 deleted and replaced with:
8
9 6. Trademarks. This License does not grant permission to use the
10 trade names, trademarks, service marks, or product names of the
11 Licensor and its affiliates, except as required for reproducing
12 the content of the NOTICE file.
13
14 You may obtain a copy of the License at
15 http://www.apache.org/licenses/LICENSE-2.0
16 */
17
18 #ifndef MAKEDEPEND
19 #include <string.h>
20 #include <string>
21 #include <vector>
22 #endif
23
24 #include <sstream>
25
26 #include <SeExpr2/ExprNode.h>
27 #include <SeExpr2/ExprPatterns.h>
28 #include "ControlSpec.h"
29
30 namespace SeExpr2 {
31
32 SpecExaminer::~SpecExaminer() {
33 std::vector<const ControlSpec*>::iterator i = _specList.begin();
34 std::vector<const ControlSpec*>::iterator const e = _specList.end();
35 for (; i != e; ++i) delete *i;
36 };
37
38 bool SpecExaminer::examine(const ExprNode* examinee) {
39 if (const ExprScalarAssignSpec* s_spec = ExprScalarAssignSpec::match(examinee)) {
40 _specList.push_back(s_spec);
41 return false;
42 } else if (const ExprVectorAssignSpec* v_spec = ExprVectorAssignSpec::match(examinee)) {
43 _specList.push_back(v_spec);
44 return false;
45 } else if (const ExprCurveAssignSpec<double>* c_spec = ExprCurveAssignSpec<double>::match(examinee)) {
46 _specList.push_back(c_spec);
47 return false;
48 } else if (const ExprCurveAssignSpec<Vec3d>* cc_spec = ExprCurveAssignSpec<Vec3d>::match(examinee)) {
49 _specList.push_back(cc_spec);
50 return false;
51 } else if (const ExprStrSpec* str_spec = ExprStrSpec::match(examinee)) {
52 _specList.push_back(str_spec);
53 return false;
54 };
55
56 return true;
57 };
58
59 inline std::vector<const ControlSpec*>::const_iterator SpecExaminer::begin() const {
60 return _specList.begin();
61 };
62
63 inline std::vector<const ControlSpec*>::const_iterator const SpecExaminer::end() const {
64 return _specList.end();
65 };
66
68 inline bool isWS(const char* source, int start, int end) {
69 for (int i = start; i < end; ++i)
70 if (source[i] != '\n') return false;
71 return true;
72 };
73
75 inline std::string findComment(const ExprNode& node) {
76 const Expression& expr = *node.expr();
77 typedef std::vector<std::pair<int, int> > Comments;
78 const Comments& comments = expr.getComments();
79 const std::string& s = expr.getExpr();
80
81 // TODO: user lower_bound to make this O(lg n) instead of O(n)
82 for (Comments::const_iterator i = comments.begin(); i != comments.end(); ++i) {
83 if (i->first >= node.endPos() && isWS(s.c_str(), node.endPos(), i->first))
84 return s.substr(i->first, i->second - i->first + 1);
85 }
86 return "";
87 }
88
89 ExprScalarAssignSpec::ExprScalarAssignSpec(const ExprAssignNode& node)
90 : ControlSpec(node), _min(0), _max(1), _val(static_cast<const ExprNumNode*>(node.child(0))->value()) {
91 _name = node.name();
92 std::string comment = findComment(node);
93 // TODO: handle integer case
94 int numParsed = sscanf(comment.c_str(), "#%lf,%lf\n", &_min, &_max);
95 if (numParsed != 2) {
96 _min = 0;
97 _max = 1;
98 }
99 }
100
101 std::string ExprScalarAssignSpec::toString() const {
102 std::stringstream ss;
103
104 ss << _name << ": " << value() << " in [" << _min << "," << _max << "]" << std::endl;
105
106 return ss.str();
107 }
108
109 const ExprScalarAssignSpec* ExprScalarAssignSpec::match(const ExprNode* node) {
110 if (const ExprAssignNode* assign = isScalarAssign(node)) return new ExprScalarAssignSpec(*assign);
111
112 return 0;
113 }
114
115 ExprVectorAssignSpec::ExprVectorAssignSpec(const ExprAssignNode& node)
116 : ControlSpec(node), _min(0), _max(1),
117 _val(Vec3d(static_cast<const ExprNumNode*>(node.child(0)->child(0))->value(),
118 static_cast<const ExprNumNode*>(node.child(0)->child(1))->value(),
119 static_cast<const ExprNumNode*>(node.child(0)->child(2))->value())) {
120 _name = node.name();
121 std::string comment = findComment(node);
122 int numParsed = sscanf(comment.c_str(), "#%lf,%lf\n", &_min, &_max);
123 if (numParsed != 2) {
124 _min = 0;
125 _max = 1;
126 }
127 }
128
129 std::string ExprVectorAssignSpec::toString() const {
130 std::stringstream ss;
131
132 ss << _name << ": " << value() << " in [" << _min << "," << _max << "]" << std::endl;
133 ;
134
135 return ss.str();
136 }
137
138 template <class T>
139 ExprCurveAssignSpec<T>::ExprCurveAssignSpec(const ExprAssignNode& node)
140 : ControlSpec(node), _vec() {
141 _name = node.name();
142 const ExprFuncNode* cnode = static_cast<const ExprFuncNode*>(node.child(0));
143 _lookupText = cnode->child(0)->toString();
144 int num = cnode->numChildren();
145 for (int i = 1; i < num - 2; i += 3)
146 _vec.push_back(typename Curve<T>::CV(
147 static_cast<const ExprNumNode*>(cnode->child(i))->value(),
148 static_cast<const ExprNumNode*>(cnode->child(i + 1))->value(),
149 (typename Curve<T>::InterpType) static_cast<const ExprNumNode*>(cnode->child(i + 2))->value()));
150 }
151
152 const ExprVectorAssignSpec* ExprVectorAssignSpec::match(const ExprNode* node) {
153 if (const ExprAssignNode* assign = isVectorAssign(node)) {
154 return new ExprVectorAssignSpec(*assign);
155 }
156
157 return 0;
158 }
159
160 template <class T>
161 std::string ExprCurveAssignSpec<T>::toString() const {
162 std::stringstream ss;
163
164 ss << _name << ": "
165 << "curve(" << _lookupText;
166 int num = _vec.size();
167 for (int i = 0; i < num; ++i) ss << _vec[i]._pos << _vec[i]._val << (int)_vec[i]._interp;
168 ss << ");";
169
170 return ss.str();
171 }
172
173 template <class T>
174 const ExprCurveAssignSpec<T>* ExprCurveAssignSpec<T>::match(const ExprNode* node) {
175 if (const ExprAssignNode* assign = isCurveAssign(node)) return new ExprCurveAssignSpec(*assign);
176
177 return 0;
178 }
179
180 #if 0
181
182 ExprCcurveAssignSpec::
183 ExprCcurveAssignSpec(const ExprAssignNode& node)
184 : ControlSpec(node),
185 _vec()
186 {
187 _name=node.name();
188 const ExprFuncNode* cnode(static_cast<const ExprFuncNode*>(node.child(0)));
189 _lookupText=cnode->child(0)->toString();
190 int num = cnode->numChildren();
191 for(int i = 1; i < num - 2; i += 3)
192 if(dynamic_cast<const ExprNumNode*>(cnode->child(i+1)))
193 _vec.push_back(Curve<Vec3d>::CV(
194 static_cast<const ExprNumNode*>(cnode->child(i))->value(),
195 static_cast<const ExprNumNode*>(cnode->child(i+1))->value(),
196 (Curve<Vec3d>::InterpType) static_cast<const ExprNumNode*>(cnode->child(i+2))->value()));
197 }
198
199 std::string
200 ExprCcurveAssignSpec::toString() const
201 {
202 std::stringstream ss;
203
204 ss << _name
205 << " = "
206 << "ccurve("
207 << _lookupText;
208 int num = _vec.size();
209 for(int i = 0; i < num; ++i)
210 ss << ", "
211 << _vec[i]._pos
212 << ", "
213 << _vec[i]._val
214 << ", "
215 << (int)_vec[i]._interp;
216 ss << ");";
217
218 return ss.str();
219 }
220
221 const ExprCcurveAssignSpec*
222 ExprCcurveAssignSpec::match(const ExprNode* node)
223 {
224 if(const ExprAssignNode* assign = isCcurveAssign(node))
225 return new ExprCcurveAssignSpec(*assign);
226
227
228 return 0;
229 }
230
231 #endif
232
233 std::string ExprStrSpec::toString() const {
234 std::stringstream ss;
235 ss << _name << ": \"" + _str + "\" ";
236 switch (_type) {
237 case STRING:
238 ss << "STRING";
239 break;
240 case FILE:
241 ss << "FILE";
242 break;
243 case DIRECTORY:
244 ss << "DIRECTORY";
245 break;
246 default:
247 ss << "INVALID";
248 break;
249 }
250 return ss.str();
251 }
252
253 const ExprStrSpec* ExprStrSpec::match(const ExprNode* node) {
254 if (const ExprStrNode* strnode = isString(node)) {
255 std::string comment = findComment(*node);
256 char* name = new char[comment.length() + 1];
257 char* type = new char[comment.length() + 1];
258 int numMatched = sscanf(comment.c_str(), "#%s %s\n", type, name);
259
260 Type newType;
261 if (numMatched == 2) {
262 bool valid = true;
263 if (!strcmp(type, "string"))
264 newType = STRING;
265 else if (!strcmp(type, "file"))
266 newType = FILE;
267 else if (!strcmp(type, "directory"))
268 newType = DIRECTORY;
269 else
270 valid = false;
271 if (valid) return new ExprStrSpec(*strnode, name, newType);
272 }
273 delete[] name;
274 delete[] type;
275 }
276 return 0;
277 }
278 }
SeExpr2::ExprStrSpec::_str
std::string _str
Definition: ControlSpec.h:119
SeExpr2::isString
const ExprStrNode * isString(const ExprNode *testee)
Definition: ExprPatterns.h:44
SeExpr2::isVectorAssign
const ExprAssignNode * isVectorAssign(const ExprNode *testee)
Definition: ExprPatterns.h:122
SeExpr2::ControlSpec::_name
std::string _name
Name of control.
Definition: ControlSpec.h:45
SeExpr2::ExprNode::numChildren
int numChildren() const
Number of children.
Definition: ExprNode.h:114
SeExpr2::ExprVectorAssignSpec::_min
double _min
Range of values.
Definition: ControlSpec.h:81
SeExpr2::ExprStrSpec::toString
virtual std::string toString() const
Generates a replacement string based on changes to the spec.
Definition: ControlSpec.cpp:233
SeExpr2::Vec< double, 3, false >
SeExpr2::ExprVectorAssignSpec::match
static const ExprVectorAssignSpec * match(const ExprNode *node)
Definition: ControlSpec.cpp:152
SeExpr2::ExprCurveAssignSpec::_vec
std::vector< typename Curve< T >::CV > _vec
Control points of curve spline.
Definition: ControlSpec.h:99
SeExpr2::ExprScalarAssignSpec::_min
double _min
Range of values.
Definition: ControlSpec.h:64
SeExpr2::ExprNumNode
Node that stores a numeric constant.
Definition: ExprNode.h:486
SeExpr2::ExprNode
Definition: ExprNode.h:72
SeExpr2::isWS
bool isWS(const char *source, int start, int end)
Returns true if no newline separates comment and node.
Definition: ControlSpec.cpp:68
SeExpr2::ExprVectorAssignSpec::toString
virtual std::string toString() const
Generates a replacement string based on changes to the spec.
Definition: ControlSpec.cpp:129
SeExpr2::ExprStrSpec::_type
Type _type
Definition: ControlSpec.h:120
SeExpr2::ExprStrSpec::FILE
Definition: ControlSpec.h:105
SeExpr2::ExprVectorAssignSpec::value
const Vec3d & value() const
Definition: ControlSpec.h:74
SeExpr2::ExprNode::toString
std::string toString() const
Access to original string representation of current expression.
Definition: ExprNode.h:105
SeExpr2::SpecExaminer::~SpecExaminer
~SpecExaminer()
Definition: ControlSpec.cpp:32
SeExpr2::ExprScalarAssignSpec::ExprScalarAssignSpec
ExprScalarAssignSpec(const ExprAssignNode &node)
Definition: ControlSpec.cpp:89
SeExpr2::isCurveAssign
const ExprAssignNode * isCurveAssign(const ExprNode *testee)
Definition: ExprPatterns.h:138
SeExpr2::ExprFuncNode
Node that calls a function.
Definition: ExprNode.h:517
SeExpr2::ExprAssignNode
Node that compute a local variable assignment.
Definition: ExprNode.h:355
SeExpr2::ExprCurveAssignSpec::_lookupText
std::string _lookupText
Lookup subexpression text.
Definition: ControlSpec.h:97
SeExpr2::ExprCurveAssignSpec::toString
virtual std::string toString() const
Generates a replacement string based on changes to the spec.
Definition: ControlSpec.cpp:161
SeExpr2::ExprScalarAssignSpec::toString
virtual std::string toString() const
Generates a replacement string based on changes to the spec.
Definition: ControlSpec.cpp:101
SeExpr2::ExprVectorAssignSpec::_max
double _max
Definition: ControlSpec.h:81
SeExpr2::ExprStrSpec::DIRECTORY
Definition: ControlSpec.h:106
SeExpr2::ExprScalarAssignSpec::_max
double _max
Definition: ControlSpec.h:64
SeExpr2
Definition: Context.h:22
SeExpr2::SpecExaminer::examine
virtual bool examine(const ExprNode *examinee)
Definition: ControlSpec.cpp:38
ExprNode.h
SeExpr2::ExprScalarAssignSpec::value
double value() const
Definition: ControlSpec.h:57
SeExpr2::ExprStrSpec::match
static const ExprStrSpec * match(const ExprNode *node)
Definition: ControlSpec.cpp:253
SeExpr2::ExprCurveAssignSpec::ExprCurveAssignSpec
ExprCurveAssignSpec(const ExprAssignNode &node)
Definition: ControlSpec.cpp:139
SeExpr2::ExprStrSpec::ExprStrSpec
ExprStrSpec(const ExprStrNode &node, char *name, Type type)
Takes name and type comments and takes ownership of them!
Definition: ControlSpec.h:111
SeExpr2::SpecExaminer::_specList
std::vector< const ControlSpec * > _specList
Definition: ControlSpec.h:143
SeExpr2::ExprCurveAssignSpec::match
static const ExprCurveAssignSpec * match(const ExprNode *node)
Definition: ControlSpec.cpp:174
SeExpr2::isScalarAssign
const ExprAssignNode * isScalarAssign(const ExprNode *testee)
Definition: ExprPatterns.h:114
SeExpr2::ExprCurveAssignSpec
Curve assignment expression. Assignment of curve to a variable.
Definition: ControlSpec.h:88
SeExpr2::ControlSpec
Generic Expression control specification.
Definition: ControlSpec.h:35
SeExpr2::Expression
main expression class
Definition: Expression.h:76
SeExpr2::ExprVectorAssignSpec
Variable equals vector control specification.
Definition: ControlSpec.h:70
SeExpr2::ExprStrSpec
Definition: ControlSpec.h:102
value
For any rgb or hsl value(except for negative s values)
SeExpr2::ExprStrSpec::STRING
Definition: ControlSpec.h:104
SeExpr2::ExprStrNode
Node that stores a string.
Definition: ExprNode.h:502
SeExpr2::ExprVectorAssignSpec::ExprVectorAssignSpec
ExprVectorAssignSpec(const ExprAssignNode &node)
Definition: ControlSpec.cpp:115
SeExpr2::ExprScalarAssignSpec
Variable equals scalar control specification.
Definition: ControlSpec.h:53
SeExpr2::ExprNode::expr
const Expression * expr() const
Access expression.
Definition: ExprNode.h:102
SeExpr2::SpecExaminer::end
const std::vector< const ControlSpec * >::const_iterator end() const
Definition: ControlSpec.cpp:63
ExprPatterns.h
ControlSpec.h
SeExpr2::SpecExaminer::begin
std::vector< const ControlSpec * >::const_iterator begin() const
Definition: ControlSpec.cpp:59
SeExpr2::ExprStrSpec::Type
Type
Definition: ControlSpec.h:103
SeExpr2::ExprNode::child
const ExprNode * child(size_t i) const
Get 0 indexed child.
Definition: ExprNode.h:117
SeExpr2::ExprNode::endPos
short int endPos() const
Access end position in input string.
Definition: ExprNode.h:159
SeExpr2::findComment
std::string findComment(const ExprNode &node)
Checks if there is whitespace in the range specified in the string.
Definition: ControlSpec.cpp:75
SeExpr2::Curve::InterpType
InterpType
Supported interpolation types.
Definition: Curve.h:43
SeExpr2::ExprScalarAssignSpec::match
static const ExprScalarAssignSpec * match(const ExprNode *node)
Definition: ControlSpec.cpp:109
source
When x is within< i > range</i > of source
Definition: userdoc.txt:111
expr
</pre >< h3 > Binding our variable reference</h3 > If we now tried to use the variable would still not be found by our expressions To make it bindable we need to override the resolveVar() function as follows</pre >< h3 > Variable setting</h3 > Next we need to make a way of setting the variable As the controlling code will use the expression it will repeatedly alternate between setting the independent variables that are used and calling evaluate(). What it has to do depends very much on the application. In this case we only need to set the independent variable x as</pre >< h2 > Evaluating expressions</h2 > Evaluating an expression is pretty easy But before we can do that we need to make an instance< pre > GrapherExpr expr("x+x^2")
SeExpr2::isCcurveAssign
const ExprAssignNode * isCcurveAssign(const ExprNode *testee)
Definition: ExprPatterns.h:146
SeExpr2::ExprAssignNode::name
const std::string & name() const
Definition: ExprNode.h:365
SeExpr2::Curve::CV
Definition: Curve.h:50