
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#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
