1 /* libs/graphics/animator/SkScript.h 2 ** 3 ** Copyright 2006, The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #ifndef SkScript_DEFINED 19 #define SkScript_DEFINED 20 21 #include "SkOperand.h" 22 #include "SkIntArray.h" 23 #include "SkTDict.h" 24 #include "SkTDStack.h" 25 26 class SkAnimateMaker; 27 28 class SkScriptEngine { 29 public: 30 enum Error { 31 kNoError, 32 kArrayIndexOutOfBounds, 33 kCouldNotFindReferencedID, 34 kDotOperatorExpectsObject, 35 kErrorInArrrayIndex, 36 kErrorInFunctionParameters, 37 kExpectedArray, 38 kExpectedBooleanExpression, 39 kExpectedFieldName, 40 kExpectedHex, 41 kExpectedIntForConditionOperator, 42 kExpectedNumber, 43 kExpectedNumberForArrayIndex, 44 kExpectedOperator, 45 kExpectedToken, 46 kExpectedTokenBeforeDotOperator, 47 kExpectedValue, 48 kHandleMemberFailed, 49 kHandleMemberFunctionFailed, 50 kHandleUnboxFailed, 51 kIndexOutOfRange, 52 kMismatchedArrayBrace, 53 kMismatchedBrackets, 54 kNoFunctionHandlerFound, 55 kPrematureEnd, 56 kTooManyParameters, 57 kTypeConversionFailed, 58 kUnterminatedString 59 }; 60 61 enum SkOpType { 62 kNoType, 63 kInt = 1, 64 kScalar = 2, 65 kString = 4, 66 kArray = 8, 67 kObject = 16 68 // kStruct = 32 69 }; 70 71 typedef bool (*_boxCallBack)(void* userStorage, SkScriptValue* result); 72 typedef bool (*_functionCallBack)(const char* func, size_t len, SkTDArray<SkScriptValue>& params, 73 void* userStorage, SkScriptValue* result); 74 typedef bool (*_memberCallBack)(const char* member, size_t len, void* object, 75 void* userStorage, SkScriptValue* result); 76 typedef bool (*_memberFunctionCallBack)(const char* member, size_t len, void* object, 77 SkTDArray<SkScriptValue>& params, void* userStorage, SkScriptValue* result); 78 // typedef bool (*_objectToStringCallBack)(void* object, void* userStorage, SkScriptValue* result); 79 typedef bool (*_propertyCallBack)(const char* prop, size_t len, void* userStorage, SkScriptValue* result); 80 typedef bool (*_unboxCallBack)(void* userStorage, SkScriptValue* result); 81 SkScriptEngine(SkOpType returnType); 82 ~SkScriptEngine(); 83 void boxCallBack(_boxCallBack func, void* userStorage); 84 bool convertTo(SkDisplayTypes , SkScriptValue* ); 85 bool evaluateScript(const char** script, SkScriptValue* value); 86 void forget(SkTypedArray* array); 87 void functionCallBack(_functionCallBack func, void* userStorage); getError()88 Error getError() const { return fError; } 89 #ifdef SK_DEBUG 90 bool getErrorString(SkString* err) const; 91 #endif 92 void memberCallBack(_memberCallBack , void* userStorage); 93 void memberFunctionCallBack(_memberFunctionCallBack , void* userStorage); 94 // void objectToStringCallBack(_objectToStringCallBack , void* userStorage); 95 void propertyCallBack(_propertyCallBack prop, void* userStorage); 96 void track(SkTypedArray* array); 97 void track(SkString* string); 98 void unboxCallBack(_unboxCallBack func, void* userStorage); 99 static bool ConvertTo(SkScriptEngine* , SkDisplayTypes toType, SkScriptValue* value); 100 static SkScalar IntToScalar(int32_t ); 101 static SkDisplayTypes ToDisplayType(SkOpType type); 102 static SkOpType ToOpType(SkDisplayTypes type); 103 static bool ValueToString(SkScriptValue value, SkString* string); 104 105 enum CallBackType { 106 kBox, 107 kFunction, 108 kMember, 109 kMemberFunction, 110 // kObjectToString, 111 kProperty, 112 kUnbox 113 }; 114 115 struct UserCallBack { 116 CallBackType fCallBackType; 117 void* fUserStorage; 118 union { 119 _boxCallBack fBoxCallBack; 120 _functionCallBack fFunctionCallBack; 121 _memberCallBack fMemberCallBack; 122 _memberFunctionCallBack fMemberFunctionCallBack; 123 // _objectToStringCallBack fObjectToStringCallBack; 124 _propertyCallBack fPropertyCallBack; 125 _unboxCallBack fUnboxCallBack; 126 }; 127 }; 128 129 enum SkOp { 130 kUnassigned, 131 kAdd, 132 kAddInt = kAdd, 133 kAddScalar, 134 kAddString, // string concat 135 kArrayOp, 136 kBitAnd, 137 kBitNot, 138 kBitOr, 139 kDivide, 140 kDivideInt = kDivide, 141 kDivideScalar, 142 kElse, 143 kEqual, 144 kEqualInt = kEqual, 145 kEqualScalar, 146 kEqualString, 147 kFlipOps, 148 kGreaterEqual, 149 kGreaterEqualInt = kGreaterEqual, 150 kGreaterEqualScalar, 151 kGreaterEqualString, 152 kIf, 153 kLogicalAnd, 154 kLogicalNot, 155 kLogicalOr, 156 kMinus, 157 kMinusInt = kMinus, 158 kMinusScalar, 159 kModulo, 160 kModuloInt = kModulo, 161 kModuloScalar, 162 kMultiply, 163 kMultiplyInt = kMultiply, 164 kMultiplyScalar, 165 kParen, 166 kShiftLeft, 167 kShiftRight, // signed 168 kSubtract, 169 kSubtractInt = kSubtract, 170 kSubtractScalar, 171 kXor, 172 kArtificialOp = 0x40 173 }; 174 175 enum SkOpBias { 176 kNoBias, 177 kTowardsNumber = 0, 178 kTowardsString 179 }; 180 181 protected: 182 183 struct SkOperatorAttributes { 184 unsigned int fLeftType : 3; // SkOpType, but only lower values 185 unsigned int fRightType : 3; // SkOpType, but only lower values 186 SkOpBias fBias : 1; 187 }; 188 189 struct SkSuppress { // !!! could be compressed to a long 190 SkOp fOperator; // operand which enabled suppression 191 int fOpStackDepth; // depth when suppression operator was found 192 SkBool8 fSuppress; // set if suppression happens now, as opposed to later 193 SkBool8 fElse; // set on the : half of ? : 194 }; 195 196 static const SkOperatorAttributes gOpAttributes[]; 197 static const signed char gPrecedence[]; 198 int arithmeticOp(char ch, char nextChar, bool lastPush); 199 void commonCallBack(CallBackType type, UserCallBack& callBack, void* userStorage); 200 bool convertParams(SkTDArray<SkScriptValue>&, const SkFunctionParamType* , 201 int paramTypeCount); convertToString(SkOperand & operand,SkDisplayTypes type)202 void convertToString(SkOperand& operand, SkDisplayTypes type) { 203 SkScriptValue scriptValue; 204 scriptValue.fOperand = operand; 205 scriptValue.fType = type; 206 convertTo(SkType_String, &scriptValue); 207 operand = scriptValue.fOperand; 208 } 209 bool evaluateDot(const char*& script, bool suppressed); 210 bool evaluateDotParam(const char*& script, bool suppressed, const char* field, size_t fieldLength); 211 bool functionParams(const char** scriptPtr, SkTDArray<SkScriptValue>& params); 212 bool handleArrayIndexer(const char** scriptPtr, bool suppressed); 213 bool handleBox(SkScriptValue* value); 214 bool handleFunction(const char** scriptPtr, bool suppressed); 215 bool handleMember(const char* field, size_t len, void* object); 216 bool handleMemberFunction(const char* field, size_t len, void* object, SkTDArray<SkScriptValue>& params); 217 // bool handleObjectToString(void* object); 218 bool handleProperty(bool suppressed); 219 bool handleUnbox(SkScriptValue* scriptValue); 220 bool innerScript(const char** scriptPtr, SkScriptValue* value); 221 int logicalOp(char ch, char nextChar); 222 Error opError(); 223 bool processOp(); setAnimateMaker(SkAnimateMaker * maker)224 void setAnimateMaker(SkAnimateMaker* maker) { fMaker = maker; } 225 bool setError(Error , const char* pos); 226 enum SkBraceStyle { 227 // kStructBrace, 228 kArrayBrace, 229 kFunctionBrace 230 }; 231 232 #if 0 233 SkIntArray(SkBraceStyle) fBraceStack; // curly, square, function paren 234 SkIntArray(SkOp) fOpStack; 235 SkIntArray(SkOpType) fTypeStack; 236 SkTDOperandArray fOperandStack; 237 SkTDArray<SkSuppress> fSuppressStack; 238 #else 239 SkTDStack<SkBraceStyle> fBraceStack; // curly, square, function paren 240 SkTDStack<SkOp> fOpStack; 241 SkTDStack<SkOpType> fTypeStack; 242 SkTDStack<SkOperand> fOperandStack; 243 SkTDStack<SkSuppress> fSuppressStack; 244 #endif 245 SkAnimateMaker* fMaker; 246 SkTDTypedArrayArray fTrackArray; 247 SkTDStringArray fTrackString; 248 const char* fToken; // one-deep stack 249 size_t fTokenLength; 250 SkTDArray<UserCallBack> fUserCallBacks; 251 SkOpType fReturnType; 252 Error fError; 253 int fErrorPosition; 254 private: 255 friend class SkTypedArray; 256 #ifdef SK_SUPPORT_UNITTEST 257 public: 258 static void UnitTest(); 259 #endif 260 }; 261 262 #ifdef SK_SUPPORT_UNITTEST 263 264 struct SkScriptNAnswer { 265 const char* fScript; 266 SkDisplayTypes fType; 267 int32_t fIntAnswer; 268 SkScalar fScalarAnswer; 269 const char* fStringAnswer; 270 }; 271 272 #endif 273 274 #endif // SkScript_DEFINED 275