
/*
 * 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

