diff options
Diffstat (limited to 'src/animator/SkScript2.h')
-rw-r--r-- | src/animator/SkScript2.h | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/src/animator/SkScript2.h b/src/animator/SkScript2.h new file mode 100644 index 0000000..4d8bd8c --- /dev/null +++ b/src/animator/SkScript2.h @@ -0,0 +1,285 @@ +#ifndef SkScript2_DEFINED +#define SkScript2_DEFINED + +#include "SkOperand2.h" +#include "SkStream.h" +#include "SkTDArray.h" +#include "SkTDArray_Experimental.h" +#include "SkTDict.h" +#include "SkTDStack.h" + +typedef SkLongArray(SkString*) SkTDStringArray; + +class SkAnimateMaker; +class SkScriptCallBack; + +class SkScriptEngine2 { +public: + enum Error { + kNoError, + kArrayIndexOutOfBounds, + kCouldNotFindReferencedID, + kFunctionCallFailed, + kMemberOpFailed, + kPropertyOpFailed + }; + + enum Attrs { + kConstant, + kVariable + }; + + SkScriptEngine2(SkOperand2::OpType returnType); + ~SkScriptEngine2(); + bool convertTo(SkOperand2::OpType , SkScriptValue2* ); + bool evaluateScript(const char** script, SkScriptValue2* value); + void forget(SkOpArray* array); + Error getError() { return fError; } + SkOperand2::OpType getReturnType() { return fReturnType; } + void track(SkOpArray* array) { + SkASSERT(fTrackArray.find(array) < 0); + *fTrackArray.append() = array; } + void track(SkString* string) { + SkASSERT(fTrackString.find(string) < 0); + *fTrackString.append() = string; + } + static bool ConvertTo(SkScriptEngine2* , SkOperand2::OpType toType, SkScriptValue2* value); + static SkScalar IntToScalar(int32_t ); + static bool ValueToString(const SkScriptValue2& value, SkString* string); + + enum Op { // used by tokenizer attribute table + kUnassigned, + kAdd, + kBitAnd, + kBitNot, + kBitOr, + kDivide, + kEqual, + kFlipOps, + kGreaterEqual, + kLogicalAnd, + kLogicalNot, + kLogicalOr, + kMinus, + kModulo, + kMultiply, + kShiftLeft, + kShiftRight, // signed + kSubtract, + kXor, +// following not in attribute table + kArrayOp, + kElse, + kIf, + kParen, + kLastLogicalOp, + kArtificialOp = 0x20 + }; + + enum TypeOp { // generated by tokenizer + kNop, // should never get generated + kAccumulatorPop, + kAccumulatorPush, + kAddInt, + kAddScalar, + kAddString, // string concat + kArrayIndex, + kArrayParam, + kArrayToken, + kBitAndInt, + kBitNotInt, + kBitOrInt, + kBoxToken, + kCallback, + kDivideInt, + kDivideScalar, + kDotOperator, + kElseOp, + kEnd, + kEqualInt, + kEqualScalar, + kEqualString, + kFunctionCall, + kFlipOpsOp, + kFunctionToken, + kGreaterEqualInt, + kGreaterEqualScalar, + kGreaterEqualString, + kIfOp, + kIntToScalar, + kIntToScalar2, + kIntToString, + kIntToString2, + kIntegerAccumulator, + kIntegerOperand, + kLogicalAndInt, + kLogicalNotInt, + kLogicalOrInt, + kMemberOp, + kMinusInt, + kMinusScalar, + kModuloInt, + kModuloScalar, + kMultiplyInt, + kMultiplyScalar, + kPropertyOp, + kScalarAccumulator, + kScalarOperand, + kScalarToInt, + kScalarToInt2, + kScalarToString, + kScalarToString2, + kShiftLeftInt, + kShiftRightInt, // signed + kStringAccumulator, + kStringOperand, + kStringToInt, + kStringToScalar, + kStringToScalar2, + kStringTrack, + kSubtractInt, + kSubtractScalar, + kToBool, + kUnboxToken, + kUnboxToken2, + kXorInt, + kLastTypeOp + }; + + enum OpBias { + kNoBias, + kTowardsNumber = 0, + kTowardsString + }; + +protected: + + enum BraceStyle { + // kStructBrace, + kArrayBrace, + kFunctionBrace + }; + + enum AddTokenRegister { + kAccumulator, + kOperand + }; + + enum ResultIsBoolean { + kResultIsNotBoolean, + kResultIsBoolean + }; + + struct OperatorAttributes { + unsigned int fLeftType : 3; // SkOpType union, but only lower values + unsigned int fRightType : 3; // SkOpType union, but only lower values + OpBias fBias : 1; + ResultIsBoolean fResultIsBoolean : 1; + }; + + struct Branch { + Branch() { + } + + Branch(Op op, int depth, unsigned offset) : fOffset(offset), fOpStackDepth(depth), fOperator(op), + fPrimed(kIsNotPrimed), fDone(kIsNotDone) { + } + + enum Primed { + kIsNotPrimed, + kIsPrimed + }; + + enum Done { + kIsNotDone, + kIsDone, + }; + + unsigned fOffset : 16; // offset in generated stream where branch needs to go + int fOpStackDepth : 7; // depth when operator was found + Op fOperator : 6; // operand which generated branch + mutable Primed fPrimed : 1; // mark when next instruction generates branch + Done fDone : 1; // mark when branch is complete + void prime() { fPrimed = kIsPrimed; } + void resolve(SkDynamicMemoryWStream* , size_t offset); + }; + + static const OperatorAttributes gOpAttributes[]; + static const signed char gPrecedence[]; + static const TypeOp gTokens[]; + void addToken(TypeOp ); + void addTokenConst(SkScriptValue2* , AddTokenRegister , SkOperand2::OpType , TypeOp ); + void addTokenInt(int ); + void addTokenScalar(SkScalar ); + void addTokenString(const SkString& ); + void addTokenValue(const SkScriptValue2& , AddTokenRegister ); + int arithmeticOp(char ch, char nextChar, bool lastPush); + bool convertParams(SkTDArray<SkScriptValue2>* , + const SkOperand2::OpType* paramTypes, int paramTypeCount); + void convertToString(SkOperand2* operand, SkOperand2::OpType type) { + SkScriptValue2 scriptValue; + scriptValue.fOperand = *operand; + scriptValue.fType = type; + convertTo(SkOperand2::kString, &scriptValue); + *operand = scriptValue.fOperand; + } + bool evaluateDot(const char*& script); + bool evaluateDotParam(const char*& script, const char* field, size_t fieldLength); + bool functionParams(const char** scriptPtr, SkTDArray<SkScriptValue2>* params); + size_t getTokenOffset(); + SkOperand2::OpType getUnboxType(SkOperand2 scriptValue); + bool handleArrayIndexer(const char** scriptPtr); + bool handleFunction(const char** scriptPtr); + bool handleMember(const char* field, size_t len, void* object); + bool handleMemberFunction(const char* field, size_t len, void* object, + SkTDArray<SkScriptValue2>* params); + bool handleProperty(); + bool handleUnbox(SkScriptValue2* scriptValue); + bool innerScript(const char** scriptPtr, SkScriptValue2* value); + int logicalOp(char ch, char nextChar); + void processLogicalOp(Op op); + bool processOp(); + void resolveBranch(Branch& ); +// void setAnimateMaker(SkAnimateMaker* maker) { fMaker = maker; } + SkDynamicMemoryWStream fStream; + SkDynamicMemoryWStream* fActiveStream; + SkTDStack<BraceStyle> fBraceStack; // curly, square, function paren + SkTDStack<Branch> fBranchStack; // logical operators, slot to store forward branch + SkLongArray(SkScriptCallBack*) fCallBackArray; + SkTDStack<Op> fOpStack; + SkTDStack<SkScriptValue2> fValueStack; +// SkAnimateMaker* fMaker; + SkLongArray(SkOpArray*) fTrackArray; + SkTDStringArray fTrackString; + const char* fToken; // one-deep stack + size_t fTokenLength; + SkOperand2::OpType fReturnType; + Error fError; + SkOperand2::OpType fAccumulatorType; // tracking for code generation + SkBool fBranchPopAllowed; + SkBool fConstExpression; + SkBool fOperandInUse; +private: +#ifdef SK_DEBUG +public: + void decompile(const unsigned char* , size_t ); + static void UnitTest(); + static void ValidateDecompileTable(); +#endif +}; + +#ifdef SK_DEBUG + +struct SkScriptNAnswer2 { + const char* fScript; + SkOperand2::OpType fType; + int32_t fIntAnswer; + SkScalar fScalarAnswer; + const char* fStringAnswer; +}; + +#endif + + +#endif // SkScript2_DEFINED + |