From 6449f7c9421503988e238efdfdf80cce5d87c862 Mon Sep 17 00:00:00 2001 From: G3Kappa Date: Wed, 17 Jan 2024 07:32:07 +0100 Subject: [PATCH] ergo-driven dialogues --- Ergo/Lang/Types/ErgoTypeResolver.cs | 27 +++++++++++++++++++++------ Ergo/Lang/Types/TermMarshall.cs | 10 ++++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/Ergo/Lang/Types/ErgoTypeResolver.cs b/Ergo/Lang/Types/ErgoTypeResolver.cs index b5317b07..597e1493 100644 --- a/Ergo/Lang/Types/ErgoTypeResolver.cs +++ b/Ergo/Lang/Types/ErgoTypeResolver.cs @@ -214,16 +214,31 @@ public virtual object FromTerm(ITerm t) } else { - if (Type.IsArray && t is List list) + if (t is List list) { - var instance = Array.CreateInstance(Type.GetElementType(), list.Contents.Length); - for (var i = 0; i < list.Contents.Length; i++) + if (Type.IsArray) { - var obj = TermMarshall.FromTerm(list.Contents[i], Type.GetElementType(), Marshalling); - instance.SetValue(obj, i); + var instance = Array.CreateInstance(Type.GetElementType(), list.Contents.Length); + for (var i = 0; i < list.Contents.Length; i++) + { + var obj = TermMarshall.FromTerm(list.Contents[i], Type.GetElementType(), Marshalling); + instance.SetValue(obj, i); + } + + return instance; } + else if (Type.GetInterfaces().FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>)) is { } iList) + { + var instance = (IList)Activator.CreateInstance(Type); + for (var i = 0; i < list.Contents.Length; i++) + { + var obj = TermMarshall.FromTerm(list.Contents[i], Type.GetElementType(), Marshalling); + instance.Add(obj); + } - return instance; + return instance; + } + else throw new NotSupportedException(); } else { diff --git a/Ergo/Lang/Types/TermMarshall.cs b/Ergo/Lang/Types/TermMarshall.cs index e5494e5c..77abbae0 100644 --- a/Ergo/Lang/Types/TermMarshall.cs +++ b/Ergo/Lang/Types/TermMarshall.cs @@ -6,6 +6,8 @@ namespace Ergo.Lang; public sealed class TermMarshall { + public readonly record struct Unmarshalled(object Value); + internal static readonly ConcurrentDictionary AttributeCache = new(); internal static readonly ConcurrentDictionary PositionalResolvers = new(); internal static readonly ConcurrentDictionary NamedResolvers = new(); @@ -54,6 +56,8 @@ private static TermAttribute GetAttribute(Type type) public static ITerm ToTerm(T value, Maybe functor = default, Maybe mode = default, TermMarshallingContext ctx = null) { + if (value is Unmarshalled) + return new Atom(value); if (typeof(T) == typeof(ITerm)) return (ITerm)value; ctx ??= new(); @@ -69,6 +73,8 @@ public static ITerm ToTerm(T value, Maybe functor = default, Maybe functor = default, Maybe mode = default, TermMarshallingContext ctx = null) { + if (value is Unmarshalled) + return new Atom(value); if (type == typeof(ITerm)) return (ITerm)value; ctx ??= new(); @@ -101,6 +107,8 @@ internal static object Transform(object o) } public static T FromTerm(ITerm value, T _ = default, Maybe mode = default) { + if (value is Atom { Value: Unmarshalled { Value: var v } }) + return (T)v; if (typeof(T) == typeof(ITerm)) return (T)value; var interfaceType = typeof(IErgoMarshalling<>).MakeGenericType(typeof(T)); @@ -116,6 +124,8 @@ public static T FromTerm(ITerm value, T _ = default, Maybe m } public static object FromTerm(ITerm value, Type type, Maybe mode = default) { + if (value is Atom { Value: Unmarshalled { Value: var v } }) + return v; if (type == typeof(ITerm)) return value; var interfaceType = typeof(IErgoMarshalling<>).MakeGenericType(type);