|  |  | 
|  | /* | 
|  | * Copyright 2006 The Android Open Source Project | 
|  | * | 
|  | * Use of this source code is governed by a BSD-style license that can be | 
|  | * found in the LICENSE file. | 
|  | */ | 
|  |  | 
|  |  | 
|  | #ifndef SkScript_DEFINED | 
|  | #define SkScript_DEFINED | 
|  |  | 
|  | #include "SkOperand.h" | 
|  | #include "SkIntArray.h" | 
|  | #include "SkTDict.h" | 
|  | #include "SkTDStack.h" | 
|  |  | 
|  | class SkAnimateMaker; | 
|  |  | 
|  | class SkScriptEngine { | 
|  | public: | 
|  | enum Error { | 
|  | kNoError, | 
|  | kArrayIndexOutOfBounds, | 
|  | kCouldNotFindReferencedID, | 
|  | kDotOperatorExpectsObject, | 
|  | kErrorInArrrayIndex, | 
|  | kErrorInFunctionParameters, | 
|  | kExpectedArray, | 
|  | kExpectedBooleanExpression, | 
|  | kExpectedFieldName, | 
|  | kExpectedHex, | 
|  | kExpectedIntForConditionOperator, | 
|  | kExpectedNumber, | 
|  | kExpectedNumberForArrayIndex, | 
|  | kExpectedOperator, | 
|  | kExpectedToken, | 
|  | kExpectedTokenBeforeDotOperator, | 
|  | kExpectedValue, | 
|  | kHandleMemberFailed, | 
|  | kHandleMemberFunctionFailed, | 
|  | kHandleUnboxFailed, | 
|  | kIndexOutOfRange, | 
|  | kMismatchedArrayBrace, | 
|  | kMismatchedBrackets, | 
|  | kNoFunctionHandlerFound, | 
|  | kPrematureEnd, | 
|  | kTooManyParameters, | 
|  | kTypeConversionFailed, | 
|  | kUnterminatedString | 
|  | }; | 
|  |  | 
|  | enum SkOpType { | 
|  | kNoType, | 
|  | kInt = 1, | 
|  | kScalar = 2, | 
|  | kString = 4, | 
|  | kArray = 8, | 
|  | kObject = 16 | 
|  | //      kStruct = 32 | 
|  | }; | 
|  |  | 
|  | typedef bool (*_boxCallBack)(void* userStorage, SkScriptValue* result); | 
|  | typedef bool (*_functionCallBack)(const char* func, size_t len, SkTDArray<SkScriptValue>& params, | 
|  | void* userStorage, SkScriptValue* result); | 
|  | typedef bool (*_memberCallBack)(const char* member, size_t len, void* object, | 
|  | void* userStorage, SkScriptValue* result); | 
|  | typedef bool (*_memberFunctionCallBack)(const char* member, size_t len, void* object, | 
|  | SkTDArray<SkScriptValue>& params, void* userStorage, SkScriptValue* result); | 
|  | //  typedef bool (*_objectToStringCallBack)(void* object, void* userStorage, SkScriptValue* result); | 
|  | typedef bool (*_propertyCallBack)(const char* prop, size_t len, void* userStorage, SkScriptValue* result); | 
|  | typedef bool (*_unboxCallBack)(void* userStorage, SkScriptValue* result); | 
|  | SkScriptEngine(SkOpType returnType); | 
|  | ~SkScriptEngine(); | 
|  | void boxCallBack(_boxCallBack func, void* userStorage); | 
|  | bool convertTo(SkDisplayTypes , SkScriptValue* ); | 
|  | bool evaluateScript(const char** script, SkScriptValue* value); | 
|  | void forget(SkTypedArray* array); | 
|  | void functionCallBack(_functionCallBack func, void* userStorage); | 
|  | Error getError() const { return fError; } | 
|  | #ifdef SK_DEBUG | 
|  | bool getErrorString(SkString* err) const; | 
|  | #endif | 
|  | void memberCallBack(_memberCallBack , void* userStorage); | 
|  | void memberFunctionCallBack(_memberFunctionCallBack , void* userStorage); | 
|  | //  void objectToStringCallBack(_objectToStringCallBack , void* userStorage); | 
|  | void propertyCallBack(_propertyCallBack prop, void* userStorage); | 
|  | void track(SkTypedArray* array); | 
|  | void track(SkString* string); | 
|  | void unboxCallBack(_unboxCallBack func, void* userStorage); | 
|  | static bool ConvertTo(SkScriptEngine* , SkDisplayTypes toType, SkScriptValue* value); | 
|  | static SkScalar IntToScalar(int32_t ); | 
|  | static SkDisplayTypes ToDisplayType(SkOpType type); | 
|  | static SkOpType ToOpType(SkDisplayTypes type); | 
|  | static bool ValueToString(SkScriptValue value, SkString* string); | 
|  |  | 
|  | enum CallBackType { | 
|  | kBox, | 
|  | kFunction, | 
|  | kMember, | 
|  | kMemberFunction, | 
|  | //  kObjectToString, | 
|  | kProperty, | 
|  | kUnbox | 
|  | }; | 
|  |  | 
|  | struct UserCallBack { | 
|  | CallBackType fCallBackType; | 
|  | void* fUserStorage; | 
|  | union { | 
|  | _boxCallBack fBoxCallBack; | 
|  | _functionCallBack fFunctionCallBack; | 
|  | _memberCallBack fMemberCallBack; | 
|  | _memberFunctionCallBack fMemberFunctionCallBack; | 
|  | //      _objectToStringCallBack fObjectToStringCallBack; | 
|  | _propertyCallBack fPropertyCallBack; | 
|  | _unboxCallBack fUnboxCallBack; | 
|  | }; | 
|  | }; | 
|  |  | 
|  | enum SkOp { | 
|  | kUnassigned, | 
|  | kAdd, | 
|  | kAddInt = kAdd, | 
|  | kAddScalar, | 
|  | kAddString, // string concat | 
|  | kArrayOp, | 
|  | kBitAnd, | 
|  | kBitNot, | 
|  | kBitOr, | 
|  | kDivide, | 
|  | kDivideInt = kDivide, | 
|  | kDivideScalar, | 
|  | kElse, | 
|  | kEqual, | 
|  | kEqualInt = kEqual, | 
|  | kEqualScalar, | 
|  | kEqualString, | 
|  | kFlipOps, | 
|  | kGreaterEqual, | 
|  | kGreaterEqualInt = kGreaterEqual, | 
|  | kGreaterEqualScalar, | 
|  | kGreaterEqualString, | 
|  | kIf, | 
|  | kLogicalAnd, | 
|  | kLogicalNot, | 
|  | kLogicalOr, | 
|  | kMinus, | 
|  | kMinusInt = kMinus, | 
|  | kMinusScalar, | 
|  | kModulo, | 
|  | kModuloInt = kModulo, | 
|  | kModuloScalar, | 
|  | kMultiply, | 
|  | kMultiplyInt = kMultiply, | 
|  | kMultiplyScalar, | 
|  | kParen, | 
|  | kShiftLeft, | 
|  | kShiftRight,    // signed | 
|  | kSubtract, | 
|  | kSubtractInt = kSubtract, | 
|  | kSubtractScalar, | 
|  | kXor, | 
|  | kArtificialOp = 0x40 | 
|  | }; | 
|  |  | 
|  | enum SkOpBias { | 
|  | kNoBias, | 
|  | kTowardsNumber = 0, | 
|  | kTowardsString | 
|  | }; | 
|  |  | 
|  | protected: | 
|  |  | 
|  | struct SkOperatorAttributes { | 
|  | unsigned int fLeftType : 3; // SkOpType, but only lower values | 
|  | unsigned int fRightType : 3;     // SkOpType, but only lower values | 
|  | SkOpBias fBias : 1; | 
|  | }; | 
|  |  | 
|  | struct SkSuppress { // !!! could be compressed to a long | 
|  | SkOp fOperator; // operand which enabled suppression | 
|  | int fOpStackDepth; // depth when suppression operator was found | 
|  | SkBool8 fSuppress; // set if suppression happens now, as opposed to later | 
|  | SkBool8 fElse; // set on the : half of ? : | 
|  | }; | 
|  |  | 
|  | static const SkOperatorAttributes gOpAttributes[]; | 
|  | static const signed char gPrecedence[]; | 
|  | int arithmeticOp(char ch, char nextChar, bool lastPush); | 
|  | void commonCallBack(CallBackType type, UserCallBack& callBack, void* userStorage); | 
|  | bool convertParams(SkTDArray<SkScriptValue>&, const SkFunctionParamType* , | 
|  | int paramTypeCount); | 
|  | void convertToString(SkOperand& operand, SkDisplayTypes type) { | 
|  | SkScriptValue scriptValue; | 
|  | scriptValue.fOperand = operand; | 
|  | scriptValue.fType = type; | 
|  | convertTo(SkType_String, &scriptValue); | 
|  | operand = scriptValue.fOperand; | 
|  | } | 
|  | bool evaluateDot(const char*& script, bool suppressed); | 
|  | bool evaluateDotParam(const char*& script, bool suppressed, const char* field, size_t fieldLength); | 
|  | bool functionParams(const char** scriptPtr, SkTDArray<SkScriptValue>& params); | 
|  | bool handleArrayIndexer(const char** scriptPtr, bool suppressed); | 
|  | bool handleBox(SkScriptValue* value); | 
|  | bool handleFunction(const char** scriptPtr, bool suppressed); | 
|  | bool handleMember(const char* field, size_t len, void* object); | 
|  | bool handleMemberFunction(const char* field, size_t len, void* object, SkTDArray<SkScriptValue>& params); | 
|  | //  bool handleObjectToString(void* object); | 
|  | bool handleProperty(bool suppressed); | 
|  | bool handleUnbox(SkScriptValue* scriptValue); | 
|  | bool innerScript(const char** scriptPtr, SkScriptValue* value); | 
|  | int logicalOp(char ch, char nextChar); | 
|  | Error opError(); | 
|  | bool processOp(); | 
|  | void setAnimateMaker(SkAnimateMaker* maker) { fMaker = maker; } | 
|  | bool setError(Error , const char* pos); | 
|  | enum SkBraceStyle { | 
|  | //  kStructBrace, | 
|  | kArrayBrace, | 
|  | kFunctionBrace | 
|  | }; | 
|  |  | 
|  | #if 0 | 
|  | SkIntArray(SkBraceStyle) fBraceStack;       // curly, square, function paren | 
|  | SkIntArray(SkOp) fOpStack; | 
|  | SkIntArray(SkOpType) fTypeStack; | 
|  | SkTDOperandArray fOperandStack; | 
|  | SkTDArray<SkSuppress> fSuppressStack; | 
|  | #else | 
|  | SkTDStack<SkBraceStyle> fBraceStack;        // curly, square, function paren | 
|  | SkTDStack<SkOp> fOpStack; | 
|  | SkTDStack<SkOpType> fTypeStack; | 
|  | SkTDStack<SkOperand> fOperandStack; | 
|  | SkTDStack<SkSuppress> fSuppressStack; | 
|  | #endif | 
|  | SkAnimateMaker* fMaker; | 
|  | SkTDTypedArrayArray fTrackArray; | 
|  | SkTDStringArray fTrackString; | 
|  | const char* fToken; // one-deep stack | 
|  | size_t fTokenLength; | 
|  | SkTDArray<UserCallBack> fUserCallBacks; | 
|  | SkOpType fReturnType; | 
|  | Error fError; | 
|  | int fErrorPosition; | 
|  | private: | 
|  | friend class SkTypedArray; | 
|  | #ifdef SK_SUPPORT_UNITTEST | 
|  | public: | 
|  | static void UnitTest(); | 
|  | #endif | 
|  | }; | 
|  |  | 
|  | #ifdef SK_SUPPORT_UNITTEST | 
|  |  | 
|  | struct SkScriptNAnswer { | 
|  | const char* fScript; | 
|  | SkDisplayTypes fType; | 
|  | int32_t fIntAnswer; | 
|  | SkScalar fScalarAnswer; | 
|  | const char* fStringAnswer; | 
|  | }; | 
|  |  | 
|  | #endif | 
|  |  | 
|  | #endif // SkScript_DEFINED |