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 
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 
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 
110  if (const ExprAssignNode* assign = isScalarAssign(node)) return new ExprScalarAssignSpec(*assign);
111 
112  return 0;
113 }
114 
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>
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 
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>
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 
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