
/*
 * 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, size_t offset)
            : fOffset(SkToU16(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
