using System; using System.IO; using Newtonsoft.Json.Linq; namespace tlang { public static class TObjectExtensions { public static bool TryGetFieldOrProperty(this TObject obj,string key,out TObject val) { val=TObject.Uninit; var dict = obj as TDictionary; if(dict != null) { if(dict.MemberExists($"get{key}")) { var p= dict[$"get{key}"] as ICallable; if(p != null) { val = p.Call(); return true; } } if(dict.MemberExists(key)) { val = dict[key]; return true; } } return false; } public static string GetExtObjType(this TObject obj) { var dict = obj as TDictionary; if(dict != null) { if(!dict.MemberExists("_extobjtype")) return ""; var _extobjtype=dict["_extobjtype"] as TString; if(_extobjtype != null) return _extobjtype.Value; } return ""; } public static TDictionary ToTObject(this TimeSpan ts) { var dict = TObject.Dictionary(); dict["_extobjtype"] ="timespan"; dict["h"] = ts.Hours; dict["m"] = ts.Minutes; dict["s"] = ts.Seconds; dict["totalseconds"] = ts.TotalSeconds; return dict; } public static bool TryGetTimeSpan(this TObject obj,out TimeSpan ts) { ts=TimeSpan.Zero; var dict = obj as TDictionary; if(dict != null) { if(dict.GetExtObjType() != "timespan") return false; if(obj.TryGetFieldOrProperty("totalseconds",out var v)) { var _totalSecond = v as TNumber; double totalSeconds = 0; if(_totalSecond != null) totalSeconds = _totalSecond.Value; ts = TimeSpan.FromSeconds(totalSeconds); return true; } if(obj.TryGetFieldOrProperty("h",out var h) && obj.TryGetFieldOrProperty("m",out var m) && obj.TryGetFieldOrProperty("s",out var s)) { var _h = h as TNumber; var _m = m as TNumber; var _s = s as TNumber; int __h=0; int __m=0; int __s=0; if(_h != null) __h = (int)_h.Value; if(_m != null) __m = (int)_m.Value; if(_s != null) __s = (int)_s.Value; ts=new TimeSpan(__h,__m,__s); return true; } } return false; } } public abstract class TObject { public static explicit operator bool(TObject obj) { return obj.AsBoolean; } public static implicit operator TObject(double dbl) { return Number(dbl); } public static implicit operator TObject(Func o) { return new TExternalMethod(o); } public static implicit operator TObject(string str) { return String(str); } public static implicit operator TObject(bool b) { return Boolean(b); } public static implicit operator TObject(int n) { return Number(n); } public static implicit operator TObject(long n) { return Number(n); } public static implicit operator TObject(short n) { return Number(n); } public static implicit operator TObject(TimeSpan ts) { return ts.ToTObject(); } public static implicit operator TObject(float f) { return Number(f); } public static implicit operator TObject(ushort s) { return Number(s); } public static implicit operator TObject(uint s) { return Number(s); } public static implicit operator TObject(ulong l) { return Number(l); } public static implicit operator TObject(char c) { return Char(c); } public static implicit operator TObject(Stream strm) { return Parser.CreateStream(strm); } public static implicit operator TObject(TObject[] array) { var a=Array(); a.Items.AddRange(array); return a; } public static implicit operator TObject(byte b) { return Number(b); } public static implicit operator TObject(sbyte b) { return Number(b); } public static TObject FromToken(JToken token) { var obj = token as JObject; var val = token as JValue; var arr = token as JArray; if(obj != null) { var dict = Dictionary(); foreach(var item in obj) { dict.SetMember(item.Key,FromToken(item.Value)); } return dict; } if(arr != null) { var array = Array(); foreach(var item in arr) { array.Items.Add(FromToken(item)); } return array; } if(val != null) { if(val.Type == JTokenType.Integer) { return Number(val.ToObject()); } if(val.Type == JTokenType.Float) { return Number(val.ToObject()); } if(val.Type == JTokenType.String) { return String(val.ToObject()); } if(val.Type == JTokenType.Null) { return Null; } if(val.Type == JTokenType.Undefined) { return Uninit; } if(val.Type == JTokenType.TimeSpan) { //h:m:s var tdict=Dictionary(); tdict["_extobjtype"] = String("timespan"); } if(val.Type == JTokenType.Boolean) { return TObject.Boolean(val.ToObject()); } } return Uninit; } public abstract JToken AsToken(); public override string ToString() { return "TObject"; } public abstract bool AsBoolean {get;} public static TObject Uninit => new TUninit(); public static TObject Null => new TNull(); public static TObject True => new TBoolean(true); public static TObject False => new TBoolean(false); public static TChar Char(char c) { return new TChar(c); } public static TNumber Number(double dbl) { return new TNumber(dbl); } public static TString String(string text) { return new TString(text); } public static TDictionary Dictionary() { return new TDictionary(); } public static TArray Array(int bufferSize=0) { return new TArray(bufferSize); } public static TObject Boolean(bool v) { return new TBoolean(v); } } }