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