using System; using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; using PorygonSharp.UserData; namespace PorygonSharp.EvalValues { public static class EvalValueCreator { public static EvalValue CreateValue(object o) { if (o == null) return new EvalValue(CreateNilEvalValue()); var type = o.GetType(); if (type.IsEnum && !type.IsGenericParameter) { var typeHash = UserDataHandler.GetTypeId(type); var ptr = ObjectEvalValueHandler.GetObjectPtr(o); return new EvalValue(CreateUserDataEvalValue(typeHash, ptr)); } var typeCode = Type.GetTypeCode(type); switch (typeCode) { case TypeCode.Boolean: return new EvalValue(CreateBoolEvalValue((bool)o)); case TypeCode.Byte: case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: return new EvalValue(CreateIntegerEvalValue(Convert.ToInt64(o))); case TypeCode.Char: case TypeCode.String: return new EvalValue(CreateStringEvalValue(o.ToString())); case TypeCode.Decimal: case TypeCode.Double: case TypeCode.Single: return new EvalValue(CreateFloatEvalValue(Convert.ToDouble(o))); case TypeCode.Object: if (typeof(IList).IsAssignableFrom(type)) return CreateListEvalValue((IList)o, type); if (!UserDataHandler.IsTypeRegistered(type) && !UserDataHandler.TryResolveType(type)) { throw new Exception($"Type is not registered for use: {type.FullName}"); } var typeHash = UserDataHandler.GetTypeId(type); var ptr = ObjectEvalValueHandler.GetObjectPtr(o); return new EvalValue(CreateUserDataEvalValue(typeHash, ptr)); default: throw new Exception($"Type {type} is not currently available as EvalValue"); } } public static EvalValue FunctionEvalValue(IntPtr func, IntPtr parent) { return new EvalValue(CreateFunctionEvalValue(func, parent)); } private static EvalValue CreateListEvalValue(IList collection, Type type) { var helper = new ListEvalValue(collection, type); var ptr = CreateCollectionValue(IntPtr.Zero, helper.ParentCollection, helper.Getter, helper.Setter, helper.GetIterator); return new EvalValue(ptr); } [DllImport("PorygonLang", EntryPoint = "CreateNilEvalValue",CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr CreateNilEvalValue(); [DllImport("PorygonLang", EntryPoint = "CreateIntegerEvalValue",CallingConvention = CallingConvention.Cdecl)] internal static extern IntPtr CreateIntegerEvalValue(long l); [DllImport("PorygonLang", EntryPoint = "CreateFloatEvalValue",CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr CreateFloatEvalValue(double d); [DllImport("PorygonLang", EntryPoint = "CreateBoolEvalValue",CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr CreateBoolEvalValue(bool b); [DllImport("PorygonLang", EntryPoint = "CreateStringEvalValue",CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr CreateStringEvalValue([MarshalAs(UnmanagedType.LPWStr)]string s); [DllImport("PorygonLang", EntryPoint = "CreateUserDataEvalValue",CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr CreateUserDataEvalValue(uint typeHash, IntPtr obj); [DllImport("PorygonLang", EntryPoint = "CreateFunctionEvalValue",CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr CreateFunctionEvalValue(IntPtr func, IntPtr parent); [DllImport("PorygonLang", EntryPoint = "CreateCollectionValue", CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr CreateCollectionValue(IntPtr type, IntPtr parent, IntPtr getter, IntPtr setter, IntPtr iterator); } }