| /* | |
| * 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 |