1 // astexpression.h 2 // this file is part of Context Free 3 // --------------------- 4 // Copyright (C) 2011-2014 John Horigan - john@glyphic.com 5 // 6 // This program is free software; you can redistribute it and/or 7 // modify it under the terms of the GNU General Public License 8 // as published by the Free Software Foundation; either version 2 9 // of the License, or (at your option) any later version. 10 // 11 // This program is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with this program; if not, write to the Free Software 18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 // 20 // John Horigan can be contacted at john@glyphic.com or at 21 // John Horigan, 1209 Villa St., Mountain View, CA 94041-1123, USA 22 // 23 // 24 25 26 #ifndef INCLUDE_ASTEXPRESSION_H 27 #define INCLUDE_ASTEXPRESSION_H 28 29 #include "ast.h" 30 #include "location.hh" 31 #include "cfdg.h" 32 #include "shape.h" 33 #include <string> 34 #include <cmath> 35 #include <limits> 36 #include "Rand64.h" 37 #include <map> 38 #include <initializer_list> 39 #include <cstddef> 40 41 class RendererAST; 42 class Builder; 43 44 #include "json_fwd.hpp" 45 using json = nlohmann::json; 46 47 namespace agg { 48 void to_json(json& j, const trans_affine& m); 49 void to_json(json& j, const trans_affine_1D& m); 50 void to_json(json& j, const trans_affine_time& m); 51 }; 52 53 void to_json(json& j, const HSBColor& m); 54 55 void to_json(json& j, const Rand64& m); 56 57 void to_json(json& j, const Modification& m); 58 59 void to_json(json& j, const StackRule& r); 60 61 class json_string { 62 public: 63 json_string() = default; json_string(const char * str)64 json_string(const char* str) : mSep(str) {} 65 json_string& operator=(const char* str) { 66 mString = str; 67 return *this; 68 } 69 json_string& operator+=(const char* str) { 70 if (!mString.empty()) 71 mString += mSep; 72 mString += str; 73 return *this; 74 } 75 json_string& operator+=(const std::string& str) { 76 if (!mString.empty()) 77 mString += mSep; 78 mString += str; 79 return *this; 80 } get()81 const std::string& get() const { 82 return mString; 83 } 84 private: 85 std::string mString; 86 std::string mSep = "+"; 87 }; 88 89 class json_float { 90 public: 91 json_float() = default; json_float(double v)92 json_float(double v) : value(v) {} 93 double value = 0.0; 94 }; 95 96 void to_json(json& j, json_float f); 97 void from_json(const json& j, json_float& f); 98 99 namespace AST { 100 101 class ASTdefine; 102 class ASTrepContainer; 103 class ASTexpression; 104 105 struct ASTexp_iter { 106 using size_type = std::size_t; 107 using difference_type = std::ptrdiff_t; 108 using value_type = const ASTexpression; 109 using reference = value_type&; 110 using pointer = value_type*; 111 using iterator_category = std::random_access_iterator_tag; 112 113 const ASTexpression* e; 114 std::size_t i; 115 ~ASTexp_iter() = default; 116 ASTexp_iter& operator=(const ASTexp_iter&) = default; 117 ASTexp_iter& operator++() {++i; return *this;} 118 ASTexp_iter operator++(int) {auto temp = *this; ++i; return temp;} 119 ASTexp_iter& operator--() {--i; return *this;} 120 ASTexp_iter operator--(int) {auto temp = *this; --i; return temp;} 121 reference operator*() const; 122 pointer operator->() const; 123 friend bool operator==(const ASTexp_iter& l, const ASTexp_iter& r) noexcept; 124 friend bool operator!=(const ASTexp_iter& l, const ASTexp_iter& r) noexcept; 125 friend bool operator<(const ASTexp_iter& l, const ASTexp_iter& r) noexcept; 126 friend bool operator>(const ASTexp_iter& l, const ASTexp_iter& r) noexcept; 127 friend bool operator<=(const ASTexp_iter& l, const ASTexp_iter& r) noexcept; 128 friend bool operator>=(const ASTexp_iter& l, const ASTexp_iter& r) noexcept; 129 130 ASTexp_iter& operator+=(size_type j) {i += j; return *this;} 131 friend ASTexp_iter operator+(const ASTexp_iter&, size_type j); 132 friend ASTexp_iter operator+(size_type j, const ASTexp_iter&); 133 ASTexp_iter& operator-=(size_type j) {i -= j; return *this;} 134 friend ASTexp_iter operator-(const ASTexp_iter&, size_type j); 135 friend difference_type operator-(const ASTexp_iter&, const ASTexp_iter&); 136 137 reference operator[](size_type) const; 138 }; 139 140 inline bool operator==(const ASTexp_iter& l, const ASTexp_iter& r) noexcept {return l.i == r.i;} 141 inline bool operator!=(const ASTexp_iter& l, const ASTexp_iter& r) noexcept {return l.i != r.i;} 142 inline bool operator<(const ASTexp_iter& l, const ASTexp_iter& r) noexcept {return l.i < r.i;} 143 inline bool operator>(const ASTexp_iter& l, const ASTexp_iter& r) noexcept {return l.i > r.i;} 144 inline bool operator<=(const ASTexp_iter& l, const ASTexp_iter& r) noexcept {return l.i <= r.i;} 145 inline bool operator>=(const ASTexp_iter& l, const ASTexp_iter& r) noexcept {return l.i >= r.i;} 146 147 inline ASTexp_iter operator+(const ASTexp_iter& iter, ASTexp_iter::size_type j) 148 {auto temp = iter; temp.i += j; return temp;} 149 inline ASTexp_iter operator+(ASTexp_iter::size_type j, const ASTexp_iter& iter) 150 {auto temp = iter; temp.i += j; return temp;} 151 inline ASTexp_iter operator-(const ASTexp_iter& iter, ASTexp_iter::size_type j) 152 {auto temp = iter; temp.i -= j; return temp;} 153 inline ASTexp_iter::difference_type operator-(const ASTexp_iter& l, const ASTexp_iter& r) 154 {return l.i - r.i;} 155 156 class ASTexpression { 157 public: 158 bool isConstant; 159 bool isNatural; 160 Locality_t mLocality; 161 expType mType; 162 yy::location where; 163 ASTexpression(const yy::location & loc)164 ASTexpression(const yy::location& loc) : isConstant(false), isNatural(false), 165 mLocality(UnknownLocal), mType(NoType), where(loc) {}; 166 ASTexpression(const yy::location& loc, bool c, bool n, expType t = NoType) isConstant(c)167 : isConstant(c), isNatural(n), mLocality(UnknownLocal), mType(t), where(loc) {}; 168 virtual ~ASTexpression() = default; 169 virtual int evaluate(double* = nullptr, int = 0, RendererAST* = nullptr) const 170 { return 0; } evaluate(Modification &,bool,RendererAST *)171 virtual void evaluate(Modification&, bool, RendererAST*) const 172 { CfdgError::Error(where, "Cannot convert this expression into an adjustment"); } 173 virtual param_ptr evalArgs(RendererAST* = nullptr, const StackRule* = nullptr) const 174 { CfdgError::Error(where, "Cannot convert this expression into a shape"); return nullptr; } entropy(std::string &)175 virtual void entropy(std::string&) const {}; simplify(Builder *)176 virtual ASTexpression* simplify(Builder*) { return nullptr; } 177 178 virtual const ASTexpression* getChild(std::size_t i) const; size()179 virtual std::size_t size() const { return 1; } 180 virtual ASTexpression* append(ASTexpression* sib); compile(CompilePhase,Builder *)181 virtual ASTexpression* compile(CompilePhase, Builder*) { return nullptr; } 182 // Always returns nullptr except during type check in the following cases: 183 // * An ASTvariable bound to a constant returns a copy of the constant 184 // * An ASTvariable bound to a rule spec returns an ASTruleSpec that 185 // acts as a stack variable 186 // * A shape spec that was parsed as an ASTuserFunc because of grammar 187 // ambiguity will return the correct ASTruleSpec 188 // 189 // It is safe to ignore the return value if you can guarantee that none 190 // of these conditions is possible. Otherwise you must replace the object 191 // with the returned object. Using the original object after type check 192 // will fail. 193 static ASTexpression* Append(ASTexpression* l, ASTexpression* r); 194 virtual void to_json(json& j) const; begin()195 ASTexp_iter begin() noexcept { return ASTexp_iter{this, 0};} begin()196 ASTexp_iter begin() const noexcept {return ASTexp_iter{this, 0};} end()197 ASTexp_iter end() noexcept {return ASTexp_iter{this, size()};} end()198 ASTexp_iter end() const noexcept {return ASTexp_iter{this, size()};} 199 }; 200 201 inline ASTexp_iter::reference ASTexp_iter::operator*() const 202 {return *e->getChild(i);} 203 inline ASTexp_iter::pointer ASTexp_iter::operator->() const 204 {return e->getChild(i);} 205 inline ASTexp_iter::reference ASTexp_iter::operator[](ASTexp_iter::size_type j) const 206 {return *e->getChild(i+j);} 207 208 void to_json(json& j, const ASTexpression& e); 209 void args_to_json(json& j, const ASTexpression& e); 210 211 class ASTfunction final : public ASTexpression { 212 public: 213 enum FuncType { NotAFunction, 214 Cos, Sin, Tan, Cot, Acos, Asin, Atan, Acot, 215 Cosh, Sinh, Tanh, Acosh, Asinh, Atanh, Log, Log10, 216 Sqrt, Exp, Abs, Floor, Ceiling, Infinity, Factorial, Sg, IsNatural, 217 BitNot, BitOr, BitAnd, BitXOR, BitLeft, BitRight, 218 Atan2, Mod, Divides, Div, 219 Dot, Cross, Hsb2Rgb, Rgb2Hsb, Vec, 220 Min, Max, Ftime, Frame, 221 Rand_Static, Rand, RandOp, Rand2, RandExponential, RandGamma, RandWeibull, 222 RandExtremeValue, RandNormal, RandLogNormal, RandChiSquared, 223 RandCauchy, RandFisherF, RandStudentT, 224 RandInt, RandBernoulli, RandBinomial, RandNegBinomial, RandPoisson, 225 RandDiscrete, RandGeometric 226 }; 227 static FuncType GetFuncType(const std::string& func); 228 static const std::string& GetFuncName(ASTfunction::FuncType t); 229 static bool RandStaticIsConst; // hideous hack for JSON 230 FuncType functype; 231 exp_ptr arguments; 232 double random; 233 ASTfunction() = delete; 234 ASTfunction(const std::string& func, exp_ptr args, Rand64& r, 235 const yy::location& nameLoc, const yy::location& argsLoc, 236 Builder* b); 237 ~ASTfunction() final = default; 238 int evaluate(double* dest = nullptr, int size = 0, RendererAST* rti = nullptr) const final; 239 void entropy(std::string& e) const final; 240 ASTexpression* compile(CompilePhase ph, Builder* b) final; 241 ASTexpression* simplify(Builder* b) final; 242 void to_json(json& j) const final; 243 }; 244 class ASTselect final : public ASTexpression { 245 enum consts_t: std::size_t { NotCached = static_cast<std::size_t>(-1) }; 246 public: 247 int tupleSize; 248 std::size_t indexCache; 249 std::string ent; 250 ASTexpArray arguments; 251 exp_ptr selector; 252 bool ifSelect; 253 254 ASTselect(exp_ptr args, const yy::location& loc, bool asIf, Builder* b); 255 ~ASTselect() final; 256 int evaluate(double* dest = nullptr, int size = 0, RendererAST* rti = nullptr) const final; 257 void evaluate(Modification& m, bool shapeDest, RendererAST* r) const final; 258 param_ptr evalArgs(RendererAST* rti = nullptr, const StackRule* parent = nullptr) const final; 259 void entropy(std::string& e) const final; 260 ASTexpression* simplify(Builder* b) final; 261 ASTexpression* compile(CompilePhase ph, Builder* b) final; 262 void to_json(json& j) const final; 263 private: 264 //ASTselect(const yy::location& loc) 265 //: ASTexpression(loc), tupleSize(-1), indexCache(0) {} 266 std::size_t getIndex(RendererAST* rti = nullptr) const; 267 }; 268 class ASTruleSpecifier : public ASTexpression { 269 public: 270 enum ArgSource { 271 NoArgs, // shapeType has no arguments 272 DynamicArgs, // shapeType has non-constant arguments 273 StackArgs, // not shapeType, StackRule* pointer to shape 274 SimpleArgs, // shapeType has constant arguments 275 ParentArgs, // reusing parent args, child shape may be different 276 SimpleParentArgs, // reusing shape args, child shape same as parent 277 ShapeArgs // not shapeType, evalArgs arguments (non-constant) to get shape 278 }; 279 int shapeType; 280 int argSize; 281 std::string entropyVal; 282 ArgSource argSource; 283 exp_ptr arguments; 284 param_ptr simpleRule; 285 int mStackIndex; 286 const ASTparameters* typeSignature; 287 const ASTparameters* parentSignature; 288 ASTparameter bound; 289 290 ASTruleSpecifier(int t, const std::string& name, exp_ptr args, const yy::location& loc, 291 const ASTparameters* parent); 292 ASTruleSpecifier(int t, const std::string& name, const yy::location& loc); 293 ASTruleSpecifier(exp_ptr args, const yy::location& loc); 294 ASTruleSpecifier(ruleSpec_ptr r) noexcept; 295 ASTruleSpecifier(const ASTruleSpecifier&) = delete; 296 ASTruleSpecifier& operator=(const ASTruleSpecifier&) = delete; ASTruleSpecifier()297 explicit ASTruleSpecifier() 298 : ASTexpression(CfdgError::Default, false, false, RuleType), shapeType(-1), 299 argSize(0), argSource(NoArgs), arguments(nullptr), 300 simpleRule(nullptr), mStackIndex(0), typeSignature(nullptr), 301 parentSignature(nullptr) {}; 302 ~ASTruleSpecifier() override; 303 int evaluate(double* dest = nullptr, int size = 0, RendererAST* rti = nullptr) const override; 304 param_ptr evalArgs(RendererAST* = nullptr, const StackRule* sr = nullptr) const override; 305 void entropy(std::string& e) const override; 306 ASTexpression* simplify(Builder* b) override; 307 ASTexpression* compile(CompilePhase ph, Builder* b) override; 308 void grab(const ASTruleSpecifier* src); 309 void to_json(json& j) const override; 310 }; 311 class ASTstartSpecifier final : public ASTruleSpecifier { 312 public: 313 mod_ptr mModification; ASTstartSpecifier(int t,const std::string & name,exp_ptr args,const yy::location & loc,mod_ptr mod)314 ASTstartSpecifier(int t, const std::string& name, exp_ptr args, 315 const yy::location& loc, mod_ptr mod) 316 : ASTruleSpecifier(t, name, std::move(args), loc, nullptr), 317 mModification(std::move(mod)) { }; ASTstartSpecifier(int nameIndex,const std::string & name,const yy::location & loc,mod_ptr mod)318 ASTstartSpecifier(int nameIndex, const std::string& name, 319 const yy::location& loc, mod_ptr mod) 320 : ASTruleSpecifier(nameIndex, name, loc), mModification(std::move(mod)) { }; ASTstartSpecifier(exp_ptr args,const yy::location & loc,mod_ptr mod)321 ASTstartSpecifier(exp_ptr args, const yy::location& loc, mod_ptr mod) 322 : ASTruleSpecifier(std::move(args), loc), mModification(std::move(mod)) { }; ASTstartSpecifier(ruleSpec_ptr r,mod_ptr m)323 ASTstartSpecifier(ruleSpec_ptr r, mod_ptr m) noexcept 324 : ASTruleSpecifier(std::move(r)), mModification(std::move(m)) { }; 325 void entropy(std::string& e) const final; 326 ASTexpression* simplify(Builder* b) final; 327 ASTexpression* compile(CompilePhase ph, Builder* b) final; 328 void to_json(json& j) const final; 329 }; 330 class ASTcons final : public ASTexpression { 331 public: 332 ASTexpArray children; 333 ASTcons() = delete; 334 ASTcons(exp_list kids); 335 ~ASTcons() final; 336 int evaluate(double* dest = nullptr, int size = 0, RendererAST* rti = nullptr) const final; 337 void evaluate(Modification& m, bool shapeDest, RendererAST* r) const final; 338 void entropy(std::string& e) const final; 339 ASTexpression* simplify(Builder* b) final; 340 ASTexpression* compile(CompilePhase ph, Builder* b) final; 341 342 const ASTexpression* getChild(std::size_t i) const final; size()343 std::size_t size() const final { return children.size(); } 344 ASTexpression* append(ASTexpression* sib) final; 345 void to_json(json& j) const final; 346 }; 347 class ASTreal final : public ASTexpression { 348 public: 349 double value; 350 std::string text; 351 ASTreal() = delete; 352 ASTreal(const std::string& t, const yy::location& loc, bool negative = false) ASTexpression(loc,true,false,NumericType)353 : ASTexpression(loc, true, false, NumericType), text(t) 354 { 355 if (negative) text.insert(0, 1, '-'); 356 value = CFatof(text.c_str()); 357 isNatural = std::floor(value) == value && value >= 0.0 && value < 9007199254740992.; 358 mLocality = PureLocal; 359 }; ASTreal(double v,const yy::location & loc)360 ASTreal(double v, const yy::location& loc) 361 : ASTexpression(loc, true, 362 std::floor(v) == v && v >= 0.0 && v < 9007199254740992., 363 NumericType), value(v) { mLocality = PureLocal; }; 364 ~ASTreal() final = default; 365 int evaluate(double* dest = nullptr, int size = 0, RendererAST* rti = nullptr) const final; 366 void entropy(std::string& e) const final; 367 void to_json(json& j) const final; 368 }; 369 class ASTvariable final : public ASTexpression { 370 public: 371 enum : int {IllegalStackIndex = std::numeric_limits<int>::max()}; 372 int stringIndex; 373 std::string text; 374 int stackIndex; 375 int count; 376 bool isParameter; 377 ASTparameter bound; 378 379 ASTvariable() = delete; 380 ASTvariable(int stringNum, const std::string& str, const yy::location& loc); 381 int evaluate(double* dest = nullptr, int size = 0, RendererAST* rti = nullptr) const final; 382 void evaluate(Modification& m, bool shapeDest, RendererAST* r) const final; 383 void entropy(std::string& e) const final; 384 ASTexpression* simplify(Builder* b) final; 385 ASTexpression* compile(CompilePhase ph, Builder* b) final; 386 void to_json(json& j) const final; 387 }; 388 class ASTuserFunction : public ASTexpression { 389 public: 390 int nameIndex; 391 ASTdefine* definition; // weak ptr 392 exp_ptr arguments; 393 bool isLet; 394 395 ASTuserFunction(int name, ASTexpression* args, ASTdefine* func, const yy::location& nameLoc); 396 ~ASTuserFunction() override = default; 397 int evaluate(double* dest = nullptr, int size = 0, RendererAST* rti = nullptr) const override; 398 void evaluate(Modification& m, bool shapeDest, RendererAST* r) const override; 399 param_ptr evalArgs(RendererAST* rti = nullptr, const StackRule* parent = nullptr) const override; 400 void entropy(std::string&) const override; 401 ASTexpression* simplify(Builder* b) override; 402 ASTexpression* compile(CompilePhase ph, Builder* b) override; 403 void to_json(json& j) const override; 404 private: 405 class StackSetup { 406 friend class ASTuserFunction; 407 StackSetup(const ASTuserFunction* func, RendererAST* rti); 408 ~StackSetup(); 409 410 const ASTuserFunction* mFunc; 411 RendererAST* mRTI; 412 const StackType* mOldTop; 413 std::size_t mOldSize; 414 }; 415 }; 416 class ASTlet final : public ASTuserFunction { 417 std::unique_ptr<ASTrepContainer> mDefinitions; 418 std::vector<std::string> mNames; 419 public: 420 ASTlet(cont_ptr args, def_ptr func, const yy::location& letLoc, 421 const yy::location& defLoc); 422 ~ASTlet() final; // inherited definition ptr owns ASTdefine 423 ASTexpression* simplify(Builder* b) final; 424 ASTexpression* compile(CompilePhase ph, Builder* b) final; 425 void to_json(json& j) const final; 426 }; 427 class ASToperator final : public ASTexpression { 428 public: 429 char op; 430 int tupleSize; 431 exp_ptr left; 432 exp_ptr right; 433 ASToperator() = delete; 434 ASToperator(char o, ASTexpression* l, ASTexpression* r); 435 ~ASToperator() final = default; 436 int evaluate(double* dest = nullptr, int size = 0, RendererAST* rti = nullptr) const final; 437 void entropy(std::string& e) const final; 438 ASTexpression* simplify(Builder* b) final; 439 ASTexpression* compile(CompilePhase ph, Builder* b) final; 440 void to_json(json& j) const final; 441 }; 442 class ASTparen final : public ASTexpression { 443 public: 444 exp_ptr e; 445 ASTparen() = delete; ASTparen(ASTexpression * e1)446 ASTparen(ASTexpression* e1) : ASTexpression(e1->where, e1->isConstant, 447 e1->isNatural, 448 e1->mType), e(e1) 449 { }; 450 ~ASTparen() final = default; 451 int evaluate(double* dest = nullptr, int size = 0, RendererAST* rti = nullptr) const final; 452 void evaluate(Modification& m, bool shapeDest, RendererAST* r) const final; 453 param_ptr evalArgs(RendererAST* rti = nullptr, const StackRule* parent = nullptr) const final; 454 void entropy(std::string& ent) const final; 455 ASTexpression* simplify(Builder* b) final; 456 ASTexpression* compile(CompilePhase ph, Builder* b) final; 457 void to_json(json& j) const final; 458 }; 459 460 class ASTmodTerm final : public ASTexpression { 461 public: 462 enum modTypeEnum : unsigned { unknownType, x, y, z, xyz, transform, 463 size, sizexyz, rot, skew, flip, 464 zsize, blend, hue, sat, bright, alpha, 465 hueTarg, satTarg, brightTarg, alphaTarg, 466 targHue, targSat, targBright, targAlpha, 467 time, timescale, 468 stroke, param, x1, y1, x2, y2, xrad, yrad, modification }; 469 470 modTypeEnum modType; 471 exp_ptr args; 472 union { 473 int argCount; 474 int flags; 475 }; 476 ASTmodTerm(modTypeEnum t,ASTexpression * a,const yy::location & loc)477 ASTmodTerm(modTypeEnum t, ASTexpression* a, const yy::location& loc) 478 : ASTexpression(loc, a->isConstant, false, ModType), modType(t), args(a), argCount(0) {}; 479 ASTmodTerm(modTypeEnum t, const std::string& ent, const yy::location& loc); ASTmodTerm(modTypeEnum t,const yy::location & loc)480 ASTmodTerm(modTypeEnum t, const yy::location& loc) 481 : ASTexpression(loc, true, false, ModType), modType(t), args(nullptr), argCount(0) {}; 482 ~ASTmodTerm() final = default; 483 int evaluate(double* dest = nullptr, int size = 0, RendererAST* rti = nullptr) const final; 484 void evaluate(Modification& m, bool shapeDest, RendererAST*) const final; 485 void entropy(std::string& e) const final; 486 ASTexpression* simplify(Builder* b) final; 487 ASTexpression* compile(CompilePhase ph, Builder* b) final; 488 void to_json(json& j) const final; 489 }; 490 491 void to_json(json& j, const ASTmodTerm& m); 492 493 class ASTmodification final : public ASTexpression { 494 public: 495 enum modClassEnum { 496 NotAClass = 0, GeomClass = 1, ZClass = 2, TimeClass = 4, 497 HueClass = 8, SatClass = 16, BrightClass = 32, AlphaClass = 64, 498 HueTargetClass = 128, SatTargetClass = 256, BrightTargetClass = 512, AlphaTargetClass = 1024, 499 StrokeClass = 2048, ParamClass = 4096, PathOpClass = 8192 500 }; 501 Modification modData; 502 ASTtermArray modExp; 503 int modClass; 504 int entropyIndex; 505 bool canonical; 506 ASTmodification(const yy::location & loc)507 ASTmodification(const yy::location& loc) 508 : ASTexpression(loc, true, false, ModType), modClass(NotAClass), 509 entropyIndex(0), canonical(true) {} 510 ASTmodification(const ASTmodification& m, const yy::location& loc); 511 ASTmodification(mod_ptr m, const yy::location& loc); 512 ~ASTmodification() final; 513 int evaluate(double* dest = nullptr, int size = 0, RendererAST* rti = nullptr) const final; 514 void evaluate(Modification& m, bool shapeDest, RendererAST*) const final; 515 ASTexpression* simplify(Builder* b) final; 516 ASTexpression* compile(CompilePhase ph, Builder* b) final; 517 void setVal(Modification& m, RendererAST* = nullptr) const; 518 void addEntropy(const std::string& name); 519 void makeCanonical(); 520 void grab(ASTmodification* m); 521 void to_json(json& j) const final; 522 }; 523 524 void to_json(json& j, const ASTmodification& m); 525 526 class ASTarray final : public ASTexpression { 527 public: 528 int mName; 529 std::unique_ptr<double[]> mData; 530 exp_ptr mArgs; 531 int mLength; 532 int mStride; 533 int mStackIndex; 534 int mCount; 535 bool isParameter; 536 std::string entString; 537 ASTparameter bound; 538 539 ASTarray(int nameIndex, exp_ptr args, const yy::location& loc, const std::string& name); 540 ASTarray(const ASTarray&) = delete; 541 ASTarray& operator=(const ASTarray&) = delete; 542 ~ASTarray() final; 543 int evaluate(double* dest = nullptr, int size = 0, RendererAST* rti = nullptr) const final; 544 void entropy(std::string& e) const final; 545 ASTexpression* simplify(Builder* b) final; 546 ASTexpression* compile(CompilePhase ph, Builder* b) final; 547 void to_json(json& j) const final; 548 }; 549 Compile(exp_ptr & exp,CompilePhase ph,Builder * b)550 inline void Compile(exp_ptr& exp, CompilePhase ph, Builder* b) 551 { 552 if (!exp) return; 553 ASTexpression* r = exp->compile(ph, b); 554 if (r) 555 exp.reset(r); 556 } 557 Simplify(exp_ptr & exp,Builder * b)558 inline void Simplify(exp_ptr& exp, Builder* b) 559 { 560 if (!exp) return; 561 ASTexpression* r = exp->simplify(b); 562 if (r) 563 exp.reset(r); 564 } 565 Extract(exp_ptr exp)566 inline ASTexpArray Extract(exp_ptr exp) 567 // Extract children from exp, leaving it empty 568 { 569 ASTexpArray ret; 570 if (ASTcons* c = dynamic_cast<ASTcons*>(exp.get())) 571 ret.swap(c->children); 572 else 573 ret.emplace_back(std::move(exp)); 574 return ret; 575 } 576 } 577 578 #endif //INCLUDE_ASTEXPRESSION_H 579