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 ExprPatterns_h
19 #define ExprPatterns_h
20 
21 #include "ExprNode.h"
22 
23 namespace SeExpr2 {
24 
isVariable(const ExprNode * testee)25 inline const ExprVarNode* isVariable(const ExprNode* testee) {
26     return dynamic_cast<const ExprVarNode*>(testee);
27 };
28 
isScalar(const ExprNode * testee)29 inline const ExprNumNode* isScalar(const ExprNode* testee) {
30     return dynamic_cast<const ExprNumNode*>(testee);
31 };
32 
isVector(const ExprNode * testee)33 inline const ExprVecNode* isVector(const ExprNode* testee) {
34     return dynamic_cast<const ExprVecNode*>(testee);
35 };
36 
isLitVec(const ExprNode * testee)37 inline const ExprVecNode* isLitVec(const ExprNode* testee) {
38     if (const ExprVecNode* vec = isVector(testee))
39         if (isScalar(vec->child(0)) && isScalar(vec->child(1)) && isScalar(vec->child(2))) return vec;
40 
41     return 0;
42 };
43 
isString(const ExprNode * testee)44 inline const ExprStrNode* isString(const ExprNode* testee) {
45     return dynamic_cast<const ExprStrNode*>(testee);
46 };
47 
isAssign(const ExprNode * testee)48 inline const ExprAssignNode* isAssign(const ExprNode* testee) {
49     return dynamic_cast<const ExprAssignNode*>(testee);
50 };
51 
isFunc(const ExprNode * testee)52 inline const ExprFuncNode* isFunc(const ExprNode* testee) {
53     return dynamic_cast<const ExprFuncNode*>(testee);
54 };
55 
isNamedFunc(const ExprNode * testee,const std::string & name)56 inline const ExprFuncNode* isNamedFunc(const ExprNode* testee, const std::string& name) {
57     if (const ExprFuncNode* func = isFunc(testee))
58         if (name.compare(func->name()) == 0) return func;
59 
60     return 0;
61 };
62 
isStrFunc(const ExprNode * testee)63 inline const ExprFuncNode* isStrFunc(const ExprNode* testee) {
64     if (const ExprFuncNode* func = isFunc(testee)) {
65         int max = testee->numChildren();
66         for (int i = 0; i < max; ++i)
67             if (isString(testee->child(i))) return func;
68     };
69 
70     return 0;
71 };
72 
hasCurveNumArgs(const ExprFuncNode * testee)73 inline bool hasCurveNumArgs(const ExprFuncNode* testee) {
74     /// numChildren must be multiple of 3 plus 1
75     return !((testee->numChildren() - 1) % 3);
76 };
77 
isCurveFunc(const ExprNode * testee)78 inline const ExprFuncNode* isCurveFunc(const ExprNode* testee) {
79     const ExprFuncNode* curveFunc = isNamedFunc(testee, "curve");
80 
81     if (curveFunc && hasCurveNumArgs(curveFunc)) {
82         int numChildren = curveFunc->numChildren() - 2;
83         for (int i = 1; i < numChildren && curveFunc; i += 3) {
84             if (!isScalar(curveFunc->child(i)))
85                 curveFunc = 0;
86             else if (!isScalar(curveFunc->child(i + 1)))
87                 curveFunc = 0;
88             else if (!isScalar(curveFunc->child(i + 2)))
89                 curveFunc = 0;
90         };
91     };
92 
93     return curveFunc;
94 };
95 
isCcurveFunc(const ExprNode * testee)96 inline const ExprFuncNode* isCcurveFunc(const ExprNode* testee) {
97     const ExprFuncNode* ccurveFunc = isNamedFunc(testee, "ccurve");
98 
99     if (ccurveFunc && hasCurveNumArgs(ccurveFunc)) {
100         int numChildren = ccurveFunc->numChildren() - 2;
101         for (int i = 1; i < numChildren && ccurveFunc; i += 3) {
102             if (!isScalar(ccurveFunc->child(i)))
103                 ccurveFunc = 0;
104             else if (!isScalar(ccurveFunc->child(i + 1)) && !isLitVec(ccurveFunc->child(i + 1)))
105                 ccurveFunc = 0;
106             else if (!isScalar(ccurveFunc->child(i + 2)))
107                 ccurveFunc = 0;
108         };
109     };
110 
111     return ccurveFunc;
112 };
113 
isScalarAssign(const ExprNode * testee)114 inline const ExprAssignNode* isScalarAssign(const ExprNode* testee) {
115     /// if testee is an assignment statement, check if its sole child is a scalar
116     if (const ExprAssignNode* assign = isAssign(testee))
117         if (isScalar(assign->child(0))) return assign;
118 
119     return 0;
120 };
121 
isVectorAssign(const ExprNode * testee)122 inline const ExprAssignNode* isVectorAssign(const ExprNode* testee) {
123     /// if testee is an assignment statement, check if its sole child is a vector
124     if (const ExprAssignNode* assign = isAssign(testee))
125         if (isLitVec(assign->child(0))) return assign;
126 
127     return 0;
128 };
129 
isStrFuncAssign(const ExprNode * testee)130 inline const ExprAssignNode* isStrFuncAssign(const ExprNode* testee) {
131     /// if testee is an assignment statement, check if its sole child is a function with a string argument
132     if (const ExprAssignNode* assign = isAssign(testee))
133         if (isStrFunc(assign->child(0))) return assign;
134 
135     return 0;
136 };
137 
isCurveAssign(const ExprNode * testee)138 inline const ExprAssignNode* isCurveAssign(const ExprNode* testee) {
139     /// if testee is an assignment statement, check if its sole child is a curve function
140     if (const ExprAssignNode* assign = isAssign(testee))
141         if (isCurveFunc(assign->child(0))) return assign;
142 
143     return 0;
144 };
145 
isCcurveAssign(const ExprNode * testee)146 inline const ExprAssignNode* isCcurveAssign(const ExprNode* testee) {
147     /// if testee is an assignment statement, check if its sole child is a ccurve function
148     if (const ExprAssignNode* assign = isAssign(testee))
149         if (isCcurveFunc(assign->child(0))) return assign;
150 
151     return 0;
152 };
153 }
154 #endif
155