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