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