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