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