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 }
bool isWS(const char *source, int start, int end)
Returns true if no newline separates comment and node.
Definition: ControlSpec.cpp:68
const ExprAssignNode * isVectorAssign(const ExprNode *testee)
Definition: ExprPatterns.h:122
std::string findComment(const ExprNode &node)
Checks if there is whitespace in the range specified in the string.
Definition: ControlSpec.cpp:75
ExprStrSpec(const ExprStrNode &node, char *name, Type type)
Takes name and type comments and takes ownership of them!
Definition: ControlSpec.h:111
const ExprAssignNode * isCcurveAssign(const ExprNode *testee)
Definition: ExprPatterns.h:146
virtual std::string toString() const
Generates a replacement string based on changes to the spec.
</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")
const ExprStrNode * isString(const ExprNode *testee)
Definition: ExprPatterns.h:44
static const ExprCurveAssignSpec * match(const ExprNode *node)
Variable equals scalar control specification.
Definition: ControlSpec.h:53
static const ExprVectorAssignSpec * match(const ExprNode *node)
double _min
Range of values.
Definition: ControlSpec.h:81
short int endPos() const
Access end position in input string.
Definition: ExprNode.h:159
double _min
Range of values.
Definition: ControlSpec.h:64
Variable equals vector control specification.
Definition: ControlSpec.h:70
Node that stores a string.
Definition: ExprNode.h:499
Generic Expression control specification.
Definition: ControlSpec.h:35
std::string _name
Name of control.
Definition: ControlSpec.h:45
const std::vector< std::pair< int, int > > & getComments() const
Definition: Expression.h:147
const ExprAssignNode * isCurveAssign(const ExprNode *testee)
Definition: ExprPatterns.h:138
ExprVectorAssignSpec(const ExprAssignNode &node)
For any rgb or hsl value(except for negative s values)
virtual bool examine(const ExprNode *examinee)
Definition: ControlSpec.cpp:38
Curve assignment expression. Assignment of curve to a variable.
Definition: ControlSpec.h:88
const std::string & getExpr() const
Get the string that this expression is currently set to evaluate.
Definition: Expression.h:122
Node that calls a function.
Definition: ExprNode.h:514
ExprScalarAssignSpec(const ExprAssignNode &node)
Definition: ControlSpec.cpp:89
const Vec3d & value() const
Definition: ControlSpec.h:74
virtual std::string toString() const
Generates a replacement string based on changes to the spec.
const ExprAssignNode * isScalarAssign(const ExprNode *testee)
Definition: ExprPatterns.h:114
main expression class
Definition: Expression.h:76
std::vector< const ControlSpec * >::const_iterator begin() const
Definition: ControlSpec.cpp:59
ExprCurveAssignSpec(const ExprAssignNode &node)
Node that compute a local variable assignment.
Definition: ExprNode.h:354
int numChildren() const
Number of children.
Definition: ExprNode.h:114
Node that stores a numeric constant.
Definition: ExprNode.h:483
static const ExprScalarAssignSpec * match(const ExprNode *node)
const Expression * expr() const
Access expression.
Definition: ExprNode.h:102
std::vector< const ControlSpec * > _specList
Definition: ControlSpec.h:143
When x is within< i > range</i > of source
Definition: userdoc.txt:111
std::string _lookupText
Lookup subexpression text.
Definition: ControlSpec.h:97
virtual std::string toString() const
Generates a replacement string based on changes to the spec.
const ExprNode * child(size_t i) const
Get 0 indexed child.
Definition: ExprNode.h:117
std::string toString() const
Access to original string representation of current expression.
Definition: ExprNode.h:105
InterpType
Supported interpolation types.
Definition: Curve.h:43
std::vector< typename Curve< T >::CV > _vec
Control points of curve spline.
Definition: ControlSpec.h:99
static const ExprStrSpec * match(const ExprNode *node)
virtual std::string toString() const
Generates a replacement string based on changes to the spec.
std::vector< const ControlSpec * >::const_iterator const end() const
Definition: ControlSpec.cpp:63
const std::string & name() const
Definition: ExprNode.h:364