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
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
18class SkAnimateMaker;
19
20class SkScriptEngine {
21public:
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);
66    typedef bool (*_memberCallBack)(const char* member, size_t len, void* object,
67        void* userStorage, SkScriptValue* result);
68    typedef bool (*_memberFunctionCallBack)(const char* member, size_t len, void* object,
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    };
172
173protected:
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;
246private:
247    friend class SkTypedArray;
248#ifdef SK_SUPPORT_UNITTEST
249public:
250    static void UnitTest();
251#endif
252};
253
254#ifdef SK_SUPPORT_UNITTEST
255
256struct 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
267