blob: aa8d9a30c8a709d155cc783aea595753fc2cfd00 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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
reed@android.com8a1c16f2008-12-17 15:59:43 +00009
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);
rmistry@google.comd6176b02012-08-23 18:14:13 +000066 typedef bool (*_memberCallBack)(const char* member, size_t len, void* object,
reed@android.com8a1c16f2008-12-17 15:59:43 +000067 void* userStorage, SkScriptValue* result);
rmistry@google.comd6176b02012-08-23 18:14:13 +000068 typedef bool (*_memberFunctionCallBack)(const char* member, size_t len, void* object,
reed@android.com8a1c16f2008-12-17 15:59:43 +000069 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 };
rmistry@google.comd6176b02012-08-23 18:14:13 +0000172
reed@android.com8a1c16f2008-12-17 15:59:43 +0000173protected:
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