#ifndef _ESC_ESC_H_ #define _ESC_ESC_H_ #include NAMESPACE_UPP enum { ESC_VOID, ESC_NUMBER, ESC_ARRAY, ESC_MAP, ESC_LAMBDA }; String EscTypeName(int sv_type); struct EscEscape; class EscLambda; struct EscHandle; struct Esc; class EscValue : Moveable { struct RefCount { Atomic refcount; RefCount() { AtomicWrite(refcount, 1); } }; int type; mutable unsigned hash; struct EscMap; struct EscArray; union { double number; EscArray *array; EscMap *map; EscLambda *lambda; }; void Free(); void Assign(const EscValue& s); void InitString(const WString& w); Vector& CloneArray(); VectorMap& CloneMap(); static int total; static int max_total; public: static int GetTotalCount(); static void SetMaxTotalCount(int n); static int GetMaxTotalCount(); bool IsVoid() const { return type == ESC_VOID; } EscValue(); bool IsNumber() const { return type == ESC_NUMBER; } double GetNumber() const { return IsNumber() ? number : 0; } bool IsInt() const; int GetInt() const; EscValue(double n); bool IsArray() const { return type == ESC_ARRAY; } const Vector& GetArray() const; EscValue ArrayGet(int i) const; EscValue ArrayGet(int i, int n) const; bool ArraySet(int i, EscValue val); bool Replace(int i, int n, EscValue a); void SetEmptyArray(); void ArrayAdd(EscValue val); bool Append(EscValue a); operator WString() const; operator String() const { return operator WString().ToString(); } EscValue(const char *s) { InitString(WString(s)); } EscValue(const WString& s) { InitString(s); } EscValue(const String& s) { InitString(s.ToWString()); } bool IsMap() const { return type == ESC_MAP; } const VectorMap& GetMap() const; EscValue MapGet(EscValue key) const; void MapSet(EscValue key, EscValue value); void SetEmptyMap(); bool IsLambda() const { return type == ESC_LAMBDA; } const EscLambda& GetLambda() const; EscLambda& CreateLambda(); void Escape(const char *method, Callback1 escape); void Escape(const char *method, EscHandle *h, Callback1 escape); bool HasNumberField(const char *id) const; int GetFieldInt(const char *id) const; int GetType() const { return type; } String GetTypeName() const { return UPP::EscTypeName(type); } int GetCount() const; unsigned GetHashValue() const; bool operator==(const EscValue& a) const; bool operator!=(const EscValue& a) const { return !(*this == a); } String ToString(int maxlen = INT_MAX, int indent_step = 4, bool hex = false, int indent = 0) const; EscValue& operator=(const EscValue& s); EscValue(const EscValue& src); ~EscValue(); }; struct EscValue::EscArray : EscValue::RefCount { Vector array; void Retain() { AtomicInc(refcount); } void Release() { if(AtomicDec(refcount) == 0) delete this; } }; struct EscValue::EscMap : EscValue::RefCount { VectorMap map; int count; void Retain() { AtomicInc(refcount); } void Release() { if(AtomicDec(refcount) == 0) delete this; } EscMap() { count = 0; } }; struct EscHandle { Atomic refcount; void Retain() { AtomicInc(refcount); } void Release() { if(AtomicDec(refcount) == 0) delete this; } EscHandle() { AtomicWrite(refcount, 0); } virtual ~EscHandle() {} }; class EscLambda { Atomic refcount; void Retain() { AtomicInc(refcount); } void Release() { if(AtomicDec(refcount) == 0) delete this; } EscLambda() { AtomicWrite(refcount, 1); varargs = false; handle = NULL; } ~EscLambda() { if(handle) handle->Release(); } friend class EscValue; public: Vector arg; Vector def; Vector inout; String code; EscHandle *handle; Callback1 escape; bool varargs; String filename; int line; private: EscLambda(const EscLambda&); void operator=(const EscLambda&); }; template <> inline unsigned GetHashValue(const EscValue& v) { return v.GetHashValue(); } bool IsTrue(const EscValue& a); void SkipBlock(CParser& p); EscValue ReadLambda(CParser& p); EscValue ReadLambda(const char *s); struct Esc : public CParser { struct SRVal : Moveable { EscValue *lval; EscValue rval; EscValue sbs; SRVal() { lval = NULL; } SRVal(const EscValue& v) { lval = NULL; rval = v; } SRVal(double n) { lval = NULL; rval = n; } }; ArrayMap& global; EscValue self; ArrayMap var; int skipexp; int loop; bool no_break, no_return; int& op_limit; int r_stack_level; EscValue return_value; static int stack_level; void OutOfMemory(); void TestLimit(); double DoCompare(const EscValue& a, const EscValue& b, const char *op); double DoCompare(const SRVal& a, const char *op); String ReadName(); EscValue ExecuteLambda(const String& id, EscValue lambda, SRVal self, Vector& arg); void Assign(EscValue& val, const Vector& sbs, int si, const EscValue& src); EscValue Get(const SRVal& val); void Assign(const SRVal& val, const EscValue& src); EscValue GetExp(); double Number(const EscValue& a, const char *oper); int Int(const EscValue& a, const char *oper); double Number(const SRVal& a, const char *oper); int Int(const SRVal& a, const char *oper); EscValue MulArray(EscValue array, EscValue times); void Subscript(SRVal& r, SRVal _self, String id); void Subscript(SRVal& r); void Term(SRVal& r); void Unary(SRVal& r); void Mul(SRVal& r); void Add(SRVal& r); void Shift(SRVal& r); void Compare(SRVal& r); void Equal(SRVal& r); void BinAnd(SRVal& r); void BinXor(SRVal& r); void BinOr(SRVal& r); void And(SRVal& r); void Or(SRVal& r); void Cond(SRVal& r); void Assign(SRVal& r); void Exp(SRVal& r); void SkipTerm(); void SkipStatement(); void SkipExp(); bool PCond(); void FinishSwitch(); void DoStatement(); void Run(); Esc(ArrayMap& global, const char *s, int& oplimit, const String& fn, int line = 1) : CParser(s, fn, line), global(global), op_limit(oplimit) { r_stack_level = stack_level; skipexp = false; } ~Esc() { stack_level = r_stack_level; } }; struct EscEscape { Esc& esc; EscValue self; Array& arg; EscValue ret_val; String id; EscValue& operator[](int i) { return arg[i]; } int GetCount() const { return arg.GetCount(); } void operator=(const EscValue& v) { ret_val = v; } operator EscValue&() { return ret_val; } void ThrowError(const char *s) { esc.ThrowError(s); } String DumpType(int i); String InCall(); void CheckNumber(int i); void CheckArray(int i); void CheckMap(int i); double Number(int i); int Int(int i); EscEscape(Esc& esc, EscValue self, Array& arg) : esc(esc), self(self), arg(arg) {} }; void Escape(ArrayMap& globals, const char *function, void (*escape)(EscEscape& e)); void Escape(ArrayMap& globals, const char *function, Callback1 escape); void Scan(ArrayMap& global, const char *code, const char *filename = ""); void StdLib(ArrayMap& global); void LambdaArgs(CParser& p, EscLambda& l); EscValue Execute(ArrayMap& global, EscValue *self, const EscValue& lambda, Vector& arg, int oplimit = 50000); EscValue Execute(ArrayMap& global, EscValue *self, const char *name, Vector& arg, int oplimit = 50000); EscValue Execute(ArrayMap& global, const char *name, int oplimit = 50000); EscValue Evaluatex(const char *expression, ArrayMap& global, int oplimit = 50000); EscValue Evaluate(const char *expression, ArrayMap& global, int oplimit = 50000); EscValue EscFromStdValue(const Value& v); Value StdValueFromEsc(const EscValue& v); void StdValueLib(ArrayMap& global); bool IsDate(const EscValue& v); bool IsTime(const EscValue& v); String Expand(const String& doc, ArrayMap& global, int oplimit = 50000, String (*format)(const Value& v) = StdFormat); END_UPP_NAMESPACE #endif