From 4ee43663fcc9c1c070caf45ebd10e7143179cb0c Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Fri, 31 May 2024 08:48:07 +0300 Subject: [PATCH 01/69] add develop --- SLThree/docs/versions/develop | 1 + slt/docs/versions/develop | 1 + 2 files changed, 2 insertions(+) create mode 100644 SLThree/docs/versions/develop create mode 100644 slt/docs/versions/develop diff --git a/SLThree/docs/versions/develop b/SLThree/docs/versions/develop new file mode 100644 index 0000000..be587a1 --- /dev/null +++ b/SLThree/docs/versions/develop @@ -0,0 +1 @@ +------ Changes ------ [~.~.~] \ No newline at end of file diff --git a/slt/docs/versions/develop b/slt/docs/versions/develop new file mode 100644 index 0000000..be587a1 --- /dev/null +++ b/slt/docs/versions/develop @@ -0,0 +1 @@ +------ Changes ------ [~.~.~] \ No newline at end of file From 466b94f4574046a4a36f721c6d09a00b8a0bc9c3 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Fri, 31 May 2024 21:15:26 +0300 Subject: [PATCH 02/69] new Wrapper --- SLThree/ExecutionContext.cs | 12 +- SLThree/Extensions/SLThreeExtensions.cs | 2 + SLThree/LocalVariablesContainer.cs | 23 +- SLThree/NewWrapper.cs | 711 ++++++++++++++++++++++++ SLThree/SLThree.csproj | 2 +- SLThree/docs/versions/develop | 5 +- slt/Program.cs | 4 +- 7 files changed, 739 insertions(+), 20 deletions(-) create mode 100644 SLThree/NewWrapper.cs diff --git a/SLThree/ExecutionContext.cs b/SLThree/ExecutionContext.cs index 83b0eec..e9333dd 100644 --- a/SLThree/ExecutionContext.cs +++ b/SLThree/ExecutionContext.cs @@ -44,25 +44,25 @@ static ExecutionContext() } - public ExecutionContext(bool assign_to_global, bool create_private = true) + public ExecutionContext(bool assign_to_global, bool create_private = true, LocalVariablesContainer localVariables = null) { + LocalVariables = localVariables ?? new LocalVariablesContainer(); @this = new ContextWrap(this); wrap = new ContextWrap(this); if (create_private) @private = new ContextWrap(new ExecutionContext(this, false)); if (assign_to_global) SuperContext = global.Context; } - - public ExecutionContext(ExecutionContext context, bool create_private = true) + public ExecutionContext(ExecutionContext context, bool create_private = true, LocalVariablesContainer localVariables = null) { + LocalVariables = localVariables ?? new LocalVariablesContainer(); @this = new ContextWrap(this); wrap = new ContextWrap(this); if (create_private) @private = new ContextWrap(new ExecutionContext(this, false)); if (context != null) SuperContext = context; } - - public ExecutionContext() : this(true, true) { } + public ExecutionContext() : this(true, true, null) { } public ContextWrap @this; @@ -112,6 +112,6 @@ public void DefaultEnvironment() } - public readonly LocalVariablesContainer LocalVariables = new LocalVariablesContainer(); + public readonly LocalVariablesContainer LocalVariables; } } diff --git a/SLThree/Extensions/SLThreeExtensions.cs b/SLThree/Extensions/SLThreeExtensions.cs index b55ad43..6d0c36e 100644 --- a/SLThree/Extensions/SLThreeExtensions.cs +++ b/SLThree/Extensions/SLThreeExtensions.cs @@ -31,5 +31,7 @@ public static string[] ReadStrings(this Stream stream) return sr.ReadToEnd().Split(new string[1] { Environment.NewLine }, StringSplitOptions.None); } } + public static string Representation(this ExecutionContext context) => sys.slt.context_repr(context.wrap); + public static string Representation(this ContextWrap context) => sys.slt.context_repr(context); } } diff --git a/SLThree/LocalVariablesContainer.cs b/SLThree/LocalVariablesContainer.cs index bab6cc7..d4fb892 100644 --- a/SLThree/LocalVariablesContainer.cs +++ b/SLThree/LocalVariablesContainer.cs @@ -6,20 +6,23 @@ namespace SLThree { public class LocalVariablesContainer { - public LocalVariablesContainer() + public LocalVariablesContainer(int default_size = 8, Dictionary names = null) { - + Variables = new object[default_size]; + NamedIdentificators = names ?? new Dictionary(); + current = NamedIdentificators.Count; } internal int current = 0; - internal object[] Variables = new object[8]; - public Dictionary NamedIdenificators = new Dictionary(); + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)] + public object[] Variables; + public Dictionary NamedIdentificators; - public Dictionary GetAsDictionary() => NamedIdenificators.ToDictionary(x => x.Key, x => Variables[x.Value]); + public Dictionary GetAsDictionary() => NamedIdentificators.ToDictionary(x => x.Key, x => Variables[x.Value]); public void ClearNulls() { - NamedIdenificators = NamedIdenificators.Where(x => Variables[x.Value] != null).ToDictionary(x => x.Key, x => x.Value); + NamedIdentificators = NamedIdentificators.Where(x => Variables[x.Value] != null).ToDictionary(x => x.Key, x => x.Value); } //[MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -37,13 +40,13 @@ public void FillArguments(Method method, object[] args) if (current <= args.Length) current = args.Length; args.CopyTo(Variables, 0); for (var i = 0; i < args.Length; i++) - NamedIdenificators[method.ParamNames[i]] = i; + NamedIdentificators[method.ParamNames[i]] = i; } //[MethodImpl(MethodImplOptions.AggressiveInlining)] public int SetValue(string name, object value) { - if (NamedIdenificators.TryGetValue(name, out var id)) + if (NamedIdentificators.TryGetValue(name, out var id)) { Variables[id] = value; return id; @@ -52,7 +55,7 @@ public int SetValue(string name, object value) { if (current >= Variables.Length) Expand(); Variables[current] = value; - NamedIdenificators[name] = current; + NamedIdentificators[name] = current; return current++; } } @@ -65,7 +68,7 @@ public void SetValue(int index, object value) //[MethodImpl(MethodImplOptions.AggressiveInlining)] public (object, int) GetValue(string name) { - if (NamedIdenificators.TryGetValue(name, out var x)) + if (NamedIdentificators.TryGetValue(name, out var x)) { return (Variables[x], x); } diff --git a/SLThree/NewWrapper.cs b/SLThree/NewWrapper.cs new file mode 100644 index 0000000..394537e --- /dev/null +++ b/SLThree/NewWrapper.cs @@ -0,0 +1,711 @@ +using SLThree.Extensions; +using SLThree.sys; +using System; +using System.CodeDom; +using System.Collections; +using System.Collections.Generic; +using System.Dynamic; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace SLThree +{ + public static class NewWrapper + { + #region Type Setting + internal static Type generic_list = typeof(List).GetGenericTypeDefinition(); + internal static Type generic_dict = typeof(Dictionary).GetGenericTypeDefinition(); + internal static Type type_ituple = typeof(ITuple); + public static bool HasRecast(Type type) + { + if (type.IsArray) return true; + if (type.IsGenericType) + { + if (type == generic_list) return true; + if (type == generic_dict) return true; + } + var interfaces = type.GetInterfaces(); + if (interfaces.Contains(type_ituple)) return true; + return false; + } + public static object[] TupleToArray(ITuple tuple) + { + var ret = new object[tuple.Length]; + for (var i = 0; i < ret.Length; i++) + ret[i] = tuple[i]; + return ret; + } + public static object UnwrapCast(Type type_to_cast, object o) + { + if (type_to_cast.IsArray && o is object[] obj_array) + { + var gga = type_to_cast.GetElementType(); + var ret = Array.CreateInstance(gga, obj_array.Length); + if (HasRecast(gga)) + { + for (var i = 0; i < obj_array.Length; i++) + ret.SetValue(UnwrapCast(gga, obj_array[i]), i); + } + else + { + for (var i = 0; i < obj_array.Length; i++) + ret.SetValue(obj_array[i], i); + } + return ret; + } + else if (type_to_cast.IsArray && o is List obj_list) + { + var gga = type_to_cast.GetElementType(); + var ret = Array.CreateInstance(gga, obj_list.Count); + if (HasRecast(gga)) + { + for (var i = 0; i < obj_list.Count; i++) + ret.SetValue(UnwrapCast(gga, obj_list[i]), i); + } + else + { + for (var i = 0; i < obj_list.Count; i++) + ret.SetValue(obj_list[i], i); + } + return ret; + } + if (type_to_cast.IsGenericType) + { + var gen_type = type_to_cast.GetGenericTypeDefinition(); + if (gen_type == generic_list && o is List obj_list) + { + var gga = type_to_cast.GetGenericArguments(); + var ret = type_to_cast.GetConstructor(new Type[0]).Invoke(new object[0]) as IList; + if (HasRecast(gga[0])) + { + for (var i = 0; i < obj_list.Count; i++) + ret.Add(UnwrapCast(gga[0], obj_list[i])); + } + else + { + for (var i = 0; i < obj_list.Count; i++) + ret.Add(obj_list[i]); + } + return ret; + } + if (gen_type == generic_dict && o is Dictionary obj_dict) + { + var gga = type_to_cast.GetGenericArguments(); + var ret = type_to_cast.GetConstructor(new Type[0]).Invoke(new object[0]) as IDictionary; + if (HasRecast(gga[0]) || HasRecast(gga[1])) + { + foreach (var x in obj_dict) + ret[UnwrapCast(gga[0], x.Key)] = UnwrapCast(gga[1], x.Value); + } + else + { + foreach (var x in obj_dict) + ret[x.Key] = x.Value; + } + return ret; + } + } + var interfaces = type_to_cast.GetInterfaces(); + if (interfaces.Contains(type_ituple) && o is ITuple tuple) + { + var gga = type_to_cast.GetGenericArguments(); + if (gga.Any(x => HasRecast(x))) + { + var ret = type_to_cast.GetConstructor(gga).Invoke(TupleToArray(tuple).Select((x, i) => UnwrapCast(gga[0], x)).ToArray()); + return ret; + } + else + { + var ret = type_to_cast.GetConstructor(gga).Invoke(TupleToArray(tuple)); + return ret; + } + } + return o.CastToType(type_to_cast); + } + public static object WrapCast(object o) + { + if (o == null) return null; + var type = o.GetType(); + if (type.IsArray) + { + var arr = o as Array; + var ret = new object[arr.Length]; + if (HasRecast(type.GetElementType())) + { + for (var i = 0; i < arr.Length; i++) + ret[i] = WrapCast(arr.GetValue(i)); + } + else + { + for (var i = 0; i < arr.Length; i++) + ret[i] = arr.GetValue(i); + } + return ret; + } + else if (type.IsGenericType) + { + var gt = type.GetGenericTypeDefinition(); + if (gt == generic_list) + { + var lst = o as IList; + var ret = new List(lst.Count); + var gga = gt.GetGenericArguments(); + if (HasRecast(gga[0])) + { + for (var i = 0; i < lst.Count; i++) + ret[i] = WrapCast(lst[i]); + } + else + { + for (var i = 0; i < lst.Count; i++) + ret[i] = lst[i]; + } + return ret; + + } + else if (gt == generic_dict) + { + var dct = o as IDictionary; + var ret = new Dictionary(); + var gga = gt.GetGenericArguments(); + if (HasRecast(gga[0]) || HasRecast(gga[1])) + { + foreach (var x in dct.Keys) + ret[WrapCast(x)] = WrapCast(dct[x]); + } + else + { + foreach (var x in dct.Keys) + ret[x] = dct[x]; + } + return ret; + } + } + else if (type.IsTuple()) + { + return CreatorTuple.Create(linq.entuple((ITuple)o).ToArray()); + } + return o; + } + #endregion + + /// + /// Пропускает этот элемент + /// + [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)] + public sealed class IgnoreAttribute : Attribute + { + + } + + /// + /// Выделяет элемент для хранения имени + /// + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] + public sealed class NameAttribute : Attribute + { + + } + + /// + /// Выключает неявные приведения при разворачивании для данного элемента + /// + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] + public sealed class StrongUnwrapAttribute : Attribute + { + + } + + /// + /// Выключает неявные приведения при сворачивании для данного элемента + /// + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] + public sealed class StrongWrapAttribute : Attribute + { + + } + + /// + /// Заставляет элемент проводить разворачивание и сворачивание словно контекст + /// + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] + public sealed class ContextAttribute : Attribute + { + + } + + /// + /// Позволяет свернуть этот readonly-элемент в контекст + /// + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] + public sealed class WrapReadonlyAttribute : Attribute + { + + } + + /// + /// Задаёт конструктор, который будет использован при разворачивании + /// + [AttributeUsage(AttributeTargets.Constructor, Inherited = false, AllowMultiple = false)] + public sealed class ConstructorAttribute : Attribute + { + + } + + /// + /// Выделяет метод, возвращающий аргументы для конструктора + /// сигнатуры static Func<ExecutionContext, object[]> + /// + [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)] + public sealed class ConstructorArgsAttribute : Attribute + { + + } + + private class WrappingMemberInfo + { + public MemberInfo MemberInfo; + public bool IsStrongWrap; + public bool IsStrongUnwrap; + public bool IsWrapReadonly; + public bool IsContext; + public bool IsField; + public int id = 0; + } + + + private static void GetElementFromContext(ILGenerator il, WrappingMemberInfo wmi) + { + + } + + /// + /// + /// + /// + /// (элементы, элемент-имя, конструктор, метод для аргументов конструктора) + private static (List, WrappingMemberInfo, ConstructorInfo, MethodInfo) Collect(Type type) + { + var ret = new List(); + var name = default(WrappingMemberInfo); + var constructor = default(ConstructorInfo); + var constructorargs = default(MethodInfo); + var id = 0; + + void Check(MemberInfo member) + { + switch (member.MemberType) + { + case MemberTypes.Field: + { + var field = (FieldInfo)member; + if (field.IsInitOnly && member.GetCustomAttribute() == null) return; + var m = new WrappingMemberInfo + { + MemberInfo = member, + IsWrapReadonly = field.IsInitOnly, + IsContext = member.GetCustomAttribute() != null, + IsStrongUnwrap = member.GetCustomAttribute() != null, + IsStrongWrap = member.GetCustomAttribute() != null, + IsField = true, + id = id++, + }; + if (member.GetCustomAttribute() == null) ret.Add(m); + else + { + if (field.IsInitOnly) throw new NotSupportedException($"Wrapper.Name cannot be readonly [{field}]"); + if (name != null) throw new NotSupportedException($"Wrapper.Name has already been defined [{field}]"); + name = m; + id--; + } + } + break; + case MemberTypes.Property: + { + var property = (PropertyInfo)member; + if (!property.CanRead) return; + if (!property.CanWrite && member.GetCustomAttribute() == null) return; + var m = new WrappingMemberInfo + { + MemberInfo = member, + IsWrapReadonly = !property.CanWrite, + IsContext = member.GetCustomAttribute() != null, + IsStrongUnwrap = member.GetCustomAttribute() != null, + IsStrongWrap = member.GetCustomAttribute() != null, + id = id++, + }; + if (member.GetCustomAttribute() == null) ret.Add(m); + else + { + if (!property.CanWrite) throw new NotSupportedException($"Wrapper.Name cannot be readonly [{property}]"); + if (name != null) throw new NotSupportedException($"Wrapper.Name has already been defined [{property}]"); + name = m; + id--; + } + } + break; + case MemberTypes.Constructor: + { + var ctor = (ConstructorInfo)member; + if (ctor.GetParameters().Length == 0) + { + constructor = ctor; + return; + } + if (member.GetCustomAttribute(typeof(ConstructorAttribute)) == null) return; + if (constructor != null && constructor.GetParameters().Length != 0) throw new NotSupportedException($"Explicit constructor has already been defined [{constructor}]"); + constructor = ctor; + } + break; + } + } + + void CheckCtorArgs(MemberInfo member) + { + switch (member.MemberType) + { + case MemberTypes.Method: + { + if (member.GetCustomAttribute() == null) return; + var method = (MethodInfo)member; + var pars = method.GetParameters(); + if (method.ReturnType != typeof(object[]) || !(pars.Length == 1 && pars[0].ParameterType == ContextType)) throw new NotSupportedException($"Wrong signature... [{method}]"); + constructorargs = method; + } + break; + } + } + + foreach (var member in type.GetMembers(BindingFlags.Public | BindingFlags.Instance)) + { + if (member.GetCustomAttribute() != null) continue; + Check(member); + } + + foreach (var member in type.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)) + { + if (member.GetCustomAttribute() != null) continue; + CheckCtorArgs(member); + } + + if (constructor != null && constructor.GetParameters().Length != 0 && constructorargs == null) + { + throw new NotSupportedException($"{type.Name} must have Wrapper.ConstructorArgs method because it has an explicit constructor"); + } + + return (ret, name, constructor, constructorargs); + } + + private static Type ContextType = typeof(ExecutionContext); + private static Type LocalsType = typeof(LocalVariablesContainer); + private static Type Void = typeof(void); + + internal static (Delegate, Delegate, Delegate, Delegate, Delegate, Delegate, Dictionary) InitWrapper(Type type) + { + var (elems, nameelem, explicit_constructor, explicit_constructor_args) = Collect(type); + + Type GetElementType(WrappingMemberInfo elem) => elem.IsField ? ((FieldInfo)elem.MemberInfo).FieldType : ((PropertyInfo)elem.MemberInfo).PropertyType; + void LoadElement(WrappingMemberInfo elem, ILGenerator il) + { + if (elem.IsField) il.Emit(OpCodes.Ldfld, (FieldInfo)elem.MemberInfo); + else il.Emit(OpCodes.Callvirt, ((PropertyInfo)elem.MemberInfo).GetAccessors(true)[0]); + } + + void SetElement(WrappingMemberInfo elem, ILGenerator il) + { + if (elem.IsField) il.Emit(OpCodes.Stfld, (FieldInfo)elem.MemberInfo); + else il.Emit(OpCodes.Callvirt, ((PropertyInfo)elem.MemberInfo).GetAccessors(true)[1]); + } + + var quickwrapper = default(Delegate); + { + var wrapper_dm = new DynamicMethod("QuickWrapper", Void, new Type[] { type, ContextType, LocalsType }); + var wrapper_il = wrapper_dm.GetILGenerator(); + + if (elems.Count > 0) + { + wrapper_il.Emit(OpCodes.Ldarg_2); + wrapper_il.Emit(OpCodes.Ldfld, LocalsType.GetField("Variables", BindingFlags.Public | BindingFlags.Instance)); + } + + for (var i = 0; i < elems.Count; i++) + { + if (i < elems.Count - 1) wrapper_il.Emit(OpCodes.Dup); + wrapper_il.Emit(OpCodes.Ldc_I4, elems[i].id); + + wrapper_il.Emit(OpCodes.Ldarg_0); + LoadElement(elems[i], wrapper_il); + + var elem_type = GetElementType(elems[i]); + if (elems[i].IsContext) + { + wrapper_il.Emit(OpCodes.Ldarg_1); + wrapper_il.Emit(OpCodes.Call, typeof(NewWrapper<>).MakeGenericType(new Type[] { elem_type }).GetMethod("WrapUnder", BindingFlags.Public | BindingFlags.Static)); + } + else + { + if (elem_type.IsValueType) + wrapper_il.Emit(OpCodes.Box, elem_type); + } + if (!elems[i].IsStrongWrap && HasRecast(elem_type)) + wrapper_il.Emit(OpCodes.Call, typeof(NewWrapper).GetMethod("WrapCast", BindingFlags.Public | BindingFlags.Static)); + + wrapper_il.Emit(OpCodes.Stelem_Ref); + } + + wrapper_il.Emit(OpCodes.Ret); + quickwrapper = wrapper_dm.CreateDelegate(typeof(Action<,,>).MakeGenericType(new Type[] { type, ContextType, LocalsType })); + } + + var safewrapper = default(Delegate); + { + var wrapper_dm = new DynamicMethod("SafeWrapper", Void, new Type[] { type, ContextType, LocalsType }); + var wrapper_il = wrapper_dm.GetILGenerator(); + + for (var i = 0; i < elems.Count; i++) + { + wrapper_il.Emit(OpCodes.Ldarg_2); + wrapper_il.Emit(OpCodes.Ldstr, elems[i].MemberInfo.Name); + wrapper_il.Emit(OpCodes.Ldarg_0); + LoadElement(elems[i], wrapper_il); + + var elem_type = GetElementType(elems[i]); + if (elems[i].IsContext) + { + wrapper_il.Emit(OpCodes.Ldarg_1); + wrapper_il.Emit(OpCodes.Call, typeof(NewWrapper<>).MakeGenericType(new Type[] { elem_type }).GetMethod("WrapUnder", BindingFlags.Public | BindingFlags.Static)); + } + else + { + if (elem_type.IsValueType) + wrapper_il.Emit(OpCodes.Box, elem_type); + } + if (!elems[i].IsStrongWrap && HasRecast(elem_type)) + wrapper_il.Emit(OpCodes.Call, typeof(NewWrapper).GetMethod("WrapCast", BindingFlags.Public | BindingFlags.Static)); + + wrapper_il.Emit(OpCodes.Callvirt, typeof(LocalVariablesContainer).GetMethod("SetValue", new Type[] {typeof(string), typeof(object)})); + wrapper_il.Emit(OpCodes.Pop); + } + + wrapper_il.Emit(OpCodes.Ret); + safewrapper = wrapper_dm.CreateDelegate(typeof(Action<,,>).MakeGenericType(new Type[] { type, ContextType, LocalsType })); + } + + var unwrapper = default(Delegate); + { + var unwrapper_dm = new DynamicMethod("Unwrapper", Void, new Type[] { LocalsType, type }); + var unwrapper_il = unwrapper_dm.GetILGenerator(); + unwrapper_il.DeclareLocal(typeof(int)); + unwrapper_il.DeclareLocal(typeof(object[])); + unwrapper_il.DeclareLocal(typeof(ContextWrap)); + + unwrapper_il.Emit(OpCodes.Ldc_I4_0); + unwrapper_il.Emit(OpCodes.Stloc_0); + unwrapper_il.Emit(OpCodes.Ldarg_0); + unwrapper_il.Emit(OpCodes.Ldfld, typeof(LocalVariablesContainer).GetField("NamedIdentificators")); + unwrapper_il.Emit(OpCodes.Ldarg_0); + unwrapper_il.Emit(OpCodes.Ldfld, typeof(LocalVariablesContainer).GetField("Variables")); + unwrapper_il.Emit(OpCodes.Stloc_1); + + + var label = default(Label); + + for (var i = 0; i < elems.Count; i++) + { + if (i < elems.Count - 1) unwrapper_il.Emit(OpCodes.Dup); + + unwrapper_il.Emit(OpCodes.Ldstr, elems[i].MemberInfo.Name); + unwrapper_il.Emit(OpCodes.Ldloca_S, 0); + unwrapper_il.Emit(OpCodes.Callvirt, typeof(Dictionary).GetMethod("TryGetValue")); + unwrapper_il.Emit(OpCodes.Brfalse_S, label = unwrapper_il.DefineLabel()); + + + var elem_type = GetElementType(elems[i]); + if (elems[i].IsContext) + { + unwrapper_il.Emit(OpCodes.Ldloc_1); + unwrapper_il.Emit(OpCodes.Ldloc_0); + unwrapper_il.Emit(OpCodes.Ldelem_Ref); + unwrapper_il.Emit(OpCodes.Isinst, typeof(ContextWrap)); + unwrapper_il.Emit(OpCodes.Stloc_2); + unwrapper_il.Emit(OpCodes.Ldloc_2); + unwrapper_il.Emit(OpCodes.Brfalse_S, label); + + unwrapper_il.Emit(OpCodes.Ldarg_1); + unwrapper_il.Emit(OpCodes.Ldloc_2); + //unwrapper_il.Emit(OpCodes.Ldfld, typeof(ContextWrap).GetField("Context")); + unwrapper_il.Emit(OpCodes.Call, typeof(NewWrapper<>).MakeGenericType(new Type[] { elem_type }).GetMethod("UnwrapUnder", BindingFlags.Public | BindingFlags.Static)); + SetElement(elems[i], unwrapper_il); + } + else + { + unwrapper_il.Emit(OpCodes.Ldarg_1); + unwrapper_il.Emit(OpCodes.Ldloc_1); + unwrapper_il.Emit(OpCodes.Ldloc_0); + unwrapper_il.Emit(OpCodes.Ldelem_Ref); + + if (elem_type.IsValueType) unwrapper_il.Emit(OpCodes.Unbox_Any, elem_type); + else unwrapper_il.Emit(OpCodes.Castclass, elem_type); + + if (!elems[i].IsStrongUnwrap && HasRecast(elem_type)) + unwrapper_il.Emit(OpCodes.Call, typeof(NewWrapper).GetMethod("UnwrapCast", BindingFlags.Public | BindingFlags.Static)); + + SetElement(elems[i], unwrapper_il); + } + unwrapper_il.MarkLabel(label); + } + + unwrapper_il.Emit(OpCodes.Ret); + unwrapper = unwrapper_dm.CreateDelegate(typeof(Action<,>).MakeGenericType(new Type[] { LocalsType, type })); + } + + var wrapname = default(Delegate); + { + var wrapname_dm = new DynamicMethod("WrapName", Void, new Type[] { type, ContextType }); + var wrapname_il = wrapname_dm.GetILGenerator(); + if (nameelem != null) + { + if (GetElementType(nameelem) != typeof(string)) throw new NotSupportedException($"Name must be string [{nameelem}]"); + + wrapname_il.Emit(OpCodes.Ldarg_1); + wrapname_il.Emit(OpCodes.Ldarg_0); + LoadElement(nameelem, wrapname_il); + + wrapname_il.Emit(OpCodes.Stfld, ContextType.GetField("Name", BindingFlags.Public | BindingFlags.Instance)); + } + wrapname_il.Emit(OpCodes.Ret); + wrapname = wrapname_dm.CreateDelegate(typeof(Action<,>).MakeGenericType(new Type[] { type, ContextType })); + } + + var unwrapname = default(Delegate); + { + var wrapname_dm = new DynamicMethod("UnwrapName", Void, new Type[] { ContextType, type }); + var wrapname_il = wrapname_dm.GetILGenerator(); + if (nameelem != null) + { + if (GetElementType(nameelem) != typeof(string)) throw new NotSupportedException($"Name must be string [{nameelem}]"); + + wrapname_il.Emit(OpCodes.Ldarg_1); + wrapname_il.Emit(OpCodes.Ldarg_0); + wrapname_il.Emit(OpCodes.Ldfld, ContextType.GetField("Name", BindingFlags.Public | BindingFlags.Instance)); + SetElement(nameelem, wrapname_il); + } + wrapname_il.Emit(OpCodes.Ret); + unwrapname = wrapname_dm.CreateDelegate(typeof(Action<,>).MakeGenericType(new Type[] { ContextType, type })); + } + + var initor = default(Delegate); + if (explicit_constructor == null) throw new NotSupportedException($"Type {type.Name} must have parameterless constructor"); + if (explicit_constructor.GetParameters().Length > 0) + { + var initor_dm = new DynamicMethod("Initor", type, new Type[1] { ContextType }, true); + var initor_il = initor_dm.GetILGenerator(); + initor_il.Emit(OpCodes.Ldarg_0); + initor_il.Emit(OpCodes.Call, explicit_constructor_args); + initor_il.DeclareLocal(typeof(object[])); + initor_il.Emit(OpCodes.Stloc_0); + var i = 0; + foreach (var p in explicit_constructor.GetParameters()) + { + initor_il.Emit(OpCodes.Ldloc_0); + initor_il.Emit(OpCodes.Ldc_I4, i++); + initor_il.Emit(OpCodes.Ldelem_Ref); + if (p.ParameterType.IsValueType) initor_il.Emit(OpCodes.Unbox_Any, p.ParameterType); + else initor_il.Emit(OpCodes.Castclass, p.ParameterType); + } + initor_il.Emit(OpCodes.Newobj, explicit_constructor); + initor_il.Emit(OpCodes.Ret); + initor = initor_dm.CreateDelegate(typeof(Func<,>).MakeGenericType(new Type[] { ContextType, type })); + } + else + { + var initor_dm = new DynamicMethod("Initor", type, new Type[1] { ContextType }, true); + var initor_il = initor_dm.GetILGenerator(); + initor_il.Emit(OpCodes.Newobj, explicit_constructor); + initor_il.Emit(OpCodes.Ret); + initor = initor_dm.CreateDelegate(typeof(Func<,>).MakeGenericType(new Type[] { ContextType, type })); + } + + return (quickwrapper, safewrapper, unwrapper, wrapname, unwrapname, initor, elems.ToDictionary(x => x.MemberInfo.Name, x => x.id)); + throw new NotImplementedException(); + } + + public static ExecutionContext Wrap(T obj) => NewWrapper.Wrap(obj); + public static T Unwrap(ExecutionContext context) => NewWrapper.Unwrap(context); + public static void WrapIn(T obj, ExecutionContext context) => NewWrapper.WrapIn(obj, context); + public static void UnwrapIn(ExecutionContext context, T obj) => NewWrapper.UnwrapIn(context, obj); + } + + public static class NewWrapper + { + public static readonly Func Initor; + + //Быстрое оборачивание заполняет переменные по отступу + public static readonly Action QuickWrapper; + //Безопасное оборачивание заполняет переменные по имени + public static readonly Action SafeWrapper; + public static readonly Action Unwrapper; + + public static readonly Action WrapName; + public static readonly Action UnwrapName; + + public static readonly Dictionary ContextNames; + public static readonly string[] Names; + public static readonly int ContextSize; + + static NewWrapper() + { + var d = NewWrapper.InitWrapper(typeof(T)); + QuickWrapper = (Action)d.Item1; + SafeWrapper = (Action)d.Item2; + Unwrapper = (Action)d.Item3; + WrapName = (Action)d.Item4; + UnwrapName = (Action)d.Item5; + Initor = (Func)d.Item6; + ContextNames = d.Item7; + Names = ContextNames.Keys.ToArray(); + ContextSize = ContextNames.Count; + } + + public static ExecutionContext Wrap(T obj) + { + var lc = new LocalVariablesContainer(ContextSize, new Dictionary(ContextNames)); + var ret = new ExecutionContext(false, false, lc); + QuickWrapper(obj, ret, lc); + WrapName(obj, ret); + return ret; + } + public static ContextWrap WrapUnder(T obj, ExecutionContext context) + { + if (obj == null) return null; + if (NewWrapper.HasRecast(obj.GetType())) throw new NotSupportedException("This type can't be converted into context"); + var lc = new LocalVariablesContainer(ContextSize, new Dictionary(ContextNames)); + var ret = new ExecutionContext(context, false, lc); + QuickWrapper(obj, ret, lc); + WrapName(obj, ret); + return ret.wrap; + } + public static T Unwrap(ExecutionContext context) + { + var ret = Initor(context); + UnwrapName(context, ret); + Unwrapper(context.LocalVariables, ret); + return ret; + } + public static T UnwrapUnder(ContextWrap context) => Unwrap(context.Context); + public static void WrapIn(T obj, ExecutionContext context) + { + SafeWrapper(obj, context, context.LocalVariables); + WrapName(obj, context); + } + public static void UnwrapIn(ExecutionContext context, T obj) + { + Unwrapper(context.LocalVariables, obj); + UnwrapName(context, obj); + } + } +} diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 58a872b..70483ca 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -13,7 +13,7 @@ git language;scripts;script-lang True - 0.7.0.2988 + 0.7.0.3063 $(Version) $(Version) slthree.ico diff --git a/SLThree/docs/versions/develop b/SLThree/docs/versions/develop index be587a1..3267eb6 100644 --- a/SLThree/docs/versions/develop +++ b/SLThree/docs/versions/develop @@ -1 +1,4 @@ ------- Changes ------ [~.~.~] \ No newline at end of file +------ Changes ------ [~.~.~] +Optimization: + - Wrappers refactoring, minumum 3x faster wrapping + minimum 20x faster unwrapping \ No newline at end of file diff --git a/slt/Program.cs b/slt/Program.cs index e4bfbd9..befb8e1 100644 --- a/slt/Program.cs +++ b/slt/Program.cs @@ -795,9 +795,9 @@ string[] Splitter(string str) if (onlynull) { - var old = REPLContext.LocalVariables.NamedIdenificators.Count; + var old = REPLContext.LocalVariables.NamedIdentificators.Count; REPLContext.LocalVariables.ClearNulls(); - var @new = REPLContext.LocalVariables.NamedIdenificators.Count; + var @new = REPLContext.LocalVariables.NamedIdentificators.Count; OutAsWarning($"{old - @new} nulls deleted from context"); } else From b1cf3b51a311ecca7dca3615c8d5734e544f73db Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Sat, 1 Jun 2024 00:56:09 +0300 Subject: [PATCH 03/69] fix #123 --- SLThree/Embedding/EmbeddingExtensions.cs | 13 - SLThree/Expressions/CastExpression.cs | 2 +- .../Operators/Binary/BinaryAssignUnknown.cs | 4 +- SLThree/Extensions/GenericExtensions.cs | 3 + SLThree/Extensions/SLTHelpers.cs | 9 +- SLThree/LocalVariablesContainer.cs | 9 +- SLThree/NewWrapper.cs | 711 ------------------ SLThree/SLThree.csproj | 2 +- SLThree/Wrapper.cs | 651 +++++++++++----- SLThree/sys/console.cs | 6 +- 10 files changed, 496 insertions(+), 914 deletions(-) delete mode 100644 SLThree/NewWrapper.cs diff --git a/SLThree/Embedding/EmbeddingExtensions.cs b/SLThree/Embedding/EmbeddingExtensions.cs index c8bb210..c10c646 100644 --- a/SLThree/Embedding/EmbeddingExtensions.cs +++ b/SLThree/Embedding/EmbeddingExtensions.cs @@ -16,18 +16,5 @@ public static ExecutionContext RunScript(this ExecutionContext context, string c { return Parser.This.RunScript(code, null, context); } - - public static T Unwrap(this ExecutionContext context) => Wrapper.Unwrap(context); - public static void UnwrapStatic(this ExecutionContext context) => Wrapper.UnwrapStatic(context); - public static ExecutionContext Wrap(this T obj) => Wrapper.Wrap(obj); - public static ExecutionContext WrapStatic() => Wrapper.WrapStatic(); - public static void UnwrapStaticClass(this ExecutionContext context, Type type) => NonGenericWrapper.GetWrapper(type).UnwrapStaticClass(context); - public static void UnwrapStaticClass(this Type type, ExecutionContext context) => NonGenericWrapper.GetWrapper(type).UnwrapStaticClass(context); - public static ExecutionContext WrapStaticClass(this Type type) => NonGenericWrapper.GetWrapper(type).WrapStaticClass(); - - public static T SafeUnwrap(this ExecutionContext context) => Wrapper.SafeUnwrap(context); - public static void SafeUnwrapStatic(this ExecutionContext context) => Wrapper.SafeUnwrapStatic(context); - public static void SafeUnwrapStaticClass(this ExecutionContext context, Type type) => NonGenericWrapper.GetWrapper(type).SafeUnwrapStaticClass(context); - public static void SafeUnwrapStaticClass(this Type type, ExecutionContext context) => NonGenericWrapper.GetWrapper(type).SafeUnwrapStaticClass(context); } } diff --git a/SLThree/Expressions/CastExpression.cs b/SLThree/Expressions/CastExpression.cs index 4e4a7a4..94ada7b 100644 --- a/SLThree/Expressions/CastExpression.cs +++ b/SLThree/Expressions/CastExpression.cs @@ -24,7 +24,7 @@ public CastExpression(BaseExpression left, TypenameExpression type, SourceContex public override object GetValue(ExecutionContext context) { - if (normal) return WrappersTypeSetting.UnwrapCast(Type.GetValue(context).Cast(), Left.GetValue(context)); + if (normal) return Wrapper.UnwrapCast(Type.GetValue(context).Cast(), Left.GetValue(context)); else return Left.DropPriority(); } diff --git a/SLThree/Expressions/Operators/Binary/BinaryAssignUnknown.cs b/SLThree/Expressions/Operators/Binary/BinaryAssignUnknown.cs index 2c3b63f..95c7f4d 100644 --- a/SLThree/Expressions/Operators/Binary/BinaryAssignUnknown.cs +++ b/SLThree/Expressions/Operators/Binary/BinaryAssignUnknown.cs @@ -29,13 +29,13 @@ public override object GetValue(ExecutionContext context) context.LocalVariables.SetValue(wrap.Context.Name, wrap); return wrap; } - NonGenericWrapper wrapper; + /*NonGenericWrapper wrapper; if ((wrapper = NonGenericWrapper.GetWrapper(right.GetType())).HasName()) { var name = wrapper.GetName(right); context.LocalVariables.SetValue(name, right); return right; - } + }*/ } throw new OperatorError(this, right?.GetType() ?? Left.GetType()); } diff --git a/SLThree/Extensions/GenericExtensions.cs b/SLThree/Extensions/GenericExtensions.cs index c0401be..20b2f1a 100644 --- a/SLThree/Extensions/GenericExtensions.cs +++ b/SLThree/Extensions/GenericExtensions.cs @@ -71,5 +71,8 @@ public static ChanceChooser ConvertChooser(this ChanceChooser new ChanceChooser(input.Values.Select(x => (selector(x.Item1), x.Item2)).ToArray()); public static ChanceChooser ConvertChooser(this ChanceChooser input) where TOut : TIn => new ChanceChooser(input.Values.Select(x => ((TOut)x.Item1, x.Item2)).ToArray()); + + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Advanced)] + public static LocalVariablesContainer ToLocals(this Dictionary dict) => LocalVariablesContainer.GetFromDictionary(dict); } } diff --git a/SLThree/Extensions/SLTHelpers.cs b/SLThree/Extensions/SLTHelpers.cs index 5b59730..9f31867 100644 --- a/SLThree/Extensions/SLTHelpers.cs +++ b/SLThree/Extensions/SLTHelpers.cs @@ -197,7 +197,7 @@ public static object CastToType(this object o, Type casting_type) if (casting_type == typeof(string)) return o.ToString(); - if (casting_type == type_context) + /*if (casting_type == type_context) { if (o is Type st_type) return @@ -206,11 +206,12 @@ public static object CastToType(this object o, Type casting_type) : new ContextWrap(NonGenericWrapper.GetWrapper(st_type).WrapStatic()); else return new ContextWrap(NonGenericWrapper.GetWrapper(o.GetType()).Wrap(o)); - } + }*/ var type = o.GetType(); if (type == casting_type) return o; if (o is IConvertible) return Convert.ChangeType(o, casting_type); - if (type == type_context) + //todo make sys.wrapper instead + /*if (type == type_context) { var wrapper = NonGenericWrapper.GetWrapper(casting_type); if (casting_type.IsAbstract) @@ -220,7 +221,7 @@ public static object CastToType(this object o, Type casting_type) return null; } else return wrapper.Unwrap(((ContextWrap)o).Context); - } + }*/ if (casting_type.IsEnum) { if (type == type_string) return Enum.Parse(casting_type, (string)o); diff --git a/SLThree/LocalVariablesContainer.cs b/SLThree/LocalVariablesContainer.cs index d4fb892..7cc990b 100644 --- a/SLThree/LocalVariablesContainer.cs +++ b/SLThree/LocalVariablesContainer.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using SLThree.Extensions; +using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; @@ -19,6 +20,12 @@ public LocalVariablesContainer(int default_size = 8, Dictionary nam public Dictionary NamedIdentificators; public Dictionary GetAsDictionary() => NamedIdentificators.ToDictionary(x => x.Key, x => Variables[x.Value]); + public static LocalVariablesContainer GetFromDictionary(IDictionary objs) + { + var ret = new LocalVariablesContainer(objs.Count, objs.Keys.Select((x, i) => (x, i)).ToDictionary(x => x.x, x => x.i)); + objs.Values.ToArray().CopyTo(ret.Variables, 0); + return ret; + } public void ClearNulls() { diff --git a/SLThree/NewWrapper.cs b/SLThree/NewWrapper.cs deleted file mode 100644 index 394537e..0000000 --- a/SLThree/NewWrapper.cs +++ /dev/null @@ -1,711 +0,0 @@ -using SLThree.Extensions; -using SLThree.sys; -using System; -using System.CodeDom; -using System.Collections; -using System.Collections.Generic; -using System.Dynamic; -using System.Linq; -using System.Reflection; -using System.Reflection.Emit; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; - -namespace SLThree -{ - public static class NewWrapper - { - #region Type Setting - internal static Type generic_list = typeof(List).GetGenericTypeDefinition(); - internal static Type generic_dict = typeof(Dictionary).GetGenericTypeDefinition(); - internal static Type type_ituple = typeof(ITuple); - public static bool HasRecast(Type type) - { - if (type.IsArray) return true; - if (type.IsGenericType) - { - if (type == generic_list) return true; - if (type == generic_dict) return true; - } - var interfaces = type.GetInterfaces(); - if (interfaces.Contains(type_ituple)) return true; - return false; - } - public static object[] TupleToArray(ITuple tuple) - { - var ret = new object[tuple.Length]; - for (var i = 0; i < ret.Length; i++) - ret[i] = tuple[i]; - return ret; - } - public static object UnwrapCast(Type type_to_cast, object o) - { - if (type_to_cast.IsArray && o is object[] obj_array) - { - var gga = type_to_cast.GetElementType(); - var ret = Array.CreateInstance(gga, obj_array.Length); - if (HasRecast(gga)) - { - for (var i = 0; i < obj_array.Length; i++) - ret.SetValue(UnwrapCast(gga, obj_array[i]), i); - } - else - { - for (var i = 0; i < obj_array.Length; i++) - ret.SetValue(obj_array[i], i); - } - return ret; - } - else if (type_to_cast.IsArray && o is List obj_list) - { - var gga = type_to_cast.GetElementType(); - var ret = Array.CreateInstance(gga, obj_list.Count); - if (HasRecast(gga)) - { - for (var i = 0; i < obj_list.Count; i++) - ret.SetValue(UnwrapCast(gga, obj_list[i]), i); - } - else - { - for (var i = 0; i < obj_list.Count; i++) - ret.SetValue(obj_list[i], i); - } - return ret; - } - if (type_to_cast.IsGenericType) - { - var gen_type = type_to_cast.GetGenericTypeDefinition(); - if (gen_type == generic_list && o is List obj_list) - { - var gga = type_to_cast.GetGenericArguments(); - var ret = type_to_cast.GetConstructor(new Type[0]).Invoke(new object[0]) as IList; - if (HasRecast(gga[0])) - { - for (var i = 0; i < obj_list.Count; i++) - ret.Add(UnwrapCast(gga[0], obj_list[i])); - } - else - { - for (var i = 0; i < obj_list.Count; i++) - ret.Add(obj_list[i]); - } - return ret; - } - if (gen_type == generic_dict && o is Dictionary obj_dict) - { - var gga = type_to_cast.GetGenericArguments(); - var ret = type_to_cast.GetConstructor(new Type[0]).Invoke(new object[0]) as IDictionary; - if (HasRecast(gga[0]) || HasRecast(gga[1])) - { - foreach (var x in obj_dict) - ret[UnwrapCast(gga[0], x.Key)] = UnwrapCast(gga[1], x.Value); - } - else - { - foreach (var x in obj_dict) - ret[x.Key] = x.Value; - } - return ret; - } - } - var interfaces = type_to_cast.GetInterfaces(); - if (interfaces.Contains(type_ituple) && o is ITuple tuple) - { - var gga = type_to_cast.GetGenericArguments(); - if (gga.Any(x => HasRecast(x))) - { - var ret = type_to_cast.GetConstructor(gga).Invoke(TupleToArray(tuple).Select((x, i) => UnwrapCast(gga[0], x)).ToArray()); - return ret; - } - else - { - var ret = type_to_cast.GetConstructor(gga).Invoke(TupleToArray(tuple)); - return ret; - } - } - return o.CastToType(type_to_cast); - } - public static object WrapCast(object o) - { - if (o == null) return null; - var type = o.GetType(); - if (type.IsArray) - { - var arr = o as Array; - var ret = new object[arr.Length]; - if (HasRecast(type.GetElementType())) - { - for (var i = 0; i < arr.Length; i++) - ret[i] = WrapCast(arr.GetValue(i)); - } - else - { - for (var i = 0; i < arr.Length; i++) - ret[i] = arr.GetValue(i); - } - return ret; - } - else if (type.IsGenericType) - { - var gt = type.GetGenericTypeDefinition(); - if (gt == generic_list) - { - var lst = o as IList; - var ret = new List(lst.Count); - var gga = gt.GetGenericArguments(); - if (HasRecast(gga[0])) - { - for (var i = 0; i < lst.Count; i++) - ret[i] = WrapCast(lst[i]); - } - else - { - for (var i = 0; i < lst.Count; i++) - ret[i] = lst[i]; - } - return ret; - - } - else if (gt == generic_dict) - { - var dct = o as IDictionary; - var ret = new Dictionary(); - var gga = gt.GetGenericArguments(); - if (HasRecast(gga[0]) || HasRecast(gga[1])) - { - foreach (var x in dct.Keys) - ret[WrapCast(x)] = WrapCast(dct[x]); - } - else - { - foreach (var x in dct.Keys) - ret[x] = dct[x]; - } - return ret; - } - } - else if (type.IsTuple()) - { - return CreatorTuple.Create(linq.entuple((ITuple)o).ToArray()); - } - return o; - } - #endregion - - /// - /// Пропускает этот элемент - /// - [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)] - public sealed class IgnoreAttribute : Attribute - { - - } - - /// - /// Выделяет элемент для хранения имени - /// - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] - public sealed class NameAttribute : Attribute - { - - } - - /// - /// Выключает неявные приведения при разворачивании для данного элемента - /// - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] - public sealed class StrongUnwrapAttribute : Attribute - { - - } - - /// - /// Выключает неявные приведения при сворачивании для данного элемента - /// - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] - public sealed class StrongWrapAttribute : Attribute - { - - } - - /// - /// Заставляет элемент проводить разворачивание и сворачивание словно контекст - /// - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] - public sealed class ContextAttribute : Attribute - { - - } - - /// - /// Позволяет свернуть этот readonly-элемент в контекст - /// - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] - public sealed class WrapReadonlyAttribute : Attribute - { - - } - - /// - /// Задаёт конструктор, который будет использован при разворачивании - /// - [AttributeUsage(AttributeTargets.Constructor, Inherited = false, AllowMultiple = false)] - public sealed class ConstructorAttribute : Attribute - { - - } - - /// - /// Выделяет метод, возвращающий аргументы для конструктора - /// сигнатуры static Func<ExecutionContext, object[]> - /// - [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)] - public sealed class ConstructorArgsAttribute : Attribute - { - - } - - private class WrappingMemberInfo - { - public MemberInfo MemberInfo; - public bool IsStrongWrap; - public bool IsStrongUnwrap; - public bool IsWrapReadonly; - public bool IsContext; - public bool IsField; - public int id = 0; - } - - - private static void GetElementFromContext(ILGenerator il, WrappingMemberInfo wmi) - { - - } - - /// - /// - /// - /// - /// (элементы, элемент-имя, конструктор, метод для аргументов конструктора) - private static (List, WrappingMemberInfo, ConstructorInfo, MethodInfo) Collect(Type type) - { - var ret = new List(); - var name = default(WrappingMemberInfo); - var constructor = default(ConstructorInfo); - var constructorargs = default(MethodInfo); - var id = 0; - - void Check(MemberInfo member) - { - switch (member.MemberType) - { - case MemberTypes.Field: - { - var field = (FieldInfo)member; - if (field.IsInitOnly && member.GetCustomAttribute() == null) return; - var m = new WrappingMemberInfo - { - MemberInfo = member, - IsWrapReadonly = field.IsInitOnly, - IsContext = member.GetCustomAttribute() != null, - IsStrongUnwrap = member.GetCustomAttribute() != null, - IsStrongWrap = member.GetCustomAttribute() != null, - IsField = true, - id = id++, - }; - if (member.GetCustomAttribute() == null) ret.Add(m); - else - { - if (field.IsInitOnly) throw new NotSupportedException($"Wrapper.Name cannot be readonly [{field}]"); - if (name != null) throw new NotSupportedException($"Wrapper.Name has already been defined [{field}]"); - name = m; - id--; - } - } - break; - case MemberTypes.Property: - { - var property = (PropertyInfo)member; - if (!property.CanRead) return; - if (!property.CanWrite && member.GetCustomAttribute() == null) return; - var m = new WrappingMemberInfo - { - MemberInfo = member, - IsWrapReadonly = !property.CanWrite, - IsContext = member.GetCustomAttribute() != null, - IsStrongUnwrap = member.GetCustomAttribute() != null, - IsStrongWrap = member.GetCustomAttribute() != null, - id = id++, - }; - if (member.GetCustomAttribute() == null) ret.Add(m); - else - { - if (!property.CanWrite) throw new NotSupportedException($"Wrapper.Name cannot be readonly [{property}]"); - if (name != null) throw new NotSupportedException($"Wrapper.Name has already been defined [{property}]"); - name = m; - id--; - } - } - break; - case MemberTypes.Constructor: - { - var ctor = (ConstructorInfo)member; - if (ctor.GetParameters().Length == 0) - { - constructor = ctor; - return; - } - if (member.GetCustomAttribute(typeof(ConstructorAttribute)) == null) return; - if (constructor != null && constructor.GetParameters().Length != 0) throw new NotSupportedException($"Explicit constructor has already been defined [{constructor}]"); - constructor = ctor; - } - break; - } - } - - void CheckCtorArgs(MemberInfo member) - { - switch (member.MemberType) - { - case MemberTypes.Method: - { - if (member.GetCustomAttribute() == null) return; - var method = (MethodInfo)member; - var pars = method.GetParameters(); - if (method.ReturnType != typeof(object[]) || !(pars.Length == 1 && pars[0].ParameterType == ContextType)) throw new NotSupportedException($"Wrong signature... [{method}]"); - constructorargs = method; - } - break; - } - } - - foreach (var member in type.GetMembers(BindingFlags.Public | BindingFlags.Instance)) - { - if (member.GetCustomAttribute() != null) continue; - Check(member); - } - - foreach (var member in type.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)) - { - if (member.GetCustomAttribute() != null) continue; - CheckCtorArgs(member); - } - - if (constructor != null && constructor.GetParameters().Length != 0 && constructorargs == null) - { - throw new NotSupportedException($"{type.Name} must have Wrapper.ConstructorArgs method because it has an explicit constructor"); - } - - return (ret, name, constructor, constructorargs); - } - - private static Type ContextType = typeof(ExecutionContext); - private static Type LocalsType = typeof(LocalVariablesContainer); - private static Type Void = typeof(void); - - internal static (Delegate, Delegate, Delegate, Delegate, Delegate, Delegate, Dictionary) InitWrapper(Type type) - { - var (elems, nameelem, explicit_constructor, explicit_constructor_args) = Collect(type); - - Type GetElementType(WrappingMemberInfo elem) => elem.IsField ? ((FieldInfo)elem.MemberInfo).FieldType : ((PropertyInfo)elem.MemberInfo).PropertyType; - void LoadElement(WrappingMemberInfo elem, ILGenerator il) - { - if (elem.IsField) il.Emit(OpCodes.Ldfld, (FieldInfo)elem.MemberInfo); - else il.Emit(OpCodes.Callvirt, ((PropertyInfo)elem.MemberInfo).GetAccessors(true)[0]); - } - - void SetElement(WrappingMemberInfo elem, ILGenerator il) - { - if (elem.IsField) il.Emit(OpCodes.Stfld, (FieldInfo)elem.MemberInfo); - else il.Emit(OpCodes.Callvirt, ((PropertyInfo)elem.MemberInfo).GetAccessors(true)[1]); - } - - var quickwrapper = default(Delegate); - { - var wrapper_dm = new DynamicMethod("QuickWrapper", Void, new Type[] { type, ContextType, LocalsType }); - var wrapper_il = wrapper_dm.GetILGenerator(); - - if (elems.Count > 0) - { - wrapper_il.Emit(OpCodes.Ldarg_2); - wrapper_il.Emit(OpCodes.Ldfld, LocalsType.GetField("Variables", BindingFlags.Public | BindingFlags.Instance)); - } - - for (var i = 0; i < elems.Count; i++) - { - if (i < elems.Count - 1) wrapper_il.Emit(OpCodes.Dup); - wrapper_il.Emit(OpCodes.Ldc_I4, elems[i].id); - - wrapper_il.Emit(OpCodes.Ldarg_0); - LoadElement(elems[i], wrapper_il); - - var elem_type = GetElementType(elems[i]); - if (elems[i].IsContext) - { - wrapper_il.Emit(OpCodes.Ldarg_1); - wrapper_il.Emit(OpCodes.Call, typeof(NewWrapper<>).MakeGenericType(new Type[] { elem_type }).GetMethod("WrapUnder", BindingFlags.Public | BindingFlags.Static)); - } - else - { - if (elem_type.IsValueType) - wrapper_il.Emit(OpCodes.Box, elem_type); - } - if (!elems[i].IsStrongWrap && HasRecast(elem_type)) - wrapper_il.Emit(OpCodes.Call, typeof(NewWrapper).GetMethod("WrapCast", BindingFlags.Public | BindingFlags.Static)); - - wrapper_il.Emit(OpCodes.Stelem_Ref); - } - - wrapper_il.Emit(OpCodes.Ret); - quickwrapper = wrapper_dm.CreateDelegate(typeof(Action<,,>).MakeGenericType(new Type[] { type, ContextType, LocalsType })); - } - - var safewrapper = default(Delegate); - { - var wrapper_dm = new DynamicMethod("SafeWrapper", Void, new Type[] { type, ContextType, LocalsType }); - var wrapper_il = wrapper_dm.GetILGenerator(); - - for (var i = 0; i < elems.Count; i++) - { - wrapper_il.Emit(OpCodes.Ldarg_2); - wrapper_il.Emit(OpCodes.Ldstr, elems[i].MemberInfo.Name); - wrapper_il.Emit(OpCodes.Ldarg_0); - LoadElement(elems[i], wrapper_il); - - var elem_type = GetElementType(elems[i]); - if (elems[i].IsContext) - { - wrapper_il.Emit(OpCodes.Ldarg_1); - wrapper_il.Emit(OpCodes.Call, typeof(NewWrapper<>).MakeGenericType(new Type[] { elem_type }).GetMethod("WrapUnder", BindingFlags.Public | BindingFlags.Static)); - } - else - { - if (elem_type.IsValueType) - wrapper_il.Emit(OpCodes.Box, elem_type); - } - if (!elems[i].IsStrongWrap && HasRecast(elem_type)) - wrapper_il.Emit(OpCodes.Call, typeof(NewWrapper).GetMethod("WrapCast", BindingFlags.Public | BindingFlags.Static)); - - wrapper_il.Emit(OpCodes.Callvirt, typeof(LocalVariablesContainer).GetMethod("SetValue", new Type[] {typeof(string), typeof(object)})); - wrapper_il.Emit(OpCodes.Pop); - } - - wrapper_il.Emit(OpCodes.Ret); - safewrapper = wrapper_dm.CreateDelegate(typeof(Action<,,>).MakeGenericType(new Type[] { type, ContextType, LocalsType })); - } - - var unwrapper = default(Delegate); - { - var unwrapper_dm = new DynamicMethod("Unwrapper", Void, new Type[] { LocalsType, type }); - var unwrapper_il = unwrapper_dm.GetILGenerator(); - unwrapper_il.DeclareLocal(typeof(int)); - unwrapper_il.DeclareLocal(typeof(object[])); - unwrapper_il.DeclareLocal(typeof(ContextWrap)); - - unwrapper_il.Emit(OpCodes.Ldc_I4_0); - unwrapper_il.Emit(OpCodes.Stloc_0); - unwrapper_il.Emit(OpCodes.Ldarg_0); - unwrapper_il.Emit(OpCodes.Ldfld, typeof(LocalVariablesContainer).GetField("NamedIdentificators")); - unwrapper_il.Emit(OpCodes.Ldarg_0); - unwrapper_il.Emit(OpCodes.Ldfld, typeof(LocalVariablesContainer).GetField("Variables")); - unwrapper_il.Emit(OpCodes.Stloc_1); - - - var label = default(Label); - - for (var i = 0; i < elems.Count; i++) - { - if (i < elems.Count - 1) unwrapper_il.Emit(OpCodes.Dup); - - unwrapper_il.Emit(OpCodes.Ldstr, elems[i].MemberInfo.Name); - unwrapper_il.Emit(OpCodes.Ldloca_S, 0); - unwrapper_il.Emit(OpCodes.Callvirt, typeof(Dictionary).GetMethod("TryGetValue")); - unwrapper_il.Emit(OpCodes.Brfalse_S, label = unwrapper_il.DefineLabel()); - - - var elem_type = GetElementType(elems[i]); - if (elems[i].IsContext) - { - unwrapper_il.Emit(OpCodes.Ldloc_1); - unwrapper_il.Emit(OpCodes.Ldloc_0); - unwrapper_il.Emit(OpCodes.Ldelem_Ref); - unwrapper_il.Emit(OpCodes.Isinst, typeof(ContextWrap)); - unwrapper_il.Emit(OpCodes.Stloc_2); - unwrapper_il.Emit(OpCodes.Ldloc_2); - unwrapper_il.Emit(OpCodes.Brfalse_S, label); - - unwrapper_il.Emit(OpCodes.Ldarg_1); - unwrapper_il.Emit(OpCodes.Ldloc_2); - //unwrapper_il.Emit(OpCodes.Ldfld, typeof(ContextWrap).GetField("Context")); - unwrapper_il.Emit(OpCodes.Call, typeof(NewWrapper<>).MakeGenericType(new Type[] { elem_type }).GetMethod("UnwrapUnder", BindingFlags.Public | BindingFlags.Static)); - SetElement(elems[i], unwrapper_il); - } - else - { - unwrapper_il.Emit(OpCodes.Ldarg_1); - unwrapper_il.Emit(OpCodes.Ldloc_1); - unwrapper_il.Emit(OpCodes.Ldloc_0); - unwrapper_il.Emit(OpCodes.Ldelem_Ref); - - if (elem_type.IsValueType) unwrapper_il.Emit(OpCodes.Unbox_Any, elem_type); - else unwrapper_il.Emit(OpCodes.Castclass, elem_type); - - if (!elems[i].IsStrongUnwrap && HasRecast(elem_type)) - unwrapper_il.Emit(OpCodes.Call, typeof(NewWrapper).GetMethod("UnwrapCast", BindingFlags.Public | BindingFlags.Static)); - - SetElement(elems[i], unwrapper_il); - } - unwrapper_il.MarkLabel(label); - } - - unwrapper_il.Emit(OpCodes.Ret); - unwrapper = unwrapper_dm.CreateDelegate(typeof(Action<,>).MakeGenericType(new Type[] { LocalsType, type })); - } - - var wrapname = default(Delegate); - { - var wrapname_dm = new DynamicMethod("WrapName", Void, new Type[] { type, ContextType }); - var wrapname_il = wrapname_dm.GetILGenerator(); - if (nameelem != null) - { - if (GetElementType(nameelem) != typeof(string)) throw new NotSupportedException($"Name must be string [{nameelem}]"); - - wrapname_il.Emit(OpCodes.Ldarg_1); - wrapname_il.Emit(OpCodes.Ldarg_0); - LoadElement(nameelem, wrapname_il); - - wrapname_il.Emit(OpCodes.Stfld, ContextType.GetField("Name", BindingFlags.Public | BindingFlags.Instance)); - } - wrapname_il.Emit(OpCodes.Ret); - wrapname = wrapname_dm.CreateDelegate(typeof(Action<,>).MakeGenericType(new Type[] { type, ContextType })); - } - - var unwrapname = default(Delegate); - { - var wrapname_dm = new DynamicMethod("UnwrapName", Void, new Type[] { ContextType, type }); - var wrapname_il = wrapname_dm.GetILGenerator(); - if (nameelem != null) - { - if (GetElementType(nameelem) != typeof(string)) throw new NotSupportedException($"Name must be string [{nameelem}]"); - - wrapname_il.Emit(OpCodes.Ldarg_1); - wrapname_il.Emit(OpCodes.Ldarg_0); - wrapname_il.Emit(OpCodes.Ldfld, ContextType.GetField("Name", BindingFlags.Public | BindingFlags.Instance)); - SetElement(nameelem, wrapname_il); - } - wrapname_il.Emit(OpCodes.Ret); - unwrapname = wrapname_dm.CreateDelegate(typeof(Action<,>).MakeGenericType(new Type[] { ContextType, type })); - } - - var initor = default(Delegate); - if (explicit_constructor == null) throw new NotSupportedException($"Type {type.Name} must have parameterless constructor"); - if (explicit_constructor.GetParameters().Length > 0) - { - var initor_dm = new DynamicMethod("Initor", type, new Type[1] { ContextType }, true); - var initor_il = initor_dm.GetILGenerator(); - initor_il.Emit(OpCodes.Ldarg_0); - initor_il.Emit(OpCodes.Call, explicit_constructor_args); - initor_il.DeclareLocal(typeof(object[])); - initor_il.Emit(OpCodes.Stloc_0); - var i = 0; - foreach (var p in explicit_constructor.GetParameters()) - { - initor_il.Emit(OpCodes.Ldloc_0); - initor_il.Emit(OpCodes.Ldc_I4, i++); - initor_il.Emit(OpCodes.Ldelem_Ref); - if (p.ParameterType.IsValueType) initor_il.Emit(OpCodes.Unbox_Any, p.ParameterType); - else initor_il.Emit(OpCodes.Castclass, p.ParameterType); - } - initor_il.Emit(OpCodes.Newobj, explicit_constructor); - initor_il.Emit(OpCodes.Ret); - initor = initor_dm.CreateDelegate(typeof(Func<,>).MakeGenericType(new Type[] { ContextType, type })); - } - else - { - var initor_dm = new DynamicMethod("Initor", type, new Type[1] { ContextType }, true); - var initor_il = initor_dm.GetILGenerator(); - initor_il.Emit(OpCodes.Newobj, explicit_constructor); - initor_il.Emit(OpCodes.Ret); - initor = initor_dm.CreateDelegate(typeof(Func<,>).MakeGenericType(new Type[] { ContextType, type })); - } - - return (quickwrapper, safewrapper, unwrapper, wrapname, unwrapname, initor, elems.ToDictionary(x => x.MemberInfo.Name, x => x.id)); - throw new NotImplementedException(); - } - - public static ExecutionContext Wrap(T obj) => NewWrapper.Wrap(obj); - public static T Unwrap(ExecutionContext context) => NewWrapper.Unwrap(context); - public static void WrapIn(T obj, ExecutionContext context) => NewWrapper.WrapIn(obj, context); - public static void UnwrapIn(ExecutionContext context, T obj) => NewWrapper.UnwrapIn(context, obj); - } - - public static class NewWrapper - { - public static readonly Func Initor; - - //Быстрое оборачивание заполняет переменные по отступу - public static readonly Action QuickWrapper; - //Безопасное оборачивание заполняет переменные по имени - public static readonly Action SafeWrapper; - public static readonly Action Unwrapper; - - public static readonly Action WrapName; - public static readonly Action UnwrapName; - - public static readonly Dictionary ContextNames; - public static readonly string[] Names; - public static readonly int ContextSize; - - static NewWrapper() - { - var d = NewWrapper.InitWrapper(typeof(T)); - QuickWrapper = (Action)d.Item1; - SafeWrapper = (Action)d.Item2; - Unwrapper = (Action)d.Item3; - WrapName = (Action)d.Item4; - UnwrapName = (Action)d.Item5; - Initor = (Func)d.Item6; - ContextNames = d.Item7; - Names = ContextNames.Keys.ToArray(); - ContextSize = ContextNames.Count; - } - - public static ExecutionContext Wrap(T obj) - { - var lc = new LocalVariablesContainer(ContextSize, new Dictionary(ContextNames)); - var ret = new ExecutionContext(false, false, lc); - QuickWrapper(obj, ret, lc); - WrapName(obj, ret); - return ret; - } - public static ContextWrap WrapUnder(T obj, ExecutionContext context) - { - if (obj == null) return null; - if (NewWrapper.HasRecast(obj.GetType())) throw new NotSupportedException("This type can't be converted into context"); - var lc = new LocalVariablesContainer(ContextSize, new Dictionary(ContextNames)); - var ret = new ExecutionContext(context, false, lc); - QuickWrapper(obj, ret, lc); - WrapName(obj, ret); - return ret.wrap; - } - public static T Unwrap(ExecutionContext context) - { - var ret = Initor(context); - UnwrapName(context, ret); - Unwrapper(context.LocalVariables, ret); - return ret; - } - public static T UnwrapUnder(ContextWrap context) => Unwrap(context.Context); - public static void WrapIn(T obj, ExecutionContext context) - { - SafeWrapper(obj, context, context.LocalVariables); - WrapName(obj, context); - } - public static void UnwrapIn(ExecutionContext context, T obj) - { - Unwrapper(context.LocalVariables, obj); - UnwrapName(context, obj); - } - } -} diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 70483ca..76a4b0a 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -13,7 +13,7 @@ git language;scripts;script-lang True - 0.7.0.3063 + 0.7.0.3066 $(Version) $(Version) slthree.ico diff --git a/SLThree/Wrapper.cs b/SLThree/Wrapper.cs index b8704c2..2e095b8 100644 --- a/SLThree/Wrapper.cs +++ b/SLThree/Wrapper.cs @@ -5,17 +5,18 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Reflection.Emit; using System.Runtime.CompilerServices; namespace SLThree { - public abstract class WrappersTypeSetting + public static class Wrapper { #region Type Setting - protected static Type generic_list = typeof(List).GetGenericTypeDefinition(); - protected static Type generic_dict = typeof(Dictionary).GetGenericTypeDefinition(); - protected static Type type_ituple = typeof(ITuple); - protected static bool HasRecast(Type type) + internal static Type generic_list = typeof(List).GetGenericTypeDefinition(); + internal static Type generic_dict = typeof(Dictionary).GetGenericTypeDefinition(); + internal static Type type_ituple = typeof(ITuple); + public static bool HasRecast(Type type) { if (type.IsArray) return true; if (type.IsGenericType) @@ -27,14 +28,14 @@ protected static bool HasRecast(Type type) if (interfaces.Contains(type_ituple)) return true; return false; } - protected static object[] TupleToArray(ITuple tuple) + public static object[] TupleToArray(ITuple tuple) { var ret = new object[tuple.Length]; for (var i = 0; i < ret.Length; i++) ret[i] = tuple[i]; return ret; } - internal static object UnwrapCast(Type type_to_cast, object o) + public static object UnwrapCast(Type type_to_cast, object o) { if (type_to_cast.IsArray && o is object[] obj_array) { @@ -121,7 +122,7 @@ internal static object UnwrapCast(Type type_to_cast, object o) } return o.CastToType(type_to_cast); } - internal static object WrapCast(object o) + public static object WrapCast(object o) { if (o == null) return null; var type = o.GetType(); @@ -188,228 +189,520 @@ internal static object WrapCast(object o) } #endregion - internal protected WrappersTypeSetting() { } - } + /// + /// Пропускает этот элемент + /// + [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)] + public sealed class IgnoreAttribute : Attribute + { - public class NonGenericWrapper : WrappersTypeSetting - { - protected Type type; - protected string typename; - protected int counter; - internal string GetWrappedContextName() => $"<{typename}>@{Convert.ToString(counter++, 16).ToUpper().PadLeft(2, '0')}"; - private static Dictionary Wrappers { get; } = new Dictionary(); - public static NonGenericWrapper GetWrapper(Type type) + } + + /// + /// Выделяет элемент для хранения имени + /// + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] + public sealed class NameAttribute : Attribute { - if (Wrappers.TryGetValue(type, out var value)) return value; - else return new NonGenericWrapper(type); + } - public static NonGenericWrapper GetWrapper() => GetWrapper(typeof(T)); - - protected internal NonGenericWrapper() { } - protected readonly Dictionary Properties = new Dictionary(); - protected Dictionary Fields = new Dictionary(); - protected readonly Dictionary StaticProperties = new Dictionary(); - protected readonly Dictionary StaticFields = new Dictionary(); - protected readonly PropertyInfo InjectContextName = null; - protected readonly bool SupportedNameWrap; - protected internal NonGenericWrapper(Type type) + + /// + /// Выключает неявные приведения при разворачивании для данного элемента + /// + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] + public sealed class StrongUnwrapAttribute : Attribute { - this.type = type; - Wrappers.Add(type, this); - typename = type.Name; - var props = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); - foreach (var property in props) - { - if (Attribute.IsDefined(property, typeof(WrapperContextNameAttribute))) InjectContextName = property; - if (Attribute.IsDefined(property, typeof(WrapperSkipAttribute))) continue; - else Properties[property.Name] = property; - } - var fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); - foreach (var field in fields) - { - if (Attribute.IsDefined(field, typeof(WrapperSkipAttribute))) continue; - else Fields[field.Name] = field; - } - var static_props = type.GetProperties(BindingFlags.Static | BindingFlags.Public); - foreach (var property in static_props) - { - if (Attribute.IsDefined(property, typeof(WrapperSkipAttribute))) continue; - //else if (Attribute.IsDefined(property, typeof(WrappeContextNameAttribute))) InjectContextName = property; - else StaticProperties[property.Name] = property; - } - var static_fields = type.GetFields(BindingFlags.Static | BindingFlags.Public); - foreach (var field in static_fields) - { - if (Attribute.IsDefined(field, typeof(WrapperSkipAttribute))) continue; - else StaticFields[field.Name] = field; - } - if (InjectContextName != null) SupportedNameWrap = InjectContextName.SetMethod != null; + } - public bool HasName() => InjectContextName != null; - public string GetName(object obj) + /// + /// Выключает неявные приведения при сворачивании для данного элемента + /// + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] + public sealed class StrongWrapAttribute : Attribute { - if (InjectContextName != null) return (string)InjectContextName.GetValue(obj); - throw new ArgumentException($"Type {typename} doesn't have property with InjectContextName"); + } - public ExecutionContext Wrap(object obj) + + /// + /// Заставляет элемент проводить разворачивание и сворачивание словно контекст + /// + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] + public sealed class ContextAttribute : Attribute { - var ret = new ExecutionContext(); - ret.Name = SupportedNameWrap ? InjectContextName.GetValue(obj).ToString() : GetWrappedContextName(); - foreach (var x in Properties) - ret.LocalVariables.SetValue(x.Key, WrapCast(x.Value.GetValue(obj))); - foreach (var x in Fields) - ret.LocalVariables.SetValue(x.Key, WrapCast(x.Value.GetValue(obj))); - return ret; + } - public ExecutionContext WrapStatic() + + /// + /// Позволяет свернуть этот readonly-элемент в контекст + /// + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)] + public sealed class WrapReadonlyAttribute : Attribute { - var ret = new ExecutionContext(); - ret.Name = GetWrappedContextName(); - foreach (var x in StaticProperties) - ret.LocalVariables.SetValue(x.Key, WrapCast(x.Value.GetValue(null))); - foreach (var x in StaticFields) - ret.LocalVariables.SetValue(x.Key, WrapCast(x.Value.GetValue(null))); - return ret; + + } + + /// + /// Задаёт конструктор, который будет использован при разворачивании + /// + [AttributeUsage(AttributeTargets.Constructor, Inherited = false, AllowMultiple = false)] + public sealed class ConstructorAttribute : Attribute + { + + } + + /// + /// Выделяет метод, возвращающий аргументы для конструктора + /// сигнатуры static Func<ExecutionContext, object[]> + /// + [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)] + public sealed class ConstructorArgsAttribute : Attribute + { + + } + + private class WrappingMemberInfo + { + public MemberInfo MemberInfo; + public bool IsStrongWrap; + public bool IsStrongUnwrap; + public bool IsWrapReadonly; + public bool IsContext; + public bool IsField; + public int id = 0; + } + + + private static void GetElementFromContext(ILGenerator il, WrappingMemberInfo wmi) + { + } - public void SafeUnwrapStatic(ExecutionContext context) + + /// + /// + /// + /// + /// (элементы, элемент-имя, конструктор, метод для аргументов конструктора) + private static (List, WrappingMemberInfo, ConstructorInfo, MethodInfo) Collect(Type type) { - foreach (var name in context.LocalVariables.GetAsDictionary()) + var ret = new List(); + var name = default(WrappingMemberInfo); + var constructor = default(ConstructorInfo); + var constructorargs = default(MethodInfo); + var id = 0; + + void Check(MemberInfo member) { - try + switch (member.MemberType) { - if (Properties.ContainsKey(name.Key) && Properties[name.Key].SetMethod != null) - Properties[name.Key].SetValue(null, UnwrapCast(Properties[name.Key].PropertyType, name.Value)); - else if (Fields.ContainsKey(name.Key)) Fields[name.Key].SetValue(null, UnwrapCast(Fields[name.Key].FieldType, name.Value)); + case MemberTypes.Field: + { + var field = (FieldInfo)member; + if (field.IsInitOnly && member.GetCustomAttribute() == null) return; + var m = new WrappingMemberInfo + { + MemberInfo = member, + IsWrapReadonly = field.IsInitOnly, + IsContext = member.GetCustomAttribute() != null, + IsStrongUnwrap = member.GetCustomAttribute() != null, + IsStrongWrap = member.GetCustomAttribute() != null, + IsField = true, + id = id++, + }; + if (member.GetCustomAttribute() == null) ret.Add(m); + else + { + if (field.IsInitOnly) throw new NotSupportedException($"Wrapper.Name cannot be readonly [{field}]"); + if (name != null) throw new NotSupportedException($"Wrapper.Name has already been defined [{field}]"); + name = m; + id--; + } + } + break; + case MemberTypes.Property: + { + var property = (PropertyInfo)member; + if (!property.CanRead) return; + if (!property.CanWrite && member.GetCustomAttribute() == null) return; + var m = new WrappingMemberInfo + { + MemberInfo = member, + IsWrapReadonly = !property.CanWrite, + IsContext = member.GetCustomAttribute() != null, + IsStrongUnwrap = member.GetCustomAttribute() != null, + IsStrongWrap = member.GetCustomAttribute() != null, + id = id++, + }; + if (member.GetCustomAttribute() == null) ret.Add(m); + else + { + if (!property.CanWrite) throw new NotSupportedException($"Wrapper.Name cannot be readonly [{property}]"); + if (name != null) throw new NotSupportedException($"Wrapper.Name has already been defined [{property}]"); + name = m; + id--; + } + } + break; + case MemberTypes.Constructor: + { + var ctor = (ConstructorInfo)member; + if (ctor.GetParameters().Length == 0) + { + constructor = ctor; + return; + } + if (member.GetCustomAttribute(typeof(ConstructorAttribute)) == null) return; + if (constructor != null && constructor.GetParameters().Length != 0) throw new NotSupportedException($"Explicit constructor has already been defined [{constructor}]"); + constructor = ctor; + } + break; } - catch (Exception e) + } + + void CheckCtorArgs(MemberInfo member) + { + switch (member.MemberType) { - context.Errors.Add(e); + case MemberTypes.Method: + { + if (member.GetCustomAttribute() == null) return; + var method = (MethodInfo)member; + var pars = method.GetParameters(); + if (method.ReturnType != typeof(object[]) || !(pars.Length == 1 && pars[0].ParameterType == ContextType)) throw new NotSupportedException($"Wrong signature... [{method}]"); + constructorargs = method; + } + break; } } - } - public void UnwrapStatic(ExecutionContext context) - { - foreach (var name in context.LocalVariables.GetAsDictionary()) + + foreach (var member in type.GetMembers(BindingFlags.Public | BindingFlags.Instance)) { - if (Properties.ContainsKey(name.Key) && Properties[name.Key].SetMethod != null) - Properties[name.Key].SetValue(null, UnwrapCast(Properties[name.Key].PropertyType, name.Value)); - else if (Fields.ContainsKey(name.Key)) Fields[name.Key].SetValue(null, UnwrapCast(Fields[name.Key].FieldType, name.Value)); + if (member.GetCustomAttribute() != null) continue; + Check(member); } - } - public ExecutionContext WrapStaticClass() - { - var ret = new ExecutionContext(); - ret.Name = GetWrappedContextName(); - var props = StaticProperties; - var fields = StaticFields; - foreach (var x in props) - ret.LocalVariables.SetValue(x.Key, x.Value.GetValue(null)); - foreach (var x in fields) - ret.LocalVariables.SetValue(x.Key, x.Value.GetValue(null)); - return ret; - } - public void UnwrapStaticClass(ExecutionContext context) - { - var props = StaticProperties; - var fields = StaticFields; - foreach (var name in context.LocalVariables.GetAsDictionary()) + + foreach (var member in type.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)) { - if (props.ContainsKey(name.Key) && props[name.Key].SetMethod != null) - props[name.Key].SetValue(null, UnwrapCast(props[name.Key].PropertyType, name.Value)); - else if (fields.ContainsKey(name.Key)) fields[name.Key].SetValue(null, UnwrapCast(fields[name.Key].FieldType, name.Value)); + if (member.GetCustomAttribute() != null) continue; + CheckCtorArgs(member); } + + if (constructor != null && constructor.GetParameters().Length != 0 && constructorargs == null) + { + throw new NotSupportedException($"{type.Name} must have Wrapper.ConstructorArgs method because it has an explicit constructor"); + } + + return (ret, name, constructor, constructorargs); } - public void SafeUnwrapStaticClass(ExecutionContext context) + + private static Type ContextType = typeof(ExecutionContext); + private static Type LocalsType = typeof(LocalVariablesContainer); + private static Type Void = typeof(void); + + internal static (Delegate, Delegate, Delegate, Delegate, Delegate, Delegate, Dictionary) InitWrapper(Type type) { - var props = StaticProperties; - var fields = StaticFields; - foreach (var name in context.LocalVariables.GetAsDictionary()) + var (elems, nameelem, explicit_constructor, explicit_constructor_args) = Collect(type); + + Type GetElementType(WrappingMemberInfo elem) => elem.IsField ? ((FieldInfo)elem.MemberInfo).FieldType : ((PropertyInfo)elem.MemberInfo).PropertyType; + void LoadElement(WrappingMemberInfo elem, ILGenerator il) + { + if (elem.IsField) il.Emit(OpCodes.Ldfld, (FieldInfo)elem.MemberInfo); + else il.Emit(OpCodes.Callvirt, ((PropertyInfo)elem.MemberInfo).GetAccessors(true)[0]); + } + + void SetElement(WrappingMemberInfo elem, ILGenerator il) { - try + if (elem.IsField) il.Emit(OpCodes.Stfld, (FieldInfo)elem.MemberInfo); + else il.Emit(OpCodes.Callvirt, ((PropertyInfo)elem.MemberInfo).GetAccessors(true)[1]); + } + + var quickwrapper = default(Delegate); + { + var wrapper_dm = new DynamicMethod("QuickWrapper", Void, new Type[] { type, ContextType, LocalsType }); + var wrapper_il = wrapper_dm.GetILGenerator(); + + if (elems.Count > 0) { - if (props.ContainsKey(name.Key) && props[name.Key].SetMethod != null) - props[name.Key].SetValue(null, UnwrapCast(props[name.Key].PropertyType, name.Value)); - else if (fields.ContainsKey(name.Key)) fields[name.Key].SetValue(null, UnwrapCast(fields[name.Key].FieldType, name.Value)); + wrapper_il.Emit(OpCodes.Ldarg_2); + wrapper_il.Emit(OpCodes.Ldfld, LocalsType.GetField("Variables", BindingFlags.Public | BindingFlags.Instance)); } - catch (Exception e) + + for (var i = 0; i < elems.Count; i++) { - context.Errors.Add(e); + if (i < elems.Count - 1) wrapper_il.Emit(OpCodes.Dup); + wrapper_il.Emit(OpCodes.Ldc_I4, elems[i].id); + + wrapper_il.Emit(OpCodes.Ldarg_0); + LoadElement(elems[i], wrapper_il); + + var elem_type = GetElementType(elems[i]); + if (elems[i].IsContext) + { + wrapper_il.Emit(OpCodes.Ldarg_1); + wrapper_il.Emit(OpCodes.Call, typeof(Wrapper<>).MakeGenericType(new Type[] { elem_type }).GetMethod("WrapUnder", BindingFlags.Public | BindingFlags.Static)); + } + else + { + if (elem_type.IsValueType) + wrapper_il.Emit(OpCodes.Box, elem_type); + } + if (!elems[i].IsStrongWrap && HasRecast(elem_type)) + wrapper_il.Emit(OpCodes.Call, typeof(Wrapper).GetMethod("WrapCast", BindingFlags.Public | BindingFlags.Static)); + + wrapper_il.Emit(OpCodes.Stelem_Ref); } + + wrapper_il.Emit(OpCodes.Ret); + quickwrapper = wrapper_dm.CreateDelegate(typeof(Action<,,>).MakeGenericType(new Type[] { type, ContextType, LocalsType })); } - } - public object Unwrap(ExecutionContext context) - { - var ret = Activator.CreateInstance(type); - InjectContextName?.SetValue(ret, context.Name); - foreach (var name in context.LocalVariables.GetAsDictionary()) + + var safewrapper = default(Delegate); { - if (Properties.ContainsKey(name.Key) && Properties[name.Key].SetMethod != null) - Properties[name.Key].SetValue(ret, UnwrapCast(Properties[name.Key].PropertyType, name.Value)); - else if (Fields.ContainsKey(name.Key)) Fields[name.Key].SetValue(ret, UnwrapCast(Fields[name.Key].FieldType, name.Value)); + var wrapper_dm = new DynamicMethod("SafeWrapper", Void, new Type[] { type, ContextType, LocalsType }); + var wrapper_il = wrapper_dm.GetILGenerator(); + + for (var i = 0; i < elems.Count; i++) + { + wrapper_il.Emit(OpCodes.Ldarg_2); + wrapper_il.Emit(OpCodes.Ldstr, elems[i].MemberInfo.Name); + wrapper_il.Emit(OpCodes.Ldarg_0); + LoadElement(elems[i], wrapper_il); + + var elem_type = GetElementType(elems[i]); + if (elems[i].IsContext) + { + wrapper_il.Emit(OpCodes.Ldarg_1); + wrapper_il.Emit(OpCodes.Call, typeof(Wrapper<>).MakeGenericType(new Type[] { elem_type }).GetMethod("WrapUnder", BindingFlags.Public | BindingFlags.Static)); + } + else + { + if (elem_type.IsValueType) + wrapper_il.Emit(OpCodes.Box, elem_type); + + if (!elems[i].IsStrongWrap && HasRecast(elem_type)) + wrapper_il.Emit(OpCodes.Call, typeof(Wrapper).GetMethod("WrapCast", BindingFlags.Public | BindingFlags.Static)); + } + + wrapper_il.Emit(OpCodes.Callvirt, typeof(LocalVariablesContainer).GetMethod("SetValue", new Type[] {typeof(string), typeof(object)})); + wrapper_il.Emit(OpCodes.Pop); + } + + wrapper_il.Emit(OpCodes.Ret); + safewrapper = wrapper_dm.CreateDelegate(typeof(Action<,,>).MakeGenericType(new Type[] { type, ContextType, LocalsType })); } - return ret; - } - public object SafeUnwrap(ExecutionContext context) - { - var ret = Activator.CreateInstance(type); - try + + var unwrapper = default(Delegate); { - InjectContextName?.SetValue(ret, context.Name); + var unwrapper_dm = new DynamicMethod("Unwrapper", Void, new Type[] { LocalsType, type }); + var unwrapper_il = unwrapper_dm.GetILGenerator(); + unwrapper_il.DeclareLocal(typeof(int)); + unwrapper_il.DeclareLocal(typeof(object[])); + unwrapper_il.DeclareLocal(typeof(ContextWrap)); + + unwrapper_il.Emit(OpCodes.Ldc_I4_0); + unwrapper_il.Emit(OpCodes.Stloc_0); + unwrapper_il.Emit(OpCodes.Ldarg_0); + unwrapper_il.Emit(OpCodes.Ldfld, typeof(LocalVariablesContainer).GetField("NamedIdentificators")); + unwrapper_il.Emit(OpCodes.Ldarg_0); + unwrapper_il.Emit(OpCodes.Ldfld, typeof(LocalVariablesContainer).GetField("Variables")); + unwrapper_il.Emit(OpCodes.Stloc_1); + + + var label = default(Label); + + for (var i = 0; i < elems.Count; i++) + { + if (i < elems.Count - 1) unwrapper_il.Emit(OpCodes.Dup); + + unwrapper_il.Emit(OpCodes.Ldstr, elems[i].MemberInfo.Name); + unwrapper_il.Emit(OpCodes.Ldloca_S, 0); + unwrapper_il.Emit(OpCodes.Callvirt, typeof(Dictionary).GetMethod("TryGetValue")); + unwrapper_il.Emit(OpCodes.Brfalse_S, label = unwrapper_il.DefineLabel()); + + + var elem_type = GetElementType(elems[i]); + if (elems[i].IsContext) + { + unwrapper_il.Emit(OpCodes.Ldloc_1); + unwrapper_il.Emit(OpCodes.Ldloc_0); + unwrapper_il.Emit(OpCodes.Ldelem_Ref); + unwrapper_il.Emit(OpCodes.Isinst, typeof(ContextWrap)); + unwrapper_il.Emit(OpCodes.Stloc_2); + unwrapper_il.Emit(OpCodes.Ldloc_2); + unwrapper_il.Emit(OpCodes.Brfalse_S, label); + + unwrapper_il.Emit(OpCodes.Ldarg_1); + unwrapper_il.Emit(OpCodes.Ldloc_2); + //unwrapper_il.Emit(OpCodes.Ldfld, typeof(ContextWrap).GetField("Context")); + unwrapper_il.Emit(OpCodes.Call, typeof(Wrapper<>).MakeGenericType(new Type[] { elem_type }).GetMethod("UnwrapUnder", BindingFlags.Public | BindingFlags.Static)); + SetElement(elems[i], unwrapper_il); + } + else + { + unwrapper_il.Emit(OpCodes.Ldarg_1); + unwrapper_il.Emit(OpCodes.Ldloc_1); + unwrapper_il.Emit(OpCodes.Ldloc_0); + unwrapper_il.Emit(OpCodes.Ldelem_Ref); + + if (elem_type.IsValueType) unwrapper_il.Emit(OpCodes.Unbox_Any, elem_type); + else unwrapper_il.Emit(OpCodes.Castclass, elem_type); + + if (!elems[i].IsStrongUnwrap && HasRecast(elem_type)) + unwrapper_il.Emit(OpCodes.Call, typeof(Wrapper).GetMethod("UnwrapCast", BindingFlags.Public | BindingFlags.Static)); + + SetElement(elems[i], unwrapper_il); + } + unwrapper_il.MarkLabel(label); + } + + unwrapper_il.Emit(OpCodes.Ret); + unwrapper = unwrapper_dm.CreateDelegate(typeof(Action<,>).MakeGenericType(new Type[] { LocalsType, type })); } - catch (Exception e) + + var wrapname = default(Delegate); { - context.Errors.Add(e); + var wrapname_dm = new DynamicMethod("WrapName", Void, new Type[] { type, ContextType }); + var wrapname_il = wrapname_dm.GetILGenerator(); + if (nameelem != null) + { + if (GetElementType(nameelem) != typeof(string)) throw new NotSupportedException($"Name must be string [{nameelem}]"); + + wrapname_il.Emit(OpCodes.Ldarg_1); + wrapname_il.Emit(OpCodes.Ldarg_0); + LoadElement(nameelem, wrapname_il); + + wrapname_il.Emit(OpCodes.Stfld, ContextType.GetField("Name", BindingFlags.Public | BindingFlags.Instance)); + } + wrapname_il.Emit(OpCodes.Ret); + wrapname = wrapname_dm.CreateDelegate(typeof(Action<,>).MakeGenericType(new Type[] { type, ContextType })); } - foreach (var name in context.LocalVariables.GetAsDictionary()) + + var unwrapname = default(Delegate); { - try + var wrapname_dm = new DynamicMethod("UnwrapName", Void, new Type[] { ContextType, type }); + var wrapname_il = wrapname_dm.GetILGenerator(); + if (nameelem != null) { - if (Properties.ContainsKey(name.Key) && Properties[name.Key].SetMethod != null) - Properties[name.Key].SetValue(ret, UnwrapCast(Properties[name.Key].PropertyType, name.Value)); - else if (Fields.ContainsKey(name.Key)) Fields[name.Key].SetValue(ret, UnwrapCast(Fields[name.Key].FieldType, name.Value)); + if (GetElementType(nameelem) != typeof(string)) throw new NotSupportedException($"Name must be string [{nameelem}]"); + + wrapname_il.Emit(OpCodes.Ldarg_1); + wrapname_il.Emit(OpCodes.Ldarg_0); + wrapname_il.Emit(OpCodes.Ldfld, ContextType.GetField("Name", BindingFlags.Public | BindingFlags.Instance)); + SetElement(nameelem, wrapname_il); } - catch (Exception e) + wrapname_il.Emit(OpCodes.Ret); + unwrapname = wrapname_dm.CreateDelegate(typeof(Action<,>).MakeGenericType(new Type[] { ContextType, type })); + } + + var initor = default(Delegate); + if (explicit_constructor == null) throw new NotSupportedException($"Type {type.Name} must have parameterless constructor"); + if (explicit_constructor.GetParameters().Length > 0) + { + var initor_dm = new DynamicMethod("Initor", type, new Type[1] { ContextType }, true); + var initor_il = initor_dm.GetILGenerator(); + initor_il.Emit(OpCodes.Ldarg_0); + initor_il.Emit(OpCodes.Call, explicit_constructor_args); + initor_il.DeclareLocal(typeof(object[])); + initor_il.Emit(OpCodes.Stloc_0); + var i = 0; + foreach (var p in explicit_constructor.GetParameters()) { - context.Errors.Add(e); + initor_il.Emit(OpCodes.Ldloc_0); + initor_il.Emit(OpCodes.Ldc_I4, i++); + initor_il.Emit(OpCodes.Ldelem_Ref); + if (p.ParameterType.IsValueType) initor_il.Emit(OpCodes.Unbox_Any, p.ParameterType); + else initor_il.Emit(OpCodes.Castclass, p.ParameterType); } + initor_il.Emit(OpCodes.Newobj, explicit_constructor); + initor_il.Emit(OpCodes.Ret); + initor = initor_dm.CreateDelegate(typeof(Func<,>).MakeGenericType(new Type[] { ContextType, type })); } - return ret; + else + { + var initor_dm = new DynamicMethod("Initor", type, new Type[1] { ContextType }, true); + var initor_il = initor_dm.GetILGenerator(); + initor_il.Emit(OpCodes.Newobj, explicit_constructor); + initor_il.Emit(OpCodes.Ret); + initor = initor_dm.CreateDelegate(typeof(Func<,>).MakeGenericType(new Type[] { ContextType, type })); + } + + return (quickwrapper, safewrapper, unwrapper, wrapname, unwrapname, initor, elems.ToDictionary(x => x.MemberInfo.Name, x => x.id)); + throw new NotImplementedException(); } + + public static ExecutionContext Wrap(this T obj) => Wrapper.Wrap(obj); + public static T Unwrap(this ExecutionContext context) => Wrapper.Unwrap(context); + public static void WrapIn(this T obj, ExecutionContext context) => Wrapper.WrapIn(obj, context); + public static void UnwrapIn(this ExecutionContext context, T obj) => Wrapper.UnwrapIn(context, obj); } public static class Wrapper { - private static readonly NonGenericWrapper wrapper; - static Wrapper() - { - wrapper = NonGenericWrapper.GetWrapper(typeof(T)); - } - public static T Unwrap(ExecutionContext context) => (T)wrapper.Unwrap(context); - public static void UnwrapStatic(ExecutionContext context) => wrapper.UnwrapStatic(context); - public static ExecutionContext Wrap(T value) => wrapper.Wrap(value); - public static ExecutionContext WrapStatic() => wrapper.WrapStatic(); + public static readonly Func Initor; + //Быстрое оборачивание заполняет переменные по отступу + public static readonly Action QuickWrapper; + //Безопасное оборачивание заполняет переменные по имени + public static readonly Action SafeWrapper; + public static readonly Action Unwrapper; - public static T SafeUnwrap(ExecutionContext context) => (T)wrapper.SafeUnwrap(context); - public static void SafeUnwrapStatic(ExecutionContext context) => wrapper.SafeUnwrapStatic(context); - } + public static readonly Action WrapName; + public static readonly Action UnwrapName; - /// - /// Это свойство будет пропущено при разворачивании - /// - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = false, AllowMultiple = false)] - public sealed class WrapperSkipAttribute : Attribute - { - public WrapperSkipAttribute() { } - } + public static readonly Dictionary ContextNames; + public static readonly string[] Names; + public static readonly int ContextSize; - /// - /// В это свойство типа string будет вписано имя контекста - /// - [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] - public sealed class WrapperContextNameAttribute : Attribute - { - public WrapperContextNameAttribute() { } + static Wrapper() + { + var d = Wrapper.InitWrapper(typeof(T)); + QuickWrapper = (Action)d.Item1; + SafeWrapper = (Action)d.Item2; + Unwrapper = (Action)d.Item3; + WrapName = (Action)d.Item4; + UnwrapName = (Action)d.Item5; + Initor = (Func)d.Item6; + ContextNames = d.Item7; + Names = ContextNames.Keys.ToArray(); + ContextSize = ContextNames.Count; + } + + public static ExecutionContext Wrap(T obj) + { + var lc = new LocalVariablesContainer(ContextSize, new Dictionary(ContextNames)); + var ret = new ExecutionContext(false, false, lc); + QuickWrapper(obj, ret, lc); + WrapName(obj, ret); + return ret; + } + public static ContextWrap WrapUnder(T obj, ExecutionContext context) + { + if (obj == null) return null; + if (Wrapper.HasRecast(obj.GetType())) throw new NotSupportedException("This type can't be converted into context"); + var lc = new LocalVariablesContainer(ContextSize, new Dictionary(ContextNames)); + var ret = new ExecutionContext(context, false, lc); + QuickWrapper(obj, ret, lc); + WrapName(obj, ret); + return ret.wrap; + } + public static T Unwrap(ExecutionContext context) + { + var ret = Initor(context); + UnwrapName(context, ret); + Unwrapper(context.LocalVariables, ret); + return ret; + } + public static T UnwrapUnder(ContextWrap context) => Unwrap(context.Context); + public static void WrapIn(T obj, ExecutionContext context) + { + SafeWrapper(obj, context, context.LocalVariables); + WrapName(obj, context); + } + public static void UnwrapIn(ExecutionContext context, T obj) + { + Unwrapper(context.LocalVariables, obj); + UnwrapName(context, obj); + } } } diff --git a/SLThree/sys/console.cs b/SLThree/sys/console.cs index bba3cbe..bab2a43 100644 --- a/SLThree/sys/console.cs +++ b/SLThree/sys/console.cs @@ -1,11 +1,13 @@ -using System; +using SLThree.Extensions; +using System; +using System.Linq; namespace SLThree.sys { #pragma warning disable IDE1006 // Стили именования public static class console { - public static ContextWrap color = new ContextWrap(Wrapper.WrapStatic()); + public static ContextWrap color = new ContextWrap(new ExecutionContext(false, false, Enum.GetNames(typeof(ConsoleColor)).ToDictionary(x => x, x => Enum.Parse(typeof(ConsoleColor), x)).ToLocals())); public static string readln() => Console.ReadLine(); public static void write(object o) => Console.Write(o); public static void writeln() => Console.WriteLine(); From 21f040bb1175c4660a6b251b38313c88303bc2f5 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Sat, 1 Jun 2024 15:46:30 +0300 Subject: [PATCH 04/69] static wrappers --- SLThree/Extensions/SLTHelpers.cs | 22 -- SLThree/JIT/NETGenerator.cs | 84 +++++- SLThree/SLThree.csproj | 2 +- SLThree/Wrapper.cs | 423 ++++++++++++++++++++++++++++++- SLThree/sys/console.cs | 2 +- 5 files changed, 492 insertions(+), 41 deletions(-) diff --git a/SLThree/Extensions/SLTHelpers.cs b/SLThree/Extensions/SLTHelpers.cs index 9f31867..b2fcbbc 100644 --- a/SLThree/Extensions/SLTHelpers.cs +++ b/SLThree/Extensions/SLTHelpers.cs @@ -197,31 +197,9 @@ public static object CastToType(this object o, Type casting_type) if (casting_type == typeof(string)) return o.ToString(); - /*if (casting_type == type_context) - { - if (o is Type st_type) - return - st_type.IsAbstract && st_type.IsSealed - ? new ContextWrap(NonGenericWrapper.GetWrapper(st_type).WrapStaticClass()) - : new ContextWrap(NonGenericWrapper.GetWrapper(st_type).WrapStatic()); - else - return new ContextWrap(NonGenericWrapper.GetWrapper(o.GetType()).Wrap(o)); - }*/ var type = o.GetType(); if (type == casting_type) return o; if (o is IConvertible) return Convert.ChangeType(o, casting_type); - //todo make sys.wrapper instead - /*if (type == type_context) - { - var wrapper = NonGenericWrapper.GetWrapper(casting_type); - if (casting_type.IsAbstract) - { - if (casting_type.IsSealed) wrapper.UnwrapStaticClass(((ContextWrap)o).Context); - else wrapper.UnwrapStatic(((ContextWrap)o).Context); - return null; - } - else return wrapper.Unwrap(((ContextWrap)o).Context); - }*/ if (casting_type.IsEnum) { if (type == type_string) return Enum.Parse(casting_type, (string)o); diff --git a/SLThree/JIT/NETGenerator.cs b/SLThree/JIT/NETGenerator.cs index 30f187f..050cc0e 100644 --- a/SLThree/JIT/NETGenerator.cs +++ b/SLThree/JIT/NETGenerator.cs @@ -2,16 +2,10 @@ using SLThree.sys; using SLThree.Visitors; using System; -using System.CodeDom; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Reflection.Emit; -using System.Security.AccessControl; -using System.Security.Permissions; -using System.Text; -using System.Threading; -using System.Threading.Tasks; namespace SLThree.JIT { @@ -145,6 +139,84 @@ public void VisitLiteral(int literal) } } + public static void EmitLoadStaticFieldOrConst(FieldInfo fieldInfo, ILGenerator il) + { + if (fieldInfo.Attributes.HasFlag(FieldAttributes.HasDefault) && fieldInfo.Attributes.HasFlag(FieldAttributes.Literal)) + { + var value = fieldInfo.GetRawConstantValue(); + if (value is Enum) value = value.CastToType(Enum.GetUnderlyingType(fieldInfo.FieldType)); + switch (value) + { + case long i64: + if (i64 >= int.MinValue && i64 <= int.MaxValue) + { + il.Emit(OpCodes.Ldc_I4, (int)i64); + il.Emit(OpCodes.Conv_I8); + } + else + { + il.Emit(OpCodes.Ldc_I8, i64); + } + break; + case ulong u64: + if (u64 >= 0 && u64 <= int.MaxValue) + { + il.Emit(OpCodes.Ldc_I4, (int)u64); + il.Emit(OpCodes.Conv_I8); + } + else + { + il.Emit(OpCodes.Ldc_I8, unchecked((long)u64)); + } + break; + case int i32: + il.Emit(OpCodes.Ldc_I4, i32); + break; + case uint u32: + il.Emit(OpCodes.Ldc_I4, unchecked((int)u32)); + break; + case float f32: + il.Emit(OpCodes.Ldc_R4, f32); + break; + case double f64: + il.Emit(OpCodes.Ldc_R8, f64); + break; + case short i: + il.Emit(OpCodes.Ldc_I4, (int)i); + il.Emit(OpCodes.Conv_I2); + break; + case ushort i: + il.Emit(OpCodes.Ldc_I4, (int)i); + il.Emit(OpCodes.Conv_I2); + break; + case sbyte i: + il.Emit(OpCodes.Ldc_I4, (int)i); + il.Emit(OpCodes.Conv_I1); + break; + case byte i: + il.Emit(OpCodes.Ldc_I4, (int)i); + il.Emit(OpCodes.Conv_I1); + break; + case bool b: + if (b) + il.Emit(OpCodes.Ldc_I4_1); + else + il.Emit(OpCodes.Ldc_I4_0); + il.Emit(OpCodes.Conv_I1); + break; + case string s: + il.Emit(OpCodes.Ldstr, s); + break; + default: + throw new NotSupportedException($"{fieldInfo.FieldType} of constant not supported"); + } + } + else + { + il.Emit(OpCodes.Ldsfld, fieldInfo); + } + } + public override void VisitExpression(Literal expression) { switch (expression) diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 76a4b0a..ea67f35 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -13,7 +13,7 @@ git language;scripts;script-lang True - 0.7.0.3066 + 0.7.0.3082 $(Version) $(Version) slthree.ico diff --git a/SLThree/Wrapper.cs b/SLThree/Wrapper.cs index 2e095b8..2a69ad0 100644 --- a/SLThree/Wrapper.cs +++ b/SLThree/Wrapper.cs @@ -1,12 +1,15 @@ using SLThree.Extensions; +using SLThree.JIT; using SLThree.sys; using System; using System.Collections; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; +using System.Threading; namespace SLThree { @@ -273,12 +276,6 @@ private class WrappingMemberInfo public int id = 0; } - - private static void GetElementFromContext(ILGenerator il, WrappingMemberInfo wmi) - { - - } - /// /// /// @@ -382,7 +379,7 @@ void CheckCtorArgs(MemberInfo member) Check(member); } - foreach (var member in type.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)) + foreach (var member in type.GetMembers(BindingFlags.Public | BindingFlags.Static)) { if (member.GetCustomAttribute() != null) continue; CheckCtorArgs(member); @@ -395,26 +392,292 @@ void CheckCtorArgs(MemberInfo member) return (ret, name, constructor, constructorargs); } + private static (List, WrappingMemberInfo) CollectStatic(Type type) + { + var ret = new List(); + var name = default(WrappingMemberInfo); + var id = 0; + + void Check(MemberInfo member) + { + switch (member.MemberType) + { + case MemberTypes.Field: + { + var field = (FieldInfo)member; + if (field.IsInitOnly && member.GetCustomAttribute() == null) return; + var m = new WrappingMemberInfo + { + MemberInfo = member, + IsWrapReadonly = type.IsEnum ? true : field.IsInitOnly, + IsContext = member.GetCustomAttribute() != null, + IsStrongUnwrap = member.GetCustomAttribute() != null, + IsStrongWrap = member.GetCustomAttribute() != null, + IsField = true, + id = id++, + }; + if (member.GetCustomAttribute() == null) ret.Add(m); + else + { + if (field.IsInitOnly) throw new NotSupportedException($"StaticWrapper.Name cannot be readonly [{field}]"); + if (name != null) throw new NotSupportedException($"StaticWrapper.Name has already been defined [{field}]"); + name = m; + id--; + } + } + break; + case MemberTypes.Property: + { + var property = (PropertyInfo)member; + if (!property.CanRead) return; + if (!property.CanWrite && member.GetCustomAttribute() == null) return; + var m = new WrappingMemberInfo + { + MemberInfo = member, + IsWrapReadonly = !property.CanWrite, + IsContext = member.GetCustomAttribute() != null, + IsStrongUnwrap = member.GetCustomAttribute() != null, + IsStrongWrap = member.GetCustomAttribute() != null, + id = id++, + }; + if (member.GetCustomAttribute() == null) ret.Add(m); + else + { + if (!property.CanWrite) throw new NotSupportedException($"StaticWrapper.Name cannot be readonly [{property}]"); + if (name != null) throw new NotSupportedException($"StaticWrapper.Name has already been defined [{property}]"); + name = m; + id--; + } + } + break; + } + } + + foreach (var member in type.GetMembers(BindingFlags.Public | BindingFlags.Static)) + { + if (member.GetCustomAttribute() != null) continue; + Check(member); + } + + return (ret, name); + } private static Type ContextType = typeof(ExecutionContext); private static Type LocalsType = typeof(LocalVariablesContainer); private static Type Void = typeof(void); + internal static MethodInfo GetPropertyGetter(PropertyInfo propertyInfo) => propertyInfo.GetAccessors(false).FirstOrDefault(x => x.ReturnType != Void); + internal static MethodInfo GetPropertySetter(PropertyInfo propertyInfo) => propertyInfo.GetAccessors(false).FirstOrDefault(x => x.ReturnType == Void); + private static Type GetElementType(WrappingMemberInfo elem) => elem.IsField ? ((FieldInfo)elem.MemberInfo).FieldType : ((PropertyInfo)elem.MemberInfo).PropertyType; + + internal static (Delegate, Delegate, Delegate, Delegate, Delegate, Dictionary) InitStaticWrapper(Type type) + { + var (elems, nameelem) = CollectStatic(type); + + void LoadElement(WrappingMemberInfo elem, ILGenerator il) + { + if (elem.IsField) + { + NETGenerator.EmitLoadStaticFieldOrConst((FieldInfo)elem.MemberInfo, il); + } + else il.Emit(OpCodes.Callvirt, GetPropertyGetter((PropertyInfo)elem.MemberInfo)); + } + + void SetElement(WrappingMemberInfo elem, ILGenerator il) + { + if (elem.IsField) il.Emit(OpCodes.Stsfld, (FieldInfo)elem.MemberInfo); + else il.Emit(OpCodes.Callvirt, GetPropertySetter((PropertyInfo)elem.MemberInfo)); + } + + var quickwrapper = default(Delegate); + { + var wrapper_dm = new DynamicMethod("QuickWrapper", Void, new Type[2] { ContextType, LocalsType }); + var wrapper_il = wrapper_dm.GetILGenerator(); + + if (elems.Count > 0) + { + wrapper_il.Emit(OpCodes.Ldarg_1); + wrapper_il.Emit(OpCodes.Ldfld, LocalsType.GetField("Variables")); + } + for (var i = 0; i < elems.Count; i++) + { + if (i < elems.Count - 1) wrapper_il.Emit(OpCodes.Dup); + wrapper_il.Emit(OpCodes.Ldc_I4, elems[i].id); + LoadElement(elems[i], wrapper_il); + + var elem_type = GetElementType(elems[i]); + if (elems[i].IsContext) + { + wrapper_il.Emit(OpCodes.Ldarg_1); + wrapper_il.Emit(OpCodes.Call, typeof(Wrapper<>).MakeGenericType(new Type[] { elem_type }).GetMethod("WrapUnder", BindingFlags.Public | BindingFlags.Static)); + } + else + { + if (elem_type.IsValueType) + wrapper_il.Emit(OpCodes.Box, elem_type); + } + if (!elems[i].IsStrongWrap && HasRecast(elem_type)) + wrapper_il.Emit(OpCodes.Call, typeof(Wrapper).GetMethod("WrapCast", BindingFlags.Public | BindingFlags.Static)); + + wrapper_il.Emit(OpCodes.Stelem_Ref); + } + + wrapper_il.Emit(OpCodes.Ret); + quickwrapper = wrapper_dm.CreateDelegate(typeof(Action<,>).MakeGenericType(new Type[2] { ContextType, LocalsType })); + } + + var safewrapper = default(Delegate); + { + var wrapper_dm = new DynamicMethod("SafeWrapper", Void, new Type[] { ContextType, LocalsType }); + var wrapper_il = wrapper_dm.GetILGenerator(); + + for (var i = 0; i < elems.Count; i++) + { + wrapper_il.Emit(OpCodes.Ldarg_1); + wrapper_il.Emit(OpCodes.Ldstr, elems[i].MemberInfo.Name); + LoadElement(elems[i], wrapper_il); + + var elem_type = GetElementType(elems[i]); + if (elems[i].IsContext) + { + wrapper_il.Emit(OpCodes.Ldarg_0); + wrapper_il.Emit(OpCodes.Call, typeof(Wrapper<>).MakeGenericType(new Type[] { elem_type }).GetMethod("WrapUnder", BindingFlags.Public | BindingFlags.Static)); + } + else + { + if (elem_type.IsValueType) + wrapper_il.Emit(OpCodes.Box, elem_type); + + if (!elems[i].IsStrongWrap && HasRecast(elem_type)) + wrapper_il.Emit(OpCodes.Call, typeof(Wrapper).GetMethod("WrapCast", BindingFlags.Public | BindingFlags.Static)); + } + + wrapper_il.Emit(OpCodes.Callvirt, typeof(LocalVariablesContainer).GetMethod("SetValue", new Type[] { typeof(string), typeof(object) })); + wrapper_il.Emit(OpCodes.Pop); + } + + wrapper_il.Emit(OpCodes.Ret); + safewrapper = wrapper_dm.CreateDelegate(typeof(Action<,>).MakeGenericType(new Type[] { ContextType, LocalsType })); + } + + var unwrapper = default(Delegate); + { + var unwrapper_dm = new DynamicMethod("Unwrapper", Void, new Type[] { LocalsType }); + var unwrapper_il = unwrapper_dm.GetILGenerator(); + unwrapper_il.DeclareLocal(typeof(int)); + unwrapper_il.DeclareLocal(typeof(object[])); + unwrapper_il.DeclareLocal(typeof(ContextWrap)); + + unwrapper_il.Emit(OpCodes.Ldc_I4_0); + unwrapper_il.Emit(OpCodes.Stloc_0); + unwrapper_il.Emit(OpCodes.Ldarg_0); + unwrapper_il.Emit(OpCodes.Ldfld, typeof(LocalVariablesContainer).GetField("NamedIdentificators")); + unwrapper_il.Emit(OpCodes.Ldarg_0); + unwrapper_il.Emit(OpCodes.Ldfld, typeof(LocalVariablesContainer).GetField("Variables")); + unwrapper_il.Emit(OpCodes.Stloc_1); + + + var label = default(Label); + + for (var i = 0; i < elems.Count; i++) + { + if (elems[i].IsWrapReadonly) continue; + if (i < elems.Count - 1) unwrapper_il.Emit(OpCodes.Dup); + + unwrapper_il.Emit(OpCodes.Ldstr, elems[i].MemberInfo.Name); + unwrapper_il.Emit(OpCodes.Ldloca_S, 0); + unwrapper_il.Emit(OpCodes.Callvirt, typeof(Dictionary).GetMethod("TryGetValue")); + unwrapper_il.Emit(OpCodes.Brfalse_S, label = unwrapper_il.DefineLabel()); + + + var elem_type = GetElementType(elems[i]); + if (elems[i].IsContext) + { + unwrapper_il.Emit(OpCodes.Ldloc_1); + unwrapper_il.Emit(OpCodes.Ldloc_0); + unwrapper_il.Emit(OpCodes.Ldelem_Ref); + unwrapper_il.Emit(OpCodes.Isinst, typeof(ContextWrap)); + unwrapper_il.Emit(OpCodes.Stloc_2); + unwrapper_il.Emit(OpCodes.Ldloc_2); + unwrapper_il.Emit(OpCodes.Brfalse_S, label); + + unwrapper_il.Emit(OpCodes.Ldloc_2); + //unwrapper_il.Emit(OpCodes.Ldfld, typeof(ContextWrap).GetField("Context")); + unwrapper_il.Emit(OpCodes.Call, typeof(Wrapper<>).MakeGenericType(new Type[] { elem_type }).GetMethod("UnwrapUnder", BindingFlags.Public | BindingFlags.Static)); + SetElement(elems[i], unwrapper_il); + } + else + { + unwrapper_il.Emit(OpCodes.Ldloc_1); + unwrapper_il.Emit(OpCodes.Ldloc_0); + unwrapper_il.Emit(OpCodes.Ldelem_Ref); + + if (elem_type.IsValueType) unwrapper_il.Emit(OpCodes.Unbox_Any, elem_type); + else unwrapper_il.Emit(OpCodes.Castclass, elem_type); + + if (!elems[i].IsStrongUnwrap && HasRecast(elem_type)) + unwrapper_il.Emit(OpCodes.Call, typeof(Wrapper).GetMethod("UnwrapCast", BindingFlags.Public | BindingFlags.Static)); + + SetElement(elems[i], unwrapper_il); + } + unwrapper_il.MarkLabel(label); + } + + unwrapper_il.Emit(OpCodes.Ret); + unwrapper = unwrapper_dm.CreateDelegate(typeof(Action<>).MakeGenericType(new Type[] { LocalsType })); + } + + var wrapname = default(Delegate); + { + var wrapname_dm = new DynamicMethod("WrapName", Void, new Type[] { ContextType }); + var wrapname_il = wrapname_dm.GetILGenerator(); + if (nameelem != null) + { + if (GetElementType(nameelem) != typeof(string)) throw new NotSupportedException($"Name must be string [{nameelem}]"); + + wrapname_il.Emit(OpCodes.Ldarg_1); + LoadElement(nameelem, wrapname_il); + + wrapname_il.Emit(OpCodes.Stfld, ContextType.GetField("Name", BindingFlags.Public | BindingFlags.Instance)); + } + wrapname_il.Emit(OpCodes.Ret); + wrapname = wrapname_dm.CreateDelegate(typeof(Action<>).MakeGenericType(new Type[] { ContextType })); + } + + var unwrapname = default(Delegate); + { + var wrapname_dm = new DynamicMethod("UnwrapName", Void, new Type[] { ContextType }); + var wrapname_il = wrapname_dm.GetILGenerator(); + if (nameelem != null) + { + if (GetElementType(nameelem) != typeof(string)) throw new NotSupportedException($"Name must be string [{nameelem}]"); + + wrapname_il.Emit(OpCodes.Ldarg_0); + wrapname_il.Emit(OpCodes.Ldfld, ContextType.GetField("Name", BindingFlags.Public | BindingFlags.Instance)); + SetElement(nameelem, wrapname_il); + } + wrapname_il.Emit(OpCodes.Ret); + unwrapname = wrapname_dm.CreateDelegate(typeof(Action<>).MakeGenericType(new Type[] { ContextType })); + } + + return (quickwrapper, safewrapper, unwrapper, wrapname, unwrapname, elems.ToDictionary(x => x.MemberInfo.Name, x => x.id)); + } internal static (Delegate, Delegate, Delegate, Delegate, Delegate, Delegate, Dictionary) InitWrapper(Type type) { + if (type.IsAbstract && type.IsSealed) throw new NotSupportedException("Non-static Wrapper not supported static classes"); + var (elems, nameelem, explicit_constructor, explicit_constructor_args) = Collect(type); - Type GetElementType(WrappingMemberInfo elem) => elem.IsField ? ((FieldInfo)elem.MemberInfo).FieldType : ((PropertyInfo)elem.MemberInfo).PropertyType; void LoadElement(WrappingMemberInfo elem, ILGenerator il) { if (elem.IsField) il.Emit(OpCodes.Ldfld, (FieldInfo)elem.MemberInfo); - else il.Emit(OpCodes.Callvirt, ((PropertyInfo)elem.MemberInfo).GetAccessors(true)[0]); + else il.Emit(OpCodes.Callvirt, GetPropertyGetter((PropertyInfo)elem.MemberInfo)); } void SetElement(WrappingMemberInfo elem, ILGenerator il) { if (elem.IsField) il.Emit(OpCodes.Stfld, (FieldInfo)elem.MemberInfo); - else il.Emit(OpCodes.Callvirt, ((PropertyInfo)elem.MemberInfo).GetAccessors(true)[1]); + else il.Emit(OpCodes.Callvirt, GetPropertySetter((PropertyInfo)elem.MemberInfo)); } var quickwrapper = default(Delegate); @@ -513,6 +776,7 @@ void SetElement(WrappingMemberInfo elem, ILGenerator il) for (var i = 0; i < elems.Count; i++) { + if (elems[i].IsWrapReadonly) continue; if (i < elems.Count - 1) unwrapper_il.Emit(OpCodes.Dup); unwrapper_il.Emit(OpCodes.Ldstr, elems[i].MemberInfo.Name); @@ -628,13 +892,100 @@ void SetElement(WrappingMemberInfo elem, ILGenerator il) } return (quickwrapper, safewrapper, unwrapper, wrapname, unwrapname, initor, elems.ToDictionary(x => x.MemberInfo.Name, x => x.id)); - throw new NotImplementedException(); } + #region Extensions public static ExecutionContext Wrap(this T obj) => Wrapper.Wrap(obj); public static T Unwrap(this ExecutionContext context) => Wrapper.Unwrap(context); public static void WrapIn(this T obj, ExecutionContext context) => Wrapper.WrapIn(obj, context); public static void UnwrapIn(this ExecutionContext context, T obj) => Wrapper.UnwrapIn(context, obj); + public static ExecutionContext StaticWrap() => StaticWrapper.Wrap(); + public static void StaticUnwrap(this ExecutionContext context) => StaticWrapper.Unwrap(context); + public static void StaticWrapIn(this ExecutionContext context) => StaticWrapper.WrapIn(context); + public static void StaticUnwrapIn(this ExecutionContext context) => StaticWrapper.UnwrapIn(context); + + public static readonly NonGenericWrapper NonGeneric = new NonGenericWrapper(typeof(object)); + public static readonly NonGenericStaticWrapper NonGenericStatic = new NonGenericStaticWrapper(typeof(object)); + public static ExecutionContext StaticWrap(this Type T) => NonGenericStatic[T].Wrap(); + public static void StaticUnwrap(this ExecutionContext context, Type T) => NonGenericStatic[T].Unwrap(context); + public static void StaticUnwrap(this Type T, ExecutionContext context) => NonGenericStatic[T].Unwrap(context); + public static void StaticWrapIn(this Type T, ExecutionContext context) => NonGenericStatic[T].WrapIn(context); + public static void StaticWrapIn(this ExecutionContext context, Type T) => NonGenericStatic[T].WrapIn(context); + public static void StaticUnwrapIn(this ExecutionContext context, Type T) => NonGenericStatic[T].UnwrapIn(context); + public static void StaticUnwrapIn(this Type T, ExecutionContext context) => NonGenericStatic[T].UnwrapIn(context); + public static ExecutionContext Wrap(this object obj, Type T) => NonGeneric[T].Wrap(obj); + public static ExecutionContext InstanceWrap(this Type T, object obj) => NonGeneric[T].Wrap(obj); + public static object Unwrap(this ExecutionContext context, Type T) => NonGeneric[T].Unwrap(context); + public static object InstanceUnwrap(this Type T, ExecutionContext context) => NonGeneric[T].Unwrap(context); + public static void WrapIn(this object obj, Type T, ExecutionContext context) => NonGeneric[T].WrapIn(obj, context); + public static void InstanceWrapIn(this Type T, object obj, ExecutionContext context) => NonGeneric[T].WrapIn(obj, context); + public static void UnwrapIn(this ExecutionContext context, Type T, object obj) => NonGeneric[T].UnwrapIn(context, obj); + public static void InstanceUnwrapIn(this Type T, ExecutionContext context, object obj) => NonGeneric[T].UnwrapIn(context, obj); + public sealed class NonGenericStaticWrapper + { + public readonly MethodInfo mWrap; + public readonly MethodInfo mUnwrap; + public readonly MethodInfo mWrapIn; + public readonly MethodInfo mUnwrapIn; + + internal NonGenericStaticWrapper(Type T) + { + var type = typeof(StaticWrapper<>).MakeGenericType(T); + mWrap = type.GetMethod("Wrap"); + mUnwrap = type.GetMethod("Unwrap"); + mWrapIn = type.GetMethod("WrapIn"); + mUnwrapIn = type.GetMethod("UnwrapIn"); + nongeneric_wrappers[T] = this; + } + + private static readonly Dictionary nongeneric_wrappers = new Dictionary(); + public NonGenericStaticWrapper this[Type type] + { + get + { + if (nongeneric_wrappers.TryGetValue(type, out var ret)) return ret; + return new NonGenericStaticWrapper(type); + } + } + + public ExecutionContext Wrap() => (ExecutionContext)mWrap.Invoke(null, Array.Empty()); + public void Unwrap(ExecutionContext context) => mUnwrap.Invoke(null, new object[] { context }); + public void WrapIn(ExecutionContext context) => mWrapIn.Invoke(null, new object[] { context }); + public void UnwrapIn(ExecutionContext context) => mUnwrapIn.Invoke(null, new object[] { context }); + } + public sealed class NonGenericWrapper + { + public readonly MethodInfo mWrap; + public readonly MethodInfo mUnwrap; + public readonly MethodInfo mWrapIn; + public readonly MethodInfo mUnwrapIn; + + internal NonGenericWrapper(Type T) + { + var type = typeof(Wrapper<>).MakeGenericType(T); + mWrap = type.GetMethod("Wrap"); + mUnwrap = type.GetMethod("Unwrap"); + mWrapIn = type.GetMethod("WrapIn"); + mUnwrapIn = type.GetMethod("UnwrapIn"); + nongeneric_wrappers[T] = this; + } + + private static readonly Dictionary nongeneric_wrappers = new Dictionary(); + public NonGenericWrapper this[Type type] + { + get + { + if (nongeneric_wrappers.TryGetValue(type, out var ret)) return ret; + return new NonGenericWrapper(type); + } + } + + public ExecutionContext Wrap(object obj) => (ExecutionContext)mWrap.Invoke(null, new object[] { obj }); + public object Unwrap(ExecutionContext context) => mUnwrap.Invoke(null, new object[] { context }); + public void WrapIn(object obj, ExecutionContext context) => mWrapIn.Invoke(null, new object[] { obj, context }); + public void UnwrapIn(ExecutionContext context, object obj) => mUnwrapIn.Invoke(null, new object[] { context, obj }); + } + #endregion } public static class Wrapper @@ -705,4 +1056,54 @@ public static void UnwrapIn(ExecutionContext context, T obj) UnwrapName(context, obj); } } + public static class StaticWrapper + { + public static readonly Action QuickWrapper; + public static readonly Action SafeWrapper; + public static readonly Action Unwrapper; + + public static readonly Action WrapName; + public static readonly Action UnwrapName; + + public static readonly Dictionary ContextNames; + public static readonly string[] Names; + public static readonly int ContextSize; + + static StaticWrapper() + { + var d = Wrapper.InitStaticWrapper(typeof(T)); + QuickWrapper = (Action)d.Item1; + SafeWrapper = (Action)d.Item2; + Unwrapper = (Action)d.Item3; + WrapName = (Action)d.Item4; + UnwrapName = (Action)d.Item5; + ContextNames = d.Item6; + Names = ContextNames.Keys.ToArray(); + ContextSize = ContextNames.Count; + } + + public static ExecutionContext Wrap() + { + var lc = new LocalVariablesContainer(ContextSize, new Dictionary(ContextNames)); + var ret = new ExecutionContext(false, false, lc); + QuickWrapper(ret, lc); + WrapName(ret); + return ret; + } + public static void Unwrap(ExecutionContext context) + { + UnwrapName(context); + Unwrapper(context.LocalVariables); + } + public static void WrapIn(ExecutionContext context) + { + SafeWrapper(context, context.LocalVariables); + WrapName(context); + } + public static void UnwrapIn(ExecutionContext context) + { + Unwrapper(context.LocalVariables); + UnwrapName(context); + } + } } diff --git a/SLThree/sys/console.cs b/SLThree/sys/console.cs index bab2a43..1d49679 100644 --- a/SLThree/sys/console.cs +++ b/SLThree/sys/console.cs @@ -7,7 +7,7 @@ namespace SLThree.sys #pragma warning disable IDE1006 // Стили именования public static class console { - public static ContextWrap color = new ContextWrap(new ExecutionContext(false, false, Enum.GetNames(typeof(ConsoleColor)).ToDictionary(x => x, x => Enum.Parse(typeof(ConsoleColor), x)).ToLocals())); + public static ContextWrap color = typeof(ConsoleColor).StaticWrap().wrap; public static string readln() => Console.ReadLine(); public static void write(object o) => Console.Write(o); public static void writeln() => Console.WriteLine(); From 6b4a7c75ca3c5bc1d9c38c6179c9c1675839276b Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Sat, 1 Jun 2024 16:21:43 +0300 Subject: [PATCH 05/69] Delete slthree.ico --- SLThree/SLThree.csproj | 4 ---- SLThree/slthree.ico | Bin 68901 -> 0 bytes 2 files changed, 4 deletions(-) delete mode 100644 SLThree/slthree.ico diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index ea67f35..9db607a 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -51,10 +51,6 @@ - - - - all diff --git a/SLThree/slthree.ico b/SLThree/slthree.ico deleted file mode 100644 index f31a73914c4d90c7323e8f58c08aa4b3dd29bebb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68901 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 O_d Date: Fri, 7 Jun 2024 19:34:27 +0300 Subject: [PATCH 06/69] Update SLThree.csproj --- SLThree/SLThree.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index df0ac6d..3529e69 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -16,7 +16,6 @@ 0.7.1.3082 $(Version) $(Version) - slthree.ico Bugfixes: - Add support for generic dict creators <T, T>{} From 9d1319c8a589ce85e83033a240f89949de6d481f Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Sat, 8 Jun 2024 19:50:54 +0300 Subject: [PATCH 07/69] verser instead of MSBump --- SLThree/.msbump | 3 - SLThree/SLThree.csproj | 30 ++---- SLThree/SLThreeOLD.csproj | 210 ------------------------------------ SLThree/docs/versions/0.8.0 | 4 + slt/.msbump | 3 - slt/Program.cs | 30 +++--- slt/docs/versions/3.0.0 | 4 + slt/slt.csproj | 8 +- verser/verser.exe | Bin 0 -> 30720 bytes verser/verserconfig.xml | 12 +++ 10 files changed, 48 insertions(+), 256 deletions(-) delete mode 100644 SLThree/.msbump delete mode 100644 SLThree/SLThreeOLD.csproj create mode 100644 SLThree/docs/versions/0.8.0 delete mode 100644 slt/.msbump create mode 100644 slt/docs/versions/3.0.0 create mode 100644 verser/verser.exe create mode 100644 verser/verserconfig.xml diff --git a/SLThree/.msbump b/SLThree/.msbump deleted file mode 100644 index b6e665a..0000000 --- a/SLThree/.msbump +++ /dev/null @@ -1,3 +0,0 @@ -{ - BumpRevision: true -} \ No newline at end of file diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 3529e69..8ac7f5e 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -1,6 +1,5 @@  - net471;netstandard2.1;net6.0 disable @@ -13,58 +12,42 @@ git language;scripts;script-lang True - 0.7.1.3082 - $(Version) - $(Version) - Bugfixes: - - Add support for generic dict creators <T, T>{} + 0.8.0-alpha.11 + $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) - 4 False - 4 False - 4 False - 4 False - False - False - + - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - @@ -78,6 +61,9 @@ + - - + + + + \ No newline at end of file diff --git a/SLThree/SLThreeOLD.csproj b/SLThree/SLThreeOLD.csproj deleted file mode 100644 index a2f9e4f..0000000 --- a/SLThree/SLThreeOLD.csproj +++ /dev/null @@ -1,210 +0,0 @@ - - - - - Debug - AnyCPU - {06A97274-8266-4F25-A78B-8CF615B12771} - Library - Properties - SLThree - SLThree - v4.7.1 - 512 - true - - - - - true - full - false - ..\bin\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - ..\bin\ - TRACE - prompt - 4 - - - OnBuildSuccess - - - - ..\packages\Pegasus.4.1.0\lib\net45\Pegasus.Common.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}. - - - - - ../building/IncRevision.bat - - - - - - \ No newline at end of file diff --git a/SLThree/docs/versions/0.8.0 b/SLThree/docs/versions/0.8.0 new file mode 100644 index 0000000..531a0e0 --- /dev/null +++ b/SLThree/docs/versions/0.8.0 @@ -0,0 +1,4 @@ +------ 0.8.0 ------ [~.~.~] +Optimization: + - Wrappers refactoring, minumum 3x faster wrapping + minimum 20x faster unwrapping \ No newline at end of file diff --git a/slt/.msbump b/slt/.msbump deleted file mode 100644 index b6e665a..0000000 --- a/slt/.msbump +++ /dev/null @@ -1,3 +0,0 @@ -{ - BumpRevision: true -} \ No newline at end of file diff --git a/slt/Program.cs b/slt/Program.cs index befb8e1..fb93c6e 100644 --- a/slt/Program.cs +++ b/slt/Program.cs @@ -127,23 +127,15 @@ public static void OutCurrentVersion() Console.ForegroundColor = ConsoleColor.Green; Console.Write(REPLVersion.Name); Console.ForegroundColor = ConsoleColor.White; - Console.Write($" {SLTREPLVersion.VersionWithoutRevision} "); - Console.ResetColor(); - Console.Write("rev "); - Console.ForegroundColor = ConsoleColor.White; - Console.WriteLine($"{SLTREPLVersion.Revision}"); + Console.WriteLine($" {SLTREPLVersion.VersionWithoutRevision} "); Console.ResetColor(); Console.ForegroundColor = ConsoleColor.Green; Console.Write(SLTVersion.Name); Console.ForegroundColor = ConsoleColor.White; - Console.Write($" {SLThreeVersion.VersionWithoutRevision} "); + Console.Write($" {GetVersionOfLanguage()} "); Console.ForegroundColor = ConsoleColor.Yellow; - Console.Write($"{SLTVersion.Edition} "); - Console.ResetColor(); - Console.Write("rev "); - Console.ForegroundColor = ConsoleColor.White; - Console.WriteLine($"{SLThreeVersion.Revision}"); + Console.WriteLine($"{SLTVersion.Edition} "); Console.ResetColor(); } @@ -860,13 +852,25 @@ public static void REPLCommand(string command) } #endregion + private static string VersionGetted = null; + private static string GetVersionOfLanguage() + { + if (string.IsNullOrEmpty(VersionGetted)) + { + var fileVersionInfo = FileVersionInfo.GetVersionInfo(SLThreeAssembly.Location).ProductVersion; + var index = fileVersionInfo.IndexOf('+'); + VersionGetted = index != -1 ? fileVersionInfo.Substring(0, index) : fileVersionInfo; + } + return VersionGetted; + } + public static void REPLShortVersion() { Console.ForegroundColor = ConsoleColor.Green; - Console.Write("SLThree REPL "); + Console.Write("SLThree "); Console.ResetColor(); Console.ForegroundColor = ConsoleColor.White; - Console.Write($"{SLTREPLVersion.VersionWithoutRevision}"); + Console.Write($"{GetVersionOfLanguage()}"); Console.ResetColor(); Console.Write(" | "); Console.ForegroundColor = ConsoleColor.Cyan; diff --git a/slt/docs/versions/3.0.0 b/slt/docs/versions/3.0.0 new file mode 100644 index 0000000..92d27e9 --- /dev/null +++ b/slt/docs/versions/3.0.0 @@ -0,0 +1,4 @@ +------ SLThree REPL 3.0.0 ------ [~.~.~] +Supporing: + - From now on, REPL will not support multiple versions + of the language. \ No newline at end of file diff --git a/slt/slt.csproj b/slt/slt.csproj index 017f6f1..a706146 100644 --- a/slt/slt.csproj +++ b/slt/slt.csproj @@ -6,7 +6,7 @@ net471;net6.0;net7.0;net8.0 disable disable - 2.0.0.700 + 3.0.0 ..\bin slthree.ico AnyCPU @@ -20,6 +20,7 @@ + @@ -33,13 +34,10 @@ + - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/verser/verser.exe b/verser/verser.exe new file mode 100644 index 0000000000000000000000000000000000000000..a9c0bcfd1c06fb057b26ad8f23fe1d5249e17dc9 GIT binary patch literal 30720 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 literal 0 HcmV?d00001 diff --git a/verser/verserconfig.xml b/verser/verserconfig.xml new file mode 100644 index 0000000..014065a --- /dev/null +++ b/verser/verserconfig.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file From 5cc9b9ca744edef074b7a5c36bb0f37a2605190b Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Sat, 8 Jun 2024 20:20:37 +0300 Subject: [PATCH 08/69] Create CreatorInstance.cs --- .../Expressions/Creators/CreatorInstance.cs | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 SLThree/Expressions/Creators/CreatorInstance.cs diff --git a/SLThree/Expressions/Creators/CreatorInstance.cs b/SLThree/Expressions/Creators/CreatorInstance.cs new file mode 100644 index 0000000..36b012e --- /dev/null +++ b/SLThree/Expressions/Creators/CreatorInstance.cs @@ -0,0 +1,103 @@ +using SLThree.Extensions; +using SLThree.Extensions.Cloning; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SLThree.Expressions.Creators +{ + public class CreatorInstance : BaseExpression + { + /* + ---Creating instances--- + new T; + new T {}; + new T(args); + new T(args) {}; + new T: TBase; + new T: TBase {}; + new T(args): TBase; + new T(args): TBase {}; + ---With name assignation + new T Name; + new T Name {}; + new T(args) Name; + new T(args) Name {}; + new T Name: TBase; + new T Name: TBase {}; + new T(args) Name: TBase; + new T(args) Name: TBase {}; + */ + public CreatorInstance(TypenameExpression type, BaseExpression[] args, NameExpression name, BaseExpression[] ancestors, CreatorContextBody body, SourceContext context) : base(context) + { + Type = type; + Arguments = args; + Name = name; + Ancestors = ancestors; + CreatorBody = body; + } + public CreatorInstance(TypenameExpression type, SourceContext context) + : this(type, new BaseExpression[0], null, new BaseExpression[0], null, context) { } + + + public TypenameExpression Type { get; set; } + public BaseExpression[] Arguments { get; set; } + public NameExpression Name { get; set; } + public BaseExpression[] Ancestors { get; set; } + public CreatorContextBody CreatorBody { get; set; } + + public override string ExpressionToString() + { + var sb = new StringBuilder(); + sb.Append("new "); + sb.Append(Type.ToString()); + if (Arguments.Length > 0) + sb.Append($"({Arguments.JoinIntoString(", ")})"); + if (Name != null) + sb.Append($" {Name}"); + if (Ancestors.Length > 0) + { + sb.Append(": "); + sb.Append(Ancestors.JoinIntoString(", ")); + } + if (CreatorBody != null) + { + sb.Append($"{{{CreatorBody}}}"); + } + return sb.ToString(); + } + + public override object GetValue(ExecutionContext context) + { + throw new NotImplementedException(); + } + + public override object Clone() + { + return new CreatorInstance(Type.CloneCast(), Arguments.CloneArray(), Name.CloneCast(), Ancestors.CloneArray(), CreatorBody.CloneCast(), SourceContext.CloneCast()); + } + } + + public class CreatorContextBody : StatementList, ICloneable + { + public CreatorContextBody() : base() { } + public CreatorContextBody(IList statements, SourceContext context) : base(statements, context) { } + + public ExecutionContext GetValue(ExecutionContext target, ExecutionContext call, ExecutionContext[] ancestors) + { + return target; + } + + public override object GetValue(ExecutionContext context) + { + throw new NotImplementedException(); + } + + public override object Clone() + { + return new CreatorContextBody(Statements.CloneArray(), SourceContext.CloneCast()); + } + } +} From 4e5803021ebf779a7f6964a0de488c62f65870c4 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Sat, 8 Jun 2024 20:23:02 +0300 Subject: [PATCH 09/69] nuget readme restore --- SLThree/README.md | 3 --- SLThree/SLThree.csproj | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 SLThree/README.md diff --git a/SLThree/README.md b/SLThree/README.md deleted file mode 100644 index 1791614..0000000 --- a/SLThree/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# SThree - -C#-like script programming language for .NET Framework \ No newline at end of file diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 8ac7f5e..a74e53e 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -14,6 +14,7 @@ True 0.8.0-alpha.11 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) + README.md 4 From 8f5d5d955bbed02f78c4f28ed635b2badfe5206b Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Sat, 8 Jun 2024 22:44:41 +0300 Subject: [PATCH 10/69] Ctrl+C in repl subparser --- slt/Program.cs | 4 +++- slt/Subparser.cs | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/slt/Program.cs b/slt/Program.cs index fb93c6e..a97001a 100644 --- a/slt/Program.cs +++ b/slt/Program.cs @@ -953,7 +953,9 @@ void cancelKeyPress(object o, ConsoleCancelEventArgs e) Console.Write("... " + new string(' ', REPLSubparser.Tabs * 4)); try { - var state = REPLSubparser.Parse(Console.ReadLine()); + var rdl = Console.ReadLine(); + var state = REPLSubparser.Parse(rdl); + if (rdl == null) Console.WriteLine(); if (state == Subparser.SubparserState.WaitingText) continue; } catch (Exception e) diff --git a/slt/Subparser.cs b/slt/Subparser.cs index 86633e4..6876c0f 100644 --- a/slt/Subparser.cs +++ b/slt/Subparser.cs @@ -107,6 +107,11 @@ public SubparserState ParseNew(string s) public SubparserState Parse(string s) { + if (s == null) + { + Clear(); + return SubparserState.Ready; + } InternalParse(s); State = Brackets.Count == 0 ? SubparserState.Ready : SubparserState.WaitingText; return State; From 2f7a7c1088927be46b9d8d0eb3eb366a1641b5cb Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Sat, 8 Jun 2024 23:16:55 +0300 Subject: [PATCH 11/69] constructors --- SLThree/ExecutionContext.cs | 20 +++++++++++++++++-- SLThree/Expressions/InvokeExpression.cs | 9 +++++++++ .../Literals/Special/BaseLiteral.cs | 14 +++++++++++++ SLThree/Methods/Method.cs | 6 ++++-- SLThree/Parser.cs | 1 + SLThree/SLThree.csproj | 8 +++++++- SLThree/docs/versions/0.8.0 | 5 ++++- 7 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 SLThree/Expressions/Literals/Special/BaseLiteral.cs diff --git a/SLThree/ExecutionContext.cs b/SLThree/ExecutionContext.cs index e9333dd..ee3601d 100644 --- a/SLThree/ExecutionContext.cs +++ b/SLThree/ExecutionContext.cs @@ -1,4 +1,5 @@ using SLThree.Extensions; +using SLThree.Extensions.Cloning; using System; using System.Collections; using System.Collections.Generic; @@ -9,6 +10,7 @@ namespace SLThree { +#pragma warning disable IDE1006 // Стили именования public class ExecutionContext { public interface IExecutable @@ -32,6 +34,7 @@ public interface IExecutable internal bool Returned; internal bool Broken; internal bool Continued; + internal int Creations = 0; public object ReturnedValue; @@ -69,8 +72,9 @@ public ExecutionContext() : this(true, true, null) { } internal ExecutionContext PreviousContext; //public ContextWrap pred => new ContextWrap(PreviousContext); public readonly ContextWrap wrap; - internal ContextWrap super; - public readonly ContextWrap @private; + public ContextWrap super; + public ContextWrap @private; + public ContextWrap @base; internal ExecutionContext SuperContext { get => super?.Context; set => super = new ContextWrap(value); } public IEnumerable GetHierarchy() @@ -112,6 +116,18 @@ public void DefaultEnvironment() } + public ExecutionContext CreateInstance(Method constructor, object[] args) + { + var ret = new ExecutionContext(super.Context); + ret.Name = $"{Name}@{Convert.ToString(Creations++, 16).ToUpper().PadLeft(4, '0')}"; + ret.@base = wrap; + constructor.Constructor = true; + constructor.definitionplace = ret.wrap; + constructor.GetValue(ret, args); + return ret; + } + public readonly LocalVariablesContainer LocalVariables; } +#pragma warning restore IDE1006 // Стили именования } diff --git a/SLThree/Expressions/InvokeExpression.cs b/SLThree/Expressions/InvokeExpression.cs index 509cca4..24e0501 100644 --- a/SLThree/Expressions/InvokeExpression.cs +++ b/SLThree/Expressions/InvokeExpression.cs @@ -1,5 +1,6 @@ using SLThree.Extensions; using SLThree.Extensions.Cloning; +using System; using System.Linq; using System.Reflection; @@ -41,6 +42,14 @@ public object GetValue(ExecutionContext context, object[] args) if (method.ParamNames.Length != args.Length) throw new RuntimeError("Call with wrong arguments count", SourceContext); return method.GetValue(context, args); } + else if (o is ContextWrap wrap) + { + if (wrap.Context.LocalVariables.GetValue("constructor").Item1 is Method constructor) + { + if (constructor.ParamNames.Length != args.Length) throw new RuntimeError("Call constructor with wrong arguments count", SourceContext); + return wrap.Context.CreateInstance(constructor, args).wrap; + } + } else if (o is MethodInfo mi) { if (!mi.IsStatic) return mi.Invoke(args[0], args.Skip(1).ToArray()); diff --git a/SLThree/Expressions/Literals/Special/BaseLiteral.cs b/SLThree/Expressions/Literals/Special/BaseLiteral.cs new file mode 100644 index 0000000..4d0f63d --- /dev/null +++ b/SLThree/Expressions/Literals/Special/BaseLiteral.cs @@ -0,0 +1,14 @@ +using Pegasus.Common; + +namespace SLThree +{ + public class BaseLiteral : Special + { + public BaseLiteral(SourceContext context) : base(context) { } + public BaseLiteral(Cursor cursor) : base(cursor) { } + + public override string ExpressionToString() => "base"; + public override object GetValue(ExecutionContext context) => context.@base; + public override object Clone() => new BaseLiteral(SourceContext); + } +} diff --git a/SLThree/Methods/Method.cs b/SLThree/Methods/Method.cs index 9fd387d..488f5ec 100644 --- a/SLThree/Methods/Method.cs +++ b/SLThree/Methods/Method.cs @@ -19,6 +19,7 @@ public class Method : ICloneable public readonly bool Implicit = false; public readonly bool Recursive = false; public readonly bool Binded = false; + public bool Constructor = false; public TypenameExpression[] ParamTypes; public TypenameExpression ReturnType; @@ -51,7 +52,7 @@ public virtual ExecutionContext GetExecutionContext(object[] arguments, Executio ExecutionContext ret; if (Recursive) { - ret = new ExecutionContext(); + ret = new ExecutionContext(false, false); ret.Name = contextName; ret.PreviousContext = super_context; ret.LocalVariables.FillArguments(this, arguments); @@ -64,11 +65,12 @@ public virtual ExecutionContext GetExecutionContext(object[] arguments, Executio if (cached_method_contextes.TryGetValue(this, out var cntx)) { ret = cntx; + if (Constructor) cntx.@this = definitionplace; ret.PrepareToInvoke(); } else { - ret = new ExecutionContext(super_context) + ret = new ExecutionContext(super_context, false) { @this = definitionplace }; diff --git a/SLThree/Parser.cs b/SLThree/Parser.cs index 7b15937..6eedb31 100644 --- a/SLThree/Parser.cs +++ b/SLThree/Parser.cs @@ -51,6 +51,7 @@ private BaseExpression GetSpecialName(NameExpression expression) { switch (expression.Name) { + case "base": return new BaseLiteral(expression.SourceContext); case "global": return new GlobalLiteral(expression.SourceContext); case "self": return new SelfLiteral(expression.SourceContext); case "this": return new ThisLiteral(expression.SourceContext); diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index a74e53e..663bd5f 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.11 + 0.8.0-alpha.49 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md @@ -64,6 +64,12 @@ + + + True + \ + + diff --git a/SLThree/docs/versions/0.8.0 b/SLThree/docs/versions/0.8.0 index 531a0e0..e3746e3 100644 --- a/SLThree/docs/versions/0.8.0 +++ b/SLThree/docs/versions/0.8.0 @@ -1,4 +1,7 @@ ------ 0.8.0 ------ [~.~.~] Optimization: - Wrappers refactoring, minumum 3x faster wrapping - minimum 20x faster unwrapping \ No newline at end of file + minimum 20x faster unwrapping + - Constructor method that creates new contexts + `context TBase { constructor = (f) => this.f = f; };` + `T1 = TBase(5); T2 = TBase(10);` \ No newline at end of file From 7d9a458e84bec0abac0f8d2e51a745d5092229e8 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Sat, 8 Jun 2024 23:17:09 +0300 Subject: [PATCH 12/69] slt.clone --- SLThree/sys/slt.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SLThree/sys/slt.cs b/SLThree/sys/slt.cs index 40f8227..e398bc5 100644 --- a/SLThree/sys/slt.cs +++ b/SLThree/sys/slt.cs @@ -15,6 +15,8 @@ public static class slt public static object eval(string s) => Parser.This.EvalExpression(s); public static object eval(ContextWrap context, string s) => Parser.This.EvalExpression(s, context.Context); + public static object clone(ICloneable clone) => clone.Clone(); + public static string repr(object o) => TreeViewer.GetView(o); public static string context_repr(ContextWrap wrap) => wrap.ToDetailedString(1, new List()); public static string xml_repr(object o) => XmlViewer.GetView(o); From 7352bcc79a88b7da1b97231c02ee0ead4f2f237e Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Sun, 9 Jun 2024 01:56:29 +0300 Subject: [PATCH 13/69] new context syntax OOP model. inheritance, new initializators --- SLThree.HTMLCreator/HTMLCreator.cs | 4 +- SLThree/ExecutionContext.cs | 38 ++++ .../Expressions/Creators/CreatorContext.cs | 104 ++++++---- .../Creators/CreatorContextBody.cs | 32 +++ .../Expressions/Creators/CreatorContextOld.cs | 61 ++++++ .../Expressions/Creators/CreatorInstance.cs | 192 ++++++++++++++---- SLThree/LocalVariablesContainer.cs | 6 + SLThree/Methods/GenericMethod.cs | 4 +- SLThree/SLThree.csproj | 2 +- SLThree/Statements/ContextStatement.cs | 4 +- SLThree/Statements/StatementList.cs | 2 +- .../Visitors/Definition/AbstractVisitor.cs | 4 +- .../Visitors/Definition/IExpressionVisitor.cs | 2 +- SLThree/docs/versions/0.8.0 | 22 +- SLThree/syntax.peg | 159 +++++++++++++-- 15 files changed, 527 insertions(+), 109 deletions(-) create mode 100644 SLThree/Expressions/Creators/CreatorContextBody.cs create mode 100644 SLThree/Expressions/Creators/CreatorContextOld.cs diff --git a/SLThree.HTMLCreator/HTMLCreator.cs b/SLThree.HTMLCreator/HTMLCreator.cs index cb17b79..0bd4af8 100644 --- a/SLThree.HTMLCreator/HTMLCreator.cs +++ b/SLThree.HTMLCreator/HTMLCreator.cs @@ -114,7 +114,7 @@ public override void VisitExpression(TypenameExpression expression) CurrentString.Append(Replace(">")); } } - public void VisitExpression(CreatorContext expression, bool newline, bool hasnew) + public void VisitExpression(CreatorContextOld expression, bool newline, bool hasnew) { if (hasnew) CurrentString.Append(GetKeyword1("new context ")); @@ -146,7 +146,7 @@ public void VisitExpression(CreatorContext expression, bool newline, bool hasnew CurrentString.Append("}"); } } - public override void VisitExpression(CreatorContext expression) + public override void VisitExpression(CreatorContextOld expression) { VisitExpression(expression, ContextElementNewLine, true); } diff --git a/SLThree/ExecutionContext.cs b/SLThree/ExecutionContext.cs index ee3601d..5ee1cc0 100644 --- a/SLThree/ExecutionContext.cs +++ b/SLThree/ExecutionContext.cs @@ -126,8 +126,46 @@ public ExecutionContext CreateInstance(Method constructor, object[] args) constructor.GetValue(ret, args); return ret; } + public ExecutionContext CreateInstance(object[] args, SourceContext sourceContext) + { + var ret = new ExecutionContext(super.Context); + ret.Name = $"{Name}@{Convert.ToString(Creations++, 16).ToUpper().PadLeft(4, '0')}"; + ret.@base = wrap; + if (LocalVariables.GetValue("constructor").Item1 is Method constructor) + { + if (constructor.ParamNames.Length != args.Length) + throw new RuntimeError("Call constructor with wrong arguments count", sourceContext); + constructor.Constructor = true; + constructor.definitionplace = ret.wrap; + constructor.GetValue(ret, args); + } + return ret; + } + public void Implementation(ExecutionContext ret, Method constructor, object[] args) + { + constructor.Constructor = true; + constructor.definitionplace = ret.wrap; + constructor.GetValue(ret, args); + } + public void Implementation(ExecutionContext ret, object[] args, SourceContext sourceContext) + { + if (LocalVariables.GetValue("constructor").Item1 is Method constructor) + { + if (constructor.ParamNames.Length != args.Length) + throw new RuntimeError("Call constructor with wrong arguments count", sourceContext); + constructor.Constructor = true; + constructor.definitionplace = ret.wrap; + constructor.GetValue(ret, args); + } + } public readonly LocalVariablesContainer LocalVariables; + + internal ExecutionContext copy(ExecutionContext context) + { + LocalVariables.FillOther(context.LocalVariables); + return this; + } } #pragma warning restore IDE1006 // Стили именования } diff --git a/SLThree/Expressions/Creators/CreatorContext.cs b/SLThree/Expressions/Creators/CreatorContext.cs index 3b28066..382a545 100644 --- a/SLThree/Expressions/Creators/CreatorContext.cs +++ b/SLThree/Expressions/Creators/CreatorContext.cs @@ -1,61 +1,91 @@ using SLThree.Extensions; using SLThree.Extensions.Cloning; -using System; using System.Linq; namespace SLThree { public class CreatorContext : BaseExpression { - public NameExpression Name; - public TypenameExpression Typecast; - public BaseStatement[] Body; + /* + ---Creating instances--- + new context Name: TBase + new context Name + new context: TBase + new context - public bool HasCast => Typecast != null; - public bool HasName => Name != null; - public bool HasBody => Body.Length > 0; - - public CreatorContext(SourceContext context) : this(null, null, new BaseStatement[0], context) { } - - public CreatorContext(NameExpression name, SourceContext context) : this(name, null, new BaseStatement[0], context) { } - - public CreatorContext(NameExpression name, TypenameExpression typecast, SourceContext context) : this(name, typecast, new BaseStatement[0], context) { } - - public CreatorContext(BaseStatement[] body, SourceContext context) : this(null, null, body, context) { } + context Name: TBase {} + context Name {} + context: TBase {} + context {} + */ + public BaseExpression Name { get; set; } + public BaseExpression[] Ancestors { get; set; } + public CreatorContextBody CreatorBody { get; set; } + public bool IsFreeCreator { get; set; } - public CreatorContext(TypenameExpression typecast, SourceContext context) : this(null, typecast, new BaseStatement[0], context) { } + public bool HasName => Name != null; - public CreatorContext(NameExpression name, TypenameExpression typecast, BaseStatement[] body, SourceContext context) : base(context) + public CreatorContext(BaseExpression name, BaseExpression[] ancestors, CreatorContextBody body, bool is_free_creator, SourceContext context) : base(context) { - Name = name; - Typecast = typecast; - Body = body; + if (!is_free_creator) + { + if (!is_free_creator && name is MemberAccess access) + Name = access.Right as NameExpression; + else Name = name as NameExpression; + } + else Name = name; + Ancestors = ancestors; + CreatorBody = body; + IsFreeCreator = is_free_creator; } + public CreatorContext(BaseExpression name, BaseExpression[] ancestors, CreatorContextBody body, SourceContext context) + : this(name, ancestors, body, true, context) { } + public CreatorContext(BaseExpression name, CreatorContextBody body, SourceContext context) + : this(name, new BaseExpression[0], body, true, context) { } + public CreatorContext(BaseExpression[] ancestors, CreatorContextBody body, SourceContext context) + : this(null, ancestors, body, true, context) { } + public CreatorContext(CreatorContextBody body, SourceContext context) + : this(null, new BaseExpression[0], body, true, context) { } + public CreatorContext(BaseExpression name, BaseExpression[] ancestors, SourceContext context) + : this(name, ancestors, null, true, context) { } + public CreatorContext(BaseExpression name, SourceContext context) + : this(name, new BaseExpression[0], null, true, context) { } + public CreatorContext(BaseExpression[] ancestors, SourceContext context) + : this(null, ancestors, null, true, context) { } + public CreatorContext(SourceContext context) + : this(null, new BaseExpression[0], null, true, context) { } - public override string ExpressionToString() => $"new context {(HasName ? Name.Name : "")} {(HasCast ? $": {Typecast}" : "")} {{\n{Body.JoinIntoString("\n")}\n}}"; + public override string ExpressionToString() => $"context {(HasName ? Name.ToString() : "")} {{\n{CreatorBody}\n}}"; - private string last_context_name; - public string LastContextName => last_context_name; + private ExecutionContext counted_invoked; + private bool is_name_expr; + private int variable_index; + private string GetName() + { + var n = Name.ToString(); + var index = n.LastIndexOf('.'); + if (index == -1) return n; + else return n.Substring(index + 1); + } public override object GetValue(ExecutionContext context) { - var ret = new ExecutionContext(context); - if (HasName) ret.Name = Name.Name; - last_context_name = ret.Name; - if (HasBody) + ExecutionContext ret; + if (Ancestors.Length > 0) ret = Ancestors[0].GetValue(context).Cast().Context; + else ret = new ExecutionContext(context); + for (var i = 1; i < Ancestors.Length; i++) + ret.copy(Ancestors[i].GetValue(context).Cast().Context); + CreatorBody?.GetValue(ret, context); + var wrap = ret.wrap; + if (HasName) { - for (var i = 0; i < Body.Length; i++) - { - if (Body[i] is ExpressionStatement es && es.Expression is BinaryAssign assign) - assign.AssignValue(ret, assign.Left, assign.Right.GetValue(context)); - else if (Body[i] is ContextStatement cs) - cs.GetValue(ret); - } + ret.Name = IsFreeCreator ? GetName() : Name.ToString(); + if (IsFreeCreator) + BinaryAssign.AssignToValue(context, Name, wrap, ref counted_invoked, ref is_name_expr, ref variable_index); } - if (HasCast) return new ContextWrap(ret).CastToType(Typecast.GetValue(context).Cast()); - return new ContextWrap(ret); + return wrap; } - public override object Clone() => new CreatorContext(Name.CloneCast(), Typecast.CloneCast(), Body?.CloneArray(), SourceContext.CloneCast()); + public override object Clone() => new CreatorContext(Name.CloneCast(), Ancestors.CloneArray(), CreatorBody.CloneCast(), IsFreeCreator, SourceContext.CloneCast()); } } diff --git a/SLThree/Expressions/Creators/CreatorContextBody.cs b/SLThree/Expressions/Creators/CreatorContextBody.cs new file mode 100644 index 0000000..df39966 --- /dev/null +++ b/SLThree/Expressions/Creators/CreatorContextBody.cs @@ -0,0 +1,32 @@ +using SLThree.Extensions.Cloning; +using System; +using System.Collections.Generic; + +namespace SLThree +{ + public class CreatorContextBody : StatementList, ICloneable + { + public CreatorContextBody() : base() { } + public CreatorContextBody(IList statements, SourceContext context) : base(statements, context) { } + + public ExecutionContext GetValue(ExecutionContext target, ExecutionContext call) + { + for (var i = 0; i < count; i++) + { + if (Statements[i] is ExpressionStatement es && es.Expression is BinaryAssign assign) + assign.AssignValue(target, assign.Left, assign.Right.GetValue(call)); + } + return target; + } + + public override object GetValue(ExecutionContext context) + { + throw new NotImplementedException(); + } + + public override object Clone() + { + return new CreatorContextBody(Statements.CloneArray(), SourceContext.CloneCast()); + } + } +} diff --git a/SLThree/Expressions/Creators/CreatorContextOld.cs b/SLThree/Expressions/Creators/CreatorContextOld.cs new file mode 100644 index 0000000..4d8bc31 --- /dev/null +++ b/SLThree/Expressions/Creators/CreatorContextOld.cs @@ -0,0 +1,61 @@ +using SLThree.Extensions; +using SLThree.Extensions.Cloning; +using System; +using System.Linq; + +namespace SLThree +{ + public class CreatorContextOld : BaseExpression + { + public NameExpression Name; + public TypenameExpression Typecast; + public BaseStatement[] Body; + + public bool HasCast => Typecast != null; + public bool HasName => Name != null; + public bool HasBody => Body.Length > 0; + + public CreatorContextOld(SourceContext context) : this(null, null, new BaseStatement[0], context) { } + + public CreatorContextOld(NameExpression name, SourceContext context) : this(name, null, new BaseStatement[0], context) { } + + public CreatorContextOld(NameExpression name, TypenameExpression typecast, SourceContext context) : this(name, typecast, new BaseStatement[0], context) { } + + public CreatorContextOld(BaseStatement[] body, SourceContext context) : this(null, null, body, context) { } + + public CreatorContextOld(TypenameExpression typecast, SourceContext context) : this(null, typecast, new BaseStatement[0], context) { } + + public CreatorContextOld(NameExpression name, TypenameExpression typecast, BaseStatement[] body, SourceContext context) : base(context) + { + Name = name; + Typecast = typecast; + Body = body; + } + + public override string ExpressionToString() => $"new context {(HasName ? Name.Name : "")} {(HasCast ? $": {Typecast}" : "")} {{\n{Body.JoinIntoString("\n")}\n}}"; + + private string last_context_name; + public string LastContextName => last_context_name; + + public override object GetValue(ExecutionContext context) + { + var ret = new ExecutionContext(context); + if (HasName) ret.Name = Name.Name; + last_context_name = ret.Name; + if (HasBody) + { + for (var i = 0; i < Body.Length; i++) + { + if (Body[i] is ExpressionStatement es && es.Expression is BinaryAssign assign) + assign.AssignValue(ret, assign.Left, assign.Right.GetValue(context)); + else if (Body[i] is ContextStatement cs) + cs.GetValue(ret); + } + } + if (HasCast) return new ContextWrap(ret).CastToType(Typecast.GetValue(context).Cast()); + return new ContextWrap(ret); + } + + public override object Clone() => new CreatorContextOld(Name.CloneCast(), Typecast.CloneCast(), Body?.CloneArray(), SourceContext.CloneCast()); + } +} diff --git a/SLThree/Expressions/Creators/CreatorInstance.cs b/SLThree/Expressions/Creators/CreatorInstance.cs index 36b012e..5c92683 100644 --- a/SLThree/Expressions/Creators/CreatorInstance.cs +++ b/SLThree/Expressions/Creators/CreatorInstance.cs @@ -6,7 +6,7 @@ using System.Text; using System.Threading.Tasks; -namespace SLThree.Expressions.Creators +namespace SLThree { public class CreatorInstance : BaseExpression { @@ -30,23 +30,132 @@ public class CreatorInstance : BaseExpression new T(args) Name: TBase; new T(args) Name: TBase {}; */ - public CreatorInstance(TypenameExpression type, BaseExpression[] args, NameExpression name, BaseExpression[] ancestors, CreatorContextBody body, SourceContext context) : base(context) + public static CreatorInstance CaseType(TypenameExpression type, SourceContext context) + => new CreatorInstance( + type, + null, + new BaseExpression[0], + null, + context); + public static CreatorInstance CaseTypeBody(TypenameExpression type, CreatorContextBody body, SourceContext context) + => new CreatorInstance( + type, + null, + new BaseExpression[0], + new CreatorContext(null, new BaseExpression[0], body, false, context), + context); + public static CreatorInstance CaseTypeArgs(TypenameExpression type, BaseExpression[] args, SourceContext context) + => new CreatorInstance( + type, + null, + args, + null, + context); + public static CreatorInstance CaseTypeArgsBody(TypenameExpression type, BaseExpression[] args, CreatorContextBody body, SourceContext context) + => new CreatorInstance( + type, + null, + args, + new CreatorContext(null, new BaseExpression[0], body, false, context), + context); + public static CreatorInstance CaseTypeInheritance(TypenameExpression type, BaseExpression[] ancestors, SourceContext context) + => new CreatorInstance( + type, + null, + new BaseExpression[0], + new CreatorContext(null, ancestors, null, false, context), + context); + public static CreatorInstance CaseTypeBodyInheritance(TypenameExpression type, BaseExpression[] ancestors, CreatorContextBody body, SourceContext context) + => new CreatorInstance( + type, + null, + new BaseExpression[0], + new CreatorContext(null, ancestors, body, false, context), + context); + public static CreatorInstance CaseTypeArgsInheritance(TypenameExpression type, BaseExpression[] args, BaseExpression[] ancestors, SourceContext context) + => new CreatorInstance( + type, + null, + args, + null, + context); + public static CreatorInstance CaseTypeArgsBodyInheritance(TypenameExpression type, BaseExpression[] args, BaseExpression[] ancestors, CreatorContextBody body, SourceContext context) + => new CreatorInstance( + type, + null, + args, + new CreatorContext(null, ancestors, body, false, context), + context); + public static CreatorInstance NamedCaseType(TypenameExpression type, BaseExpression name, SourceContext context) + => new CreatorInstance( + type, + name, + new BaseExpression[0], + null, + context); + public static CreatorInstance NamedCaseTypeBody(TypenameExpression type, BaseExpression name, CreatorContextBody body, SourceContext context) + => new CreatorInstance( + type, + name, + new BaseExpression[0], + new CreatorContext(null, new BaseExpression[0], body, false, context), + context); + public static CreatorInstance NamedCaseTypeArgs(TypenameExpression type, BaseExpression name, BaseExpression[] args, SourceContext context) + => new CreatorInstance( + type, + name, + args, + null, + context); + public static CreatorInstance NamedCaseTypeArgsBody(TypenameExpression type, BaseExpression name, BaseExpression[] args, CreatorContextBody body, SourceContext context) + => new CreatorInstance( + type, + name, + args, + new CreatorContext(name, new BaseExpression[0], body, false, context), + context); + public static CreatorInstance NamedCaseTypeInheritance(TypenameExpression type, BaseExpression name, BaseExpression[] ancestors, SourceContext context) + => new CreatorInstance( + type, + name, + new BaseExpression[0], + new CreatorContext(name, ancestors, null, false, context), + context); + public static CreatorInstance NamedCaseTypeBodyInheritance(TypenameExpression type, BaseExpression name, BaseExpression[] ancestors, CreatorContextBody body, SourceContext context) + => new CreatorInstance( + type, + name, + new BaseExpression[0], + new CreatorContext(name, ancestors, body, false, context), + context); + public static CreatorInstance NamedCaseTypeArgsInheritance(TypenameExpression type, BaseExpression name, BaseExpression[] args, BaseExpression[] ancestors, SourceContext context) + => new CreatorInstance( + type, + name, + args, + null, + context); + public static CreatorInstance NamedCaseTypeArgsBodyInheritance(TypenameExpression type, BaseExpression name, BaseExpression[] args, BaseExpression[] ancestors, CreatorContextBody body, SourceContext context) + => new CreatorInstance( + type, + name, + args, + new CreatorContext(name, ancestors, body, false, context), + context); + + + public CreatorInstance(TypenameExpression type, BaseExpression name, BaseExpression[] args, CreatorContext creatorContext, SourceContext context) : base(context) { Type = type; - Arguments = args; Name = name; - Ancestors = ancestors; - CreatorBody = body; + Arguments = args; + CreatorContext = creatorContext; } - public CreatorInstance(TypenameExpression type, SourceContext context) - : this(type, new BaseExpression[0], null, new BaseExpression[0], null, context) { } - public TypenameExpression Type { get; set; } + public BaseExpression Name { get; set; } public BaseExpression[] Arguments { get; set; } - public NameExpression Name { get; set; } - public BaseExpression[] Ancestors { get; set; } - public CreatorContextBody CreatorBody { get; set; } + public CreatorContext CreatorContext { get; set; } public override string ExpressionToString() { @@ -55,49 +164,52 @@ public override string ExpressionToString() sb.Append(Type.ToString()); if (Arguments.Length > 0) sb.Append($"({Arguments.JoinIntoString(", ")})"); - if (Name != null) - sb.Append($" {Name}"); - if (Ancestors.Length > 0) + if (CreatorContext?.Name != null) + sb.Append($" {CreatorContext.Name}"); + if (CreatorContext.Ancestors.Length > 0) { sb.Append(": "); - sb.Append(Ancestors.JoinIntoString(", ")); + sb.Append(CreatorContext.Ancestors.JoinIntoString(", ")); } - if (CreatorBody != null) + if (CreatorContext.CreatorBody != null) { - sb.Append($"{{{CreatorBody}}}"); + sb.Append($"{{\n{CreatorContext.CreatorBody}\n}}"); } return sb.ToString(); } + private ExecutionContext counted_invoked; + private bool is_name_expr; + private int variable_index; public override object GetValue(ExecutionContext context) { - throw new NotImplementedException(); - } - - public override object Clone() - { - return new CreatorInstance(Type.CloneCast(), Arguments.CloneArray(), Name.CloneCast(), Ancestors.CloneArray(), CreatorBody.CloneCast(), SourceContext.CloneCast()); - } - } - - public class CreatorContextBody : StatementList, ICloneable - { - public CreatorContextBody() : base() { } - public CreatorContextBody(IList statements, SourceContext context) : base(statements, context) { } - - public ExecutionContext GetValue(ExecutionContext target, ExecutionContext call, ExecutionContext[] ancestors) - { - return target; - } - - public override object GetValue(ExecutionContext context) - { - throw new NotImplementedException(); + object instance; + var type = Type.GetValue(context).Cast(); + if (CreatorContext != null) + { + var created = CreatorContext.GetValue(context).Cast().Context; + if (Arguments.Length == 0) + instance = type.InstanceUnwrap(created); + else + { + instance = Activator.CreateInstance(type, Arguments.ConvertAll(x => x.GetValue(context))); + type.InstanceUnwrapIn(created, instance); + } + if (CreatorContext.Name != null) + BinaryAssign.AssignToValue(context, CreatorContext.Name, instance, ref counted_invoked, ref is_name_expr, ref variable_index); + } + else + { + instance = Activator.CreateInstance(type, Arguments.ConvertAll(x => x.GetValue(context))); + if (Name != null) + BinaryAssign.AssignToValue(context, Name, instance, ref counted_invoked, ref is_name_expr, ref variable_index); + } + return instance; } public override object Clone() { - return new CreatorContextBody(Statements.CloneArray(), SourceContext.CloneCast()); + return new CreatorInstance(Type.CloneCast(), Name.CloneCast(), Arguments.CloneArray(), CreatorContext.CloneCast(), SourceContext.CloneCast()); } } } diff --git a/SLThree/LocalVariablesContainer.cs b/SLThree/LocalVariablesContainer.cs index 7cc990b..a56ed5b 100644 --- a/SLThree/LocalVariablesContainer.cs +++ b/SLThree/LocalVariablesContainer.cs @@ -1,4 +1,5 @@ using SLThree.Extensions; +using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; @@ -49,6 +50,11 @@ public void FillArguments(Method method, object[] args) for (var i = 0; i < args.Length; i++) NamedIdentificators[method.ParamNames[i]] = i; } + public void FillOther(LocalVariablesContainer container) + { + foreach (var x in container.NamedIdentificators) + SetValue(x.Key, container.Variables[x.Value]); + } //[MethodImpl(MethodImplOptions.AggressiveInlining)] public int SetValue(string name, object value) diff --git a/SLThree/Methods/GenericMethod.cs b/SLThree/Methods/GenericMethod.cs index a6e717e..5ed7b4a 100644 --- a/SLThree/Methods/GenericMethod.cs +++ b/SLThree/Methods/GenericMethod.cs @@ -145,9 +145,9 @@ public RangeCreator(CreatorRange concrete, int position) : base(concrete, positi public override ref TypenameExpression GetPlacer() => ref Concrete.RangeType; } - public class ContextCreator : GenericInfo + public class ContextCreator : GenericInfo { - public ContextCreator(CreatorContext concrete, int position) : base(concrete, position) + public ContextCreator(CreatorContextOld concrete, int position) : base(concrete, position) { } diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 663bd5f..3cf58da 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.49 + 0.8.0-alpha.68 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md diff --git a/SLThree/Statements/ContextStatement.cs b/SLThree/Statements/ContextStatement.cs index 403a30e..5fa109c 100644 --- a/SLThree/Statements/ContextStatement.cs +++ b/SLThree/Statements/ContextStatement.cs @@ -5,9 +5,9 @@ namespace SLThree { public class ContextStatement : BaseStatement { - public CreatorContext Creator; + public CreatorContextOld Creator; - public ContextStatement(CreatorContext creator, SourceContext context) : base(context) + public ContextStatement(CreatorContextOld creator, SourceContext context) : base(context) { Creator = creator; } diff --git a/SLThree/Statements/StatementList.cs b/SLThree/Statements/StatementList.cs index d8e5f9a..c86a03b 100644 --- a/SLThree/Statements/StatementList.cs +++ b/SLThree/Statements/StatementList.cs @@ -7,7 +7,7 @@ namespace SLThree public class StatementList : BaseStatement { public BaseStatement[] Statements; - private int count; + private protected int count; public StatementList() : base() { } diff --git a/SLThree/Visitors/Definition/AbstractVisitor.cs b/SLThree/Visitors/Definition/AbstractVisitor.cs index de1c91c..dcb18fd 100644 --- a/SLThree/Visitors/Definition/AbstractVisitor.cs +++ b/SLThree/Visitors/Definition/AbstractVisitor.cs @@ -68,7 +68,7 @@ public virtual void VisitExpression(BaseExpression expression) case TypenameExpression expr: VisitExpression(expr); return; case CreatorNewArray expr: VisitExpression(expr); return; case CreatorArray expr: VisitExpression(expr); return; - case CreatorContext expr: VisitExpression(expr); return; + case CreatorContextOld expr: VisitExpression(expr); return; case CreatorRange expr: VisitExpression(expr); return; case MatchExpression expr: VisitExpression(expr); return; } @@ -368,7 +368,7 @@ public virtual void VisitExpression(CreatorNewArray expression) VisitExpression(expression.Size); } - public virtual void VisitExpression(CreatorContext expression) + public virtual void VisitExpression(CreatorContextOld expression) { if (expression.Typecast != null) { diff --git a/SLThree/Visitors/Definition/IExpressionVisitor.cs b/SLThree/Visitors/Definition/IExpressionVisitor.cs index babe5df..767b894 100644 --- a/SLThree/Visitors/Definition/IExpressionVisitor.cs +++ b/SLThree/Visitors/Definition/IExpressionVisitor.cs @@ -6,7 +6,7 @@ public interface IExpressionVisitor void VisitExpression(CreatorArray expression); void VisitExpression(CreatorNewArray expression); - void VisitExpression(CreatorContext expression); + void VisitExpression(CreatorContextOld expression); void VisitExpression(CreatorDictionary expression); void VisitExpression(CreatorList expression); void VisitExpression(CreatorRange expression); diff --git a/SLThree/docs/versions/0.8.0 b/SLThree/docs/versions/0.8.0 index e3746e3..78caea8 100644 --- a/SLThree/docs/versions/0.8.0 +++ b/SLThree/docs/versions/0.8.0 @@ -1,7 +1,21 @@ ------ 0.8.0 ------ [~.~.~] -Optimization: - - Wrappers refactoring, minumum 3x faster wrapping - minimum 20x faster unwrapping +Language: + - You can now copy contexts with ":" in the following cases: + - New initializers: // [] - optional + `new T [Name][: Ancestors][{...}]` + - New context creators: + `context [Name][: Ancestors] {...}` + `new context [Name][: Ancestors]` - Constructor method that creates new contexts `context TBase { constructor = (f) => this.f = f; };` - `T1 = TBase(5); T2 = TBase(10);` \ No newline at end of file + `T1 = TBase(5); T2 = TBase(10);` + - Changed context syntax: + `new context Name: T {...}` -> `new T Name {...}` + `new context: T {...}` -> `new T {...}` + `new context Name: T` -> `new T Name` + `new context: T` -> `new T` + `new context Name {...}` -> `context Name {...}` + `new context {...}` -> `context {...}` +Optimization: + - Wrappers refactoring, minumum 3x faster wrapping + minimum 20x faster unwrapping \ No newline at end of file diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index fef4185..b55f763 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -16,7 +16,6 @@ statement / break_statement / continue_statement / using_statement - / context_statement / condition_statement / foreach_statement / while_statement @@ -87,9 +86,6 @@ throw_statement = "throw" _required_ expr:expression _ ";" { new ThrowStatement(expr, state) } / "throw" _required_ expr:expression _ { Panic(new SyntaxError("Expected `;`", state)) } -context_statement - = "context" c:context { new ContextStatement(c, state) } - expression_statement = value:expression _ ";" { new ExpressionStatement(value, state) } / expression _ { Panic(new SyntaxError("Expected `;`", state)) } @@ -227,9 +223,149 @@ primary -memoize / "(" _ x:expression _ ")" { x.RaisePriority() } / "<" _ t:typename<2,2,"," _> _ ">" _ "{" _ etrs:dictionary_entry <0,,"," _> _ ("," _ )? "}" { new CreatorDictionary(etrs.ToArray(), t.ToArray(), state) } / "{" _ etrs:dictionary_entry <0,,"," _> _ ("," _ )? "}" { new CreatorDictionary(etrs.ToArray(), state) } - / "new" _required_ "context" c: context { c } + // "new" _required_ "context" c: context { c } / "new" _required_ "using" _required_ u: using { u } - / "new" _required_ right:typename _ "(" _ args:expression<0,,"," _> _ ")" { new NewExpression(right, args.ToArray(), state) } + +//--------CREATOR--CONTEXT------------------------------------------------- +// new context Name: TBase + / "new" _required_ "context" _required_ name:primary _ ":" _ ancestors:primary<1,,"," _> { + new CreatorContext(name, ancestors.ToArray(), state) + } +//--------CREATOR--CONTEXT------------------------------------------------- +// new context Name + / "new" _required_ "context" _required_ name:primary { + new CreatorContext(name, state) + } +//--------CREATOR--CONTEXT------------------------------------------------- +// new context: TBase + / "new" _required_ "context" _ ":" _ ancestors:primary<1,,"," _> { + new CreatorContext(ancestors.ToArray(), state) + } +//--------CREATOR--CONTEXT------------------------------------------------- +// new context + / "new" _required_ "context" { + new CreatorContext(state) + } +//--------CREATOR--CONTEXT------------------------------------------------- +// context Name: TBase {} + / "context" _required_ name:primary _ ":" _ ancestors:primary<1,,"," _> + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + new CreatorContext(name, ancestors.ToArray(), body, state) + } +//--------CREATOR--CONTEXT------------------------------------------------- +// context Name {} + / "context" _required_ name:primary + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + new CreatorContext(name, body, state) + } +//--------CREATOR--CONTEXT------------------------------------------------- +// context: TBase {} + / "context" _ ":" _ ancestors:primary<1,,"," _> + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + new CreatorContext(ancestors.ToArray(), body, state) + } +//--------CREATOR--CONTEXT------------------------------------------------- +// context {} + / "context" + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + new CreatorContext(body, state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T(args) Name: TBase {}; + / "new" _required_ t:typename _ "(" _ args:expression<0,,"," _> _ ")" _ name:primary + _ ":" _ ancestors:primary<1,,"," _> + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + CreatorInstance.NamedCaseTypeArgsBodyInheritance(t, name, args.ToArray(), ancestors.ToArray(), body, state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T(args) Name: TBase; + / "new" _required_ t:typename _ "(" _ args:expression<0,,"," _> _ ")" _ name:primary + _ ":" _ ancestors:primary<1,,"," _> { + CreatorInstance.NamedCaseTypeArgsInheritance(t, name, args.ToArray(), ancestors.ToArray(), state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T(args): TBase {}; + / "new" _required_ t:typename _ "(" _ args:expression<0,,"," _> _ ")" + _ ":" _ ancestors:primary<1,,"," _> + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + CreatorInstance.CaseTypeArgsBodyInheritance(t, args.ToArray(), ancestors.ToArray(), body, state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T(args): TBase; + / "new" _required_ t:typename _ "(" _ args:expression<0,,"," _> _ ")" + _ ":" _ ancestors:primary<1,,"," _> { + CreatorInstance.CaseTypeArgsInheritance(t, args.ToArray(), ancestors.ToArray(), state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T Name: TBase {}; + / "new" _required_ t:typename _ name:primary + _ ":" _ ancestors:primary<1,,"," _> + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + CreatorInstance.NamedCaseTypeBodyInheritance(t, name, ancestors.ToArray(), body, state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T Name: TBase; + / "new" _required_ t:typename _ name:primary + _ ":" _ ancestors:primary<1,,"," _> { + CreatorInstance.NamedCaseTypeInheritance(t, name, ancestors.ToArray(), state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T: TBase {}; + / "new" _required_ t:typename + _ ":" _ ancestors:primary<1,,"," _> + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + CreatorInstance.CaseTypeBodyInheritance(t, ancestors.ToArray(), body, state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T: TBase; + / "new" _required_ t:typename + _ ":" _ ancestors:primary<1,,"," _> { + CreatorInstance.CaseTypeInheritance(t, ancestors.ToArray(), state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T(args) Name {}; + / "new" _required_ t:typename _ "(" _ args:expression<0,,"," _> _ ")" _ name:primary + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + CreatorInstance.NamedCaseTypeArgsBody(t, name, args.ToArray(), body, state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T(args) Name; + / "new" _required_ t:typename _ "(" _ args:expression<0,,"," _> _ ")" _ name:primary { + CreatorInstance.NamedCaseTypeArgs(t, name, args.ToArray(), state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T(args) {}; + / "new" _required_ t:typename _ "(" _ args:expression<0,,"," _> _ ")" + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + CreatorInstance.CaseTypeArgsBody(t, args.ToArray(), body, state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T(args); + / "new" _required_ t:typename _ "(" _ args:expression<0,,"," _> _ ")" { + CreatorInstance.CaseTypeArgs(t, args.ToArray(), state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T Name {}; + / "new" _required_ t:typename _ name:primary + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + CreatorInstance.NamedCaseTypeBody(t, name, body, state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T Name; + / "new" _required_ t:typename _ name:primary { + CreatorInstance.NamedCaseType(t, name, state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T {}; + / "new" _required_ t:typename + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + CreatorInstance.CaseTypeBody(t, body, state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T; + / "new" _required_ t:typename { + CreatorInstance.CaseType(t, state) + } / "new" _required_ tp:typename _ "[" _ size:expression _ "]" { new CreatorNewArray(tp, size, state) } / "(" _ args:req_arg_name<1,,"," _> _ ("," _ )? ")" { new CreatorTuple(args.ToArray(), state) } / "(" _ args:expression<1,,"," _> _ ("," _ )? ")" { new CreatorTuple(args.ToArray(), state) } @@ -253,17 +389,6 @@ access_right -memoize using = t_name:typename { new CreatorUsing(t_name, state) } -context - = context_name:( _required_ n:name {n})? - context_type:( _ ":" _ t:typename {t})? - context_body:( _ st:block_statement {st})? { - new CreatorContext( - GetOptional(context_name), - GetOptional(context_type), - GetOptional(context_body)?.Statements.ToArray().ConvertAll(x => CheckOnContextStatements(x)) ?? new BaseStatement[0], - state) - } - generic_lambda = left:( , NameExpression[], TypenameExpression, NameExpression[]>> From a6318197a1ae91c4dca547999e600b4309e4ca3c Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Sun, 9 Jun 2024 17:00:33 +0300 Subject: [PATCH 14/69] check context statements --- .../Expressions/Creators/CreatorContextBody.cs | 17 ++++++++++++++++- SLThree/Parser.cs | 13 ------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/SLThree/Expressions/Creators/CreatorContextBody.cs b/SLThree/Expressions/Creators/CreatorContextBody.cs index df39966..6d1b481 100644 --- a/SLThree/Expressions/Creators/CreatorContextBody.cs +++ b/SLThree/Expressions/Creators/CreatorContextBody.cs @@ -7,7 +7,11 @@ namespace SLThree public class CreatorContextBody : StatementList, ICloneable { public CreatorContextBody() : base() { } - public CreatorContextBody(IList statements, SourceContext context) : base(statements, context) { } + public CreatorContextBody(IList statements, SourceContext context) : base(statements, context) + { + foreach (var x in Statements) + CheckOnContextStatements(x); + } public ExecutionContext GetValue(ExecutionContext target, ExecutionContext call) { @@ -19,6 +23,17 @@ public ExecutionContext GetValue(ExecutionContext target, ExecutionContext call) return target; } + private static BaseStatement CheckOnContextStatements(BaseStatement statement) + { + if (statement is ExpressionStatement expressionStatement) + { + if (expressionStatement.Expression is BinaryAssign) + return statement; + throw new SyntaxError($"Expected assign expression, found {expressionStatement.Expression.GetType().Name}", expressionStatement.Expression.SourceContext); + } + throw new SyntaxError($"Expected assign expression, found {statement.GetType().Name}", statement.SourceContext); + } + public override object GetValue(ExecutionContext context) { throw new NotImplementedException(); diff --git a/SLThree/Parser.cs b/SLThree/Parser.cs index 6eedb31..2adf5db 100644 --- a/SLThree/Parser.cs +++ b/SLThree/Parser.cs @@ -107,18 +107,5 @@ private static T Panic(SLTException exception) { throw exception; } - - private static BaseStatement CheckOnContextStatements(BaseStatement statement) - { - if (statement is ExpressionStatement expressionStatement) - { - if (expressionStatement.Expression is BinaryAssign) - return statement; - throw new SyntaxError($"Expected assign expression, found {expressionStatement.Expression.GetType().Name}", expressionStatement.Expression.SourceContext); - } - if (statement is ContextStatement contextStatement) - return contextStatement; - throw new SyntaxError($"Expected assign expression, found {statement.GetType().Name}", statement.SourceContext); - } } } From da69bcb2bc354c51719abea18770a8c2b359c283 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Sun, 9 Jun 2024 17:01:40 +0300 Subject: [PATCH 15/69] CreatorInstance body null check --- SLThree/Expressions/Creators/CreatorInstance.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SLThree/Expressions/Creators/CreatorInstance.cs b/SLThree/Expressions/Creators/CreatorInstance.cs index 5c92683..cb6384d 100644 --- a/SLThree/Expressions/Creators/CreatorInstance.cs +++ b/SLThree/Expressions/Creators/CreatorInstance.cs @@ -166,12 +166,12 @@ public override string ExpressionToString() sb.Append($"({Arguments.JoinIntoString(", ")})"); if (CreatorContext?.Name != null) sb.Append($" {CreatorContext.Name}"); - if (CreatorContext.Ancestors.Length > 0) + if (CreatorContext?.Ancestors.Length > 0) { sb.Append(": "); sb.Append(CreatorContext.Ancestors.JoinIntoString(", ")); } - if (CreatorContext.CreatorBody != null) + if (CreatorContext?.CreatorBody != null) { sb.Append($"{{\n{CreatorContext.CreatorBody}\n}}"); } From 35579595f24cde0d8b6e65e450e1fcd137b25d61 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Sun, 9 Jun 2024 17:02:24 +0300 Subject: [PATCH 16/69] empty statement deletion --- SLThree/Statements/EmptyStatement.cs | 13 +++++++++++++ SLThree/Statements/StatementList.cs | 4 ++-- SLThree/syntax.peg | 2 +- 3 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 SLThree/Statements/EmptyStatement.cs diff --git a/SLThree/Statements/EmptyStatement.cs b/SLThree/Statements/EmptyStatement.cs new file mode 100644 index 0000000..c1e4fd4 --- /dev/null +++ b/SLThree/Statements/EmptyStatement.cs @@ -0,0 +1,13 @@ +using SLThree.Extensions.Cloning; + +namespace SLThree +{ + public class EmptyStatement : BaseStatement + { + public EmptyStatement(SourceContext context) : base(context) { } + + public override string ToString() => $";"; + public override object GetValue(ExecutionContext context) => null; + public override object Clone() => new EmptyStatement(SourceContext.CloneCast()); + } +} diff --git a/SLThree/Statements/StatementList.cs b/SLThree/Statements/StatementList.cs index c86a03b..3d98f60 100644 --- a/SLThree/Statements/StatementList.cs +++ b/SLThree/Statements/StatementList.cs @@ -13,8 +13,8 @@ public StatementList() : base() { } public StatementList(IList statements, SourceContext context) : base(context) { - Statements = statements.ToArray(); - count = statements.Count; + Statements = statements.Where(x => !(x is EmptyStatement)).ToArray(); + count = Statements.Length; } public override string ToString() => $"{Statements.Length} statements"; diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index b55f763..934191e 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -23,7 +23,7 @@ statement / throw_statement / expression_statement / block_statement - / ";" { new StatementList(new BaseStatement[0], state) } + / ";" { new EmptyStatement(state) } using_statement = "using" _required_ u:using From 9b40e7e535d252e0ce1251f4baa592bda8390697 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Sun, 9 Jun 2024 17:02:48 +0300 Subject: [PATCH 17/69] visitor define checker --- SLThree/sys/language.cs | 88 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 SLThree/sys/language.cs diff --git a/SLThree/sys/language.cs b/SLThree/sys/language.cs new file mode 100644 index 0000000..7836419 --- /dev/null +++ b/SLThree/sys/language.cs @@ -0,0 +1,88 @@ +using SLThree.JIT; +using SLThree.Visitors; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace SLThree.sys +{ +#pragma warning disable IDE1006 // Стили именования + public static class language + { + public static Assembly SLThree = typeof(language).Assembly; + public static IEnumerable GetAncestors(Type type) + { + type = type.BaseType; + while (type != null) + { + yield return type; + type = type.BaseType; + } + } + + public static void show() + { + var types = SLThree.GetTypes(); + var statements = types.Where(x => GetAncestors(x).Contains(typeof(BaseStatement))); + var expressions = types.Where(x => GetAncestors(x).Contains(typeof(BaseExpression))); + expressions = expressions.Where(x => !GetAncestors(x).Contains(typeof(Literal))); + expressions = expressions.Where(x => !GetAncestors(x).Contains(typeof(Special))); + expressions = expressions.Where(x => !GetAncestors(x).Contains(typeof(BinaryOperator))); + expressions = expressions.Where(x => !GetAncestors(x).Contains(typeof(UnaryOperator))); + + //name, AV define, TV define, XMLV define + var infos = new List<(string, bool, bool, bool, bool, bool)>(); + foreach (var statement in statements) + { + var AVdefine = typeof(IStatementVisitor).GetMethods().Any(x => x.Name == "VisitStatement" && x.GetParameters()[0].ParameterType == statement); + var TVdefine = typeof(TreeViewer).GetMethods().Any(x => x.Name == "VisitStatement" && x.GetParameters()[0].ParameterType == statement && x.DeclaringType != typeof(AbstractVisitor)); + var XMLdefine = typeof(XmlViewer).GetMethods().Any(x => x.Name == "VisitStatement" && x.GetParameters()[0].ParameterType == statement && x.DeclaringType != typeof(AbstractVisitor)); + var NETdefine = typeof(NETGenerator).GetMethods().Any(x => x.Name == "VisitStatement" && x.GetParameters()[0].ParameterType == statement && x.DeclaringType != typeof(AbstractVisitor)); + infos.Add((statement.Name, false, AVdefine, TVdefine, XMLdefine, NETdefine)); + } + foreach (var expression in expressions) + { + var AVdefine = typeof(IExpressionVisitor).GetMethods().Any(x => x.Name == "VisitExpression" && x.GetParameters()[0].ParameterType == expression); + var TVdefine = typeof(TreeViewer).GetMethods().Any(x => x.Name == "VisitExpression" && x.GetParameters()[0].ParameterType == expression && x.DeclaringType != typeof(AbstractVisitor)); + var XMLdefine = typeof(XmlViewer).GetMethods().Any(x => x.Name == "VisitExpression" && x.GetParameters()[0].ParameterType == expression && x.DeclaringType != typeof(AbstractVisitor)); + var NETdefine = typeof(NETGenerator).GetMethods().Any(x => x.Name == "VisitExpression" && x.GetParameters()[0].ParameterType == expression && x.DeclaringType != typeof(AbstractVisitor)); + infos.Add((expression.Name, true, AVdefine, TVdefine, XMLdefine, NETdefine)); + } + infos.Sort((x, y) => (string.Compare(x.Item1, y.Item1))); + var nameident = infos.Max(x => x.Item1.Length); + var defs = new Dictionary { { false, "not" }, { true, "defined" } }; + var colors = new Dictionary { { false, ConsoleColor.Red }, { true, ConsoleColor.Green } }; + Console.ResetColor(); + Console.WriteLine($"{"Element name".PadRight(nameident)} │ AVdef │ TVdef │ XMLdef │ NETdef "); + foreach (var x in infos) + { + Console.ForegroundColor = x.Item2 ? ConsoleColor.Cyan : ConsoleColor.Magenta; + Console.Write(x.Item1.PadRight(nameident)); + Console.ResetColor(); + Console.Write(" │ "); + Console.ForegroundColor = colors[x.Item3]; + Console.Write(defs[x.Item3].PadRight(7)); + Console.ResetColor(); + Console.Write(" │ "); + Console.ForegroundColor = colors[x.Item4]; + Console.Write(defs[x.Item4].PadRight(7)); + Console.ResetColor(); + Console.Write(" │ "); + Console.ForegroundColor = colors[x.Item5]; + Console.Write(defs[x.Item5].PadRight(7)); + Console.ResetColor(); + Console.Write(" │ "); + Console.ForegroundColor = colors[x.Item6]; + Console.Write(defs[x.Item6].PadRight(7)); + Console.ResetColor(); + Console.WriteLine(); + } + + Console.WriteLine(); + } + } +#pragma warning restore IDE1006 // Стили именования +} From 9ca2ad02f46cb914462906eebaea78f14ac7ab5e Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Sun, 9 Jun 2024 17:05:09 +0300 Subject: [PATCH 18/69] tests actualization --- test/executing/capturing.slt | 8 ++++---- test/executing/expressions/brackets.slt | 2 +- test/executing/expressions/creators.slt | 2 +- test/executing/reflection.slt | 2 +- test/parsing/hell_callable.slt | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/executing/capturing.slt b/test/executing/capturing.slt index b7c1684..7019cc2 100644 --- a/test/executing/capturing.slt +++ b/test/executing/capturing.slt @@ -1,16 +1,16 @@ -plus = left => new context { +plus = left => context { left = left; with_right = right => this.left + right; }.with_right; -mins = left => new context { +mins = left => context { left = left; with_right = right => this.left - right; }.with_right; -mult = left => new context { +mult = left => context { left = left; with_right = right => this.left * right; }.with_right; -divi = left => new context { +divi = left => context { left = left; with_right = right => this.left / right; }.with_right; diff --git a/test/executing/expressions/brackets.slt b/test/executing/expressions/brackets.slt index c16b61d..e1737db 100644 --- a/test/executing/expressions/brackets.slt +++ b/test/executing/expressions/brackets.slt @@ -1,4 +1,4 @@ -tests = new context { +tests = context { //indexator (1), call (2), tuple (3) test_111 = [[[0x111]]]; diff --git a/test/executing/expressions/creators.slt b/test/executing/expressions/creators.slt index c902fe9..535fe11 100644 --- a/test/executing/expressions/creators.slt +++ b/test/executing/expressions/creators.slt @@ -8,7 +8,7 @@ lst = [228 as tested_type, ]; ASSERT(self, (lst[0] is tested_type) as is); //context -cntxt = new context { a = 229 as tested_type; }; +cntxt = context { a = 229 as tested_type; }; ASSERT(self, (cntxt.a is tested_type) as is); //using diff --git a/test/executing/reflection.slt b/test/executing/reflection.slt index 4b2a53e..7033996 100644 --- a/test/executing/reflection.slt +++ b/test/executing/reflection.slt @@ -1,6 +1,6 @@ ASSERT(self, (@TestSuite.Program == @TestSuite.Program) as is); ASSERT(self, (@TestSuite.Program::Assert(context, SLThree.BaseExpression) == ASSERT) as is); -x = new context A { +x = context A { ASSERT = ASSERT; OWN_ASSERT = @TestSuite.Program::Assert(context, SLThree.BaseExpression); m1 = () => this.ASSERT; diff --git a/test/parsing/hell_callable.slt b/test/parsing/hell_callable.slt index 4ae4374..574b90e 100644 --- a/test/parsing/hell_callable.slt +++ b/test/parsing/hell_callable.slt @@ -1,4 +1,4 @@ -global.a = () => new context { r = () => global; }; +global.a = () => context { r = () => global; }; global.a().r().a().r().a().r().a(); global.a = [() => 2]; global.a[0]().ToString(); \ No newline at end of file From fcd7d955450fd4ab5f7c0b4edb21867cd3fe275e Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Sun, 9 Jun 2024 17:15:39 +0300 Subject: [PATCH 19/69] condition expression --- SLThree/Expressions/ConditionExpression.cs | 56 ++++++++++++++++++++++ SLThree/docs/versions/0.8.0 | 1 + SLThree/syntax.peg | 23 +++++---- 3 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 SLThree/Expressions/ConditionExpression.cs diff --git a/SLThree/Expressions/ConditionExpression.cs b/SLThree/Expressions/ConditionExpression.cs new file mode 100644 index 0000000..5d8f025 --- /dev/null +++ b/SLThree/Expressions/ConditionExpression.cs @@ -0,0 +1,56 @@ +using SLThree.Extensions.Cloning; +using System.Linq; + +namespace SLThree +{ + public class ConditionExpression : BaseExpression + { + public BaseExpression Condition { get; set; } + public BaseStatement[] Body { get; set; } + + public ConditionExpression() { } + public ConditionExpression(BaseExpression condition, BaseStatement[] body, int falsestart, SourceContext context) : base(context) + { + Condition = condition; + Body = body; + count = Body.Length; + this.falsestart = falsestart; + } + + public ConditionExpression(BaseExpression condition, StatementList trueBlock, StatementList falseBlock, SourceContext context) : base(context) + { + Condition = condition; + count = trueBlock.Statements.Length + falseBlock.Statements.Length; + Body = new BaseStatement[count]; + trueBlock.Statements.CopyTo(Body, 0); + falsestart = trueBlock.Statements.Length; + falseBlock.Statements.CopyTo(Body, falsestart); + } + private int count; + private int falsestart; + + public BaseStatement[] IfBody => Body.Take(falsestart).ToArray(); + public BaseStatement[] ElseBody => Body.Skip(falsestart).ToArray(); + + public override string ExpressionToString() => $"if ({Condition}) {{{Body}}}"; + + public override object GetValue(ExecutionContext context) + { + var ret = default(object); + var cond = (bool)Condition.GetValue(context); + var start = cond ? 0 : falsestart; + var end = cond ? falsestart : count; + for (var i = start; i < end; i++) + { + ret = Body[i].GetValue(context); + if (context.Returned || context.Broken || context.Continued) break; + } + return ret; + } + + public override object Clone() + { + return new ConditionExpression(Condition.CloneCast(), Body.CloneArray(), falsestart, SourceContext.CloneCast()); + } + } +} diff --git a/SLThree/docs/versions/0.8.0 b/SLThree/docs/versions/0.8.0 index 78caea8..813d9c6 100644 --- a/SLThree/docs/versions/0.8.0 +++ b/SLThree/docs/versions/0.8.0 @@ -9,6 +9,7 @@ Language: - Constructor method that creates new contexts `context TBase { constructor = (f) => this.f = f; };` `T1 = TBase(5); T2 = TBase(10);` + - Condition expression instead of condition statement - Changed context syntax: `new context Name: T {...}` -> `new T Name {...}` `new context: T {...}` -> `new T {...}` diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index 934191e..203151f 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -16,11 +16,11 @@ statement / break_statement / continue_statement / using_statement - / condition_statement / foreach_statement / while_statement / try_statement / throw_statement + / e:condition_statement { new ExpressionStatement(e, state) } / expression_statement / block_statement / ";" { new EmptyStatement(state) } @@ -62,11 +62,6 @@ foreach_statement / "foreach" _ "(" _ ")" _ statement? { Panic(new SyntaxError("Empty loop head", state)) } / "foreach" _required_ cond:expression { Panic(new SyntaxError("Loop head must be in ( )", state)) } -condition_statement - = "if" _ "(" _ cond:expression _ ")" _ t:statement _ "else" _ f:statement { new ConditionStatement(cond, GetListStatement(t), GetListStatement(f), state) } - / "if" _ "(" _ cond:expression _ ")" _ t:statement { new ConditionStatement(cond, GetListStatement(t), new StatementList(new BaseStatement[0], state), state) } - / "if" _ "(" _ ")" _ statement? { Panic(new SyntaxError("Empty condition", state)) } - try_statement = "try" _ try_body:block_statement _ "catch" _ "(" _ catch_var:expression _ ")" _ catch_body:statement _ @@ -86,6 +81,10 @@ throw_statement = "throw" _required_ expr:expression _ ";" { new ThrowStatement(expr, state) } / "throw" _required_ expr:expression _ { Panic(new SyntaxError("Expected `;`", state)) } +expression_as_statement + = block_statement + / value:expression { new ExpressionStatement(value, state) } + expression_statement = value:expression _ ";" { new ExpressionStatement(value, state) } / expression _ { Panic(new SyntaxError("Expected `;`", state)) } @@ -195,14 +194,20 @@ unary / "*" _ left:binary_min { new UnaryGetChooser(left, null, state) } / "@@" _ left:typename { new UnaryStaticReflection(left, state) } / "@" _ left:typename { new UnaryReflection(left, state) } - / match + / condition_expression + / match_expression + / primary -match +condition_expression + = "if" _ "(" _ cond:expression _ ")" _ t:expression_as_statement _ "else" _ f:expression_as_statement { new ConditionExpression(cond, GetListStatement(t), GetListStatement(f), state) } + / "if" _ "(" _ cond:expression _ ")" _ t:expression_as_statement { new ConditionExpression(cond, GetListStatement(t), new StatementList(new BaseStatement[0], state), state) } + / "if" _ "(" _ ")" _ statement? { Panic(new SyntaxError("Empty condition", state)) } + +match_expression = "match" _ "(" _ expr:expression _ ")" _ "{" _ matches:match_node<1,,";" _> _ ";"? _ "}" { new MatchExpression(expr, matches, state) } - / primary match_node , BaseStatement>> = left:(>"(" _ ")" { null } / exprs:expression<1,,"," _> { exprs }) From b80d75e9d12810fa77f62aec13df58eae5fdbc47 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Sun, 9 Jun 2024 17:15:57 +0300 Subject: [PATCH 20/69] statement-like notation --- SLThree/SLThree.csproj | 2 +- SLThree/docs/versions/0.8.0 | 2 + SLThree/syntax.peg | 96 ++++++++++++++++++++++++++++++++----- 3 files changed, 86 insertions(+), 14 deletions(-) diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 3cf58da..3b928e8 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.68 + 0.8.0-alpha.112 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md diff --git a/SLThree/docs/versions/0.8.0 b/SLThree/docs/versions/0.8.0 index 813d9c6..ba6176d 100644 --- a/SLThree/docs/versions/0.8.0 +++ b/SLThree/docs/versions/0.8.0 @@ -6,6 +6,8 @@ Language: - New context creators: `context [Name][: Ancestors] {...}` `new context [Name][: Ancestors]` + - Statement-like notation (without `;`) for expressions with body: + condition, match, context, new - Constructor method that creates new contexts `context TBase { constructor = (f) => this.f = f; };` `T1 = TBase(5); T2 = TBase(10);` diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index 203151f..df63649 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -21,6 +21,9 @@ statement / try_statement / throw_statement / e:condition_statement { new ExpressionStatement(e, state) } + / e:match_expression { new ExpressionStatement(e, state) } + / e:context_expression { new ExpressionStatement(e, state) } + / e:block_instance_expression { new ExpressionStatement(e, state) } / expression_statement / block_statement / ";" { new EmptyStatement(state) } @@ -198,6 +201,11 @@ unary / match_expression / primary +condition_statement + = "if" _ "(" _ cond:expression _ ")" _ t:statement _ "else" _ f:block_statement { new ConditionExpression(cond, GetListStatement(t), GetListStatement(f), state) } + / "if" _ "(" _ cond:expression _ ")" _ t:block_statement { new ConditionExpression(cond, GetListStatement(t), new StatementList(new BaseStatement[0], state), state) } + / "if" _ "(" _ ")" _ block_statement? { Panic(new SyntaxError("Empty condition", state)) } + condition_expression = "if" _ "(" _ cond:expression _ ")" _ t:expression_as_statement _ "else" _ f:expression_as_statement { new ConditionExpression(cond, GetListStatement(t), GetListStatement(f), state) } / "if" _ "(" _ cond:expression _ ")" _ t:expression_as_statement { new ConditionExpression(cond, GetListStatement(t), new StatementList(new BaseStatement[0], state), state) } @@ -228,12 +236,26 @@ primary -memoize / "(" _ x:expression _ ")" { x.RaisePriority() } / "<" _ t:typename<2,2,"," _> _ ">" _ "{" _ etrs:dictionary_entry <0,,"," _> _ ("," _ )? "}" { new CreatorDictionary(etrs.ToArray(), t.ToArray(), state) } / "{" _ etrs:dictionary_entry <0,,"," _> _ ("," _ )? "}" { new CreatorDictionary(etrs.ToArray(), state) } + / "new" _required_ tp:typename _ "[" _ size:expression _ "]" { new CreatorNewArray(tp, size, state) } // "new" _required_ "context" c: context { c } / "new" _required_ "using" _required_ u: using { u } + / new_context_expression + / context_expression + / instance_expression + / "(" _ args:req_arg_name<1,,"," _> _ ("," _ )? ")" { new CreatorTuple(args.ToArray(), state) } + / "(" _ args:expression<1,,"," _> _ ("," _ )? ")" { new CreatorTuple(args.ToArray(), state) } + / "<" _ t:typename _ ">" _ "-[" _ args:expression<0,,"," _> _ ("," _ )? "]" { new CreatorArray(args.ToArray(), t, state) } + / "<" _ t:typename _ ">" _ "[" _ args:expression<0,,"," _> _ ("," _ )? "]" { new CreatorList(args.ToArray(), t, state) } + / "[" _ args:expression<0,,"," _> _ ("," _ )? "]" { new CreatorList(args.ToArray(), state) } + / special + / literal + / "[" _ x:expression { Panic(new SyntaxError("Unclosed brackets", state)) } + / "(" _ x:expression { Panic(new SyntaxError("Unclosed brackets", state)) } +new_context_expression //--------CREATOR--CONTEXT------------------------------------------------- // new context Name: TBase - / "new" _required_ "context" _required_ name:primary _ ":" _ ancestors:primary<1,,"," _> { + = "new" _required_ "context" _required_ name:primary _ ":" _ ancestors:primary<1,,"," _> { new CreatorContext(name, ancestors.ToArray(), state) } //--------CREATOR--CONTEXT------------------------------------------------- @@ -251,9 +273,11 @@ primary -memoize / "new" _required_ "context" { new CreatorContext(state) } + +context_expression //--------CREATOR--CONTEXT------------------------------------------------- // context Name: TBase {} - / "context" _required_ name:primary _ ":" _ ancestors:primary<1,,"," _> + = "context" _required_ name:primary _ ":" _ ancestors:primary<1,,"," _> _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { new CreatorContext(name, ancestors.ToArray(), body, state) } @@ -275,9 +299,11 @@ primary -memoize _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { new CreatorContext(body, state) } + +instance_expression //--------CREATOR--INSTANCE------------------------------------------------ // new T(args) Name: TBase {}; - / "new" _required_ t:typename _ "(" _ args:expression<0,,"," _> _ ")" _ name:primary + = "new" _required_ t:typename _ "(" _ args:expression<0,,"," _> _ ")" _ name:primary _ ":" _ ancestors:primary<1,,"," _> _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { CreatorInstance.NamedCaseTypeArgsBodyInheritance(t, name, args.ToArray(), ancestors.ToArray(), body, state) @@ -371,16 +397,60 @@ primary -memoize / "new" _required_ t:typename { CreatorInstance.CaseType(t, state) } - / "new" _required_ tp:typename _ "[" _ size:expression _ "]" { new CreatorNewArray(tp, size, state) } - / "(" _ args:req_arg_name<1,,"," _> _ ("," _ )? ")" { new CreatorTuple(args.ToArray(), state) } - / "(" _ args:expression<1,,"," _> _ ("," _ )? ")" { new CreatorTuple(args.ToArray(), state) } - / "<" _ t:typename _ ">" _ "-[" _ args:expression<0,,"," _> _ ("," _ )? "]" { new CreatorArray(args.ToArray(), t, state) } - / "<" _ t:typename _ ">" _ "[" _ args:expression<0,,"," _> _ ("," _ )? "]" { new CreatorList(args.ToArray(), t, state) } - / "[" _ args:expression<0,,"," _> _ ("," _ )? "]" { new CreatorList(args.ToArray(), state) } - / special - / literal - / "[" _ x:expression { Panic(new SyntaxError("Unclosed brackets", state)) } - / "(" _ x:expression { Panic(new SyntaxError("Unclosed brackets", state)) } + +block_instance_expression +//--------CREATOR--INSTANCE------------------------------------------------ +// new T(args) Name: TBase {}; + = "new" _required_ t:typename _ "(" _ args:expression<0,,"," _> _ ")" _ name:primary + _ ":" _ ancestors:primary<1,,"," _> + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + CreatorInstance.NamedCaseTypeArgsBodyInheritance(t, name, args.ToArray(), ancestors.ToArray(), body, state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T(args): TBase {}; + / "new" _required_ t:typename _ "(" _ args:expression<0,,"," _> _ ")" + _ ":" _ ancestors:primary<1,,"," _> + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + CreatorInstance.CaseTypeArgsBodyInheritance(t, args.ToArray(), ancestors.ToArray(), body, state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T Name: TBase {}; + / "new" _required_ t:typename _ name:primary + _ ":" _ ancestors:primary<1,,"," _> + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + CreatorInstance.NamedCaseTypeBodyInheritance(t, name, ancestors.ToArray(), body, state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T: TBase {}; + / "new" _required_ t:typename + _ ":" _ ancestors:primary<1,,"," _> + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + CreatorInstance.CaseTypeBodyInheritance(t, ancestors.ToArray(), body, state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T(args) Name {}; + / "new" _required_ t:typename _ "(" _ args:expression<0,,"," _> _ ")" _ name:primary + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + CreatorInstance.NamedCaseTypeArgsBody(t, name, args.ToArray(), body, state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T(args) {}; + / "new" _required_ t:typename _ "(" _ args:expression<0,,"," _> _ ")" + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + CreatorInstance.CaseTypeArgsBody(t, args.ToArray(), body, state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T Name {}; + / "new" _required_ t:typename _ name:primary + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + CreatorInstance.NamedCaseTypeBody(t, name, body, state) + } +//--------CREATOR--INSTANCE------------------------------------------------ +// new T {}; + / "new" _required_ t:typename + _ body:( _ st:block_statement { new CreatorContextBody(st.Statements, st.SourceContext) }) { + CreatorInstance.CaseTypeBody(t, body, state) + } dictionary_entry = left:expression _ ":" _ right:expression { new CreatorDictionary.Entry(left, right, state) } From 125cb9810dde803f6e3729d7199f31413e973459 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Sun, 9 Jun 2024 17:29:45 +0300 Subject: [PATCH 21/69] identity --- SLThree/Methods/Method.cs | 18 ++++++++++++------ SLThree/SLThree.csproj | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/SLThree/Methods/Method.cs b/SLThree/Methods/Method.cs index 488f5ec..123e837 100644 --- a/SLThree/Methods/Method.cs +++ b/SLThree/Methods/Method.cs @@ -11,8 +11,7 @@ namespace SLThree { public class Method : ICloneable { - private static readonly Dictionary cached_method_contextes = new Dictionary(); - + private ExecutionContext cached_context; public readonly string Name; public readonly string[] ParamNames; public readonly StatementList Statements; @@ -62,10 +61,10 @@ public virtual ExecutionContext GetExecutionContext(object[] arguments, Executio } else { - if (cached_method_contextes.TryGetValue(this, out var cntx)) + if (cached_context != null) { - ret = cntx; - if (Constructor) cntx.@this = definitionplace; + ret = cached_context; + if (Constructor) cached_context.@this = definitionplace; ret.PrepareToInvoke(); } else @@ -75,7 +74,7 @@ public virtual ExecutionContext GetExecutionContext(object[] arguments, Executio @this = definitionplace }; ret.SuperContext = ret.@this.Context?.SuperContext; - cached_method_contextes.Add(this, ret); + cached_context = ret; } ret.Name = contextName; ret.PreviousContext = super_context; @@ -99,6 +98,13 @@ public virtual object GetValue(ExecutionContext old_context, object[] args) return null; } + public Method identity(ContextWrap context) + { + if (Recursive) definitionplace = context; + else cached_context = null; + return this; + } + #region Invoke [auto-generated] [MethodImpl(MethodImplOptions.AggressiveInlining)] public object Invoke() diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 3b928e8..5b6728c 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.112 + 0.8.0-alpha.114 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md From 92257a4ae14bc4bf62b192c78e9befd7f102b06a Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Sun, 9 Jun 2024 19:29:19 +0300 Subject: [PATCH 22/69] new method definitions --- .../Expressions/Creators/CreatorContext.cs | 6 +- SLThree/Expressions/FunctionDefinition.cs | 84 +++++++++++++++++++ SLThree/Expressions/LambdaExpression.cs | 3 +- .../Expressions/LambdaGenericExpression.cs | 1 - .../Operators/Binary/BinaryAssign.cs | 9 +- SLThree/Methods/GenericMethod.cs | 4 +- SLThree/Methods/Method.cs | 6 +- SLThree/SLThree.csproj | 2 +- SLThree/syntax.peg | 68 ++++++++++++++- test/parsing/recursive_fibonacci.slt | 2 +- 10 files changed, 163 insertions(+), 22 deletions(-) create mode 100644 SLThree/Expressions/FunctionDefinition.cs diff --git a/SLThree/Expressions/Creators/CreatorContext.cs b/SLThree/Expressions/Creators/CreatorContext.cs index 382a545..08f6a24 100644 --- a/SLThree/Expressions/Creators/CreatorContext.cs +++ b/SLThree/Expressions/Creators/CreatorContext.cs @@ -61,9 +61,11 @@ public CreatorContext(SourceContext context) private bool is_name_expr; private int variable_index; - private string GetName() + private string GetName() => GetLastName(Name); + public static string GetLastName(BaseExpression name) { - var n = Name.ToString(); + name.PrioriryRaised = false; + var n = name.ToString(); var index = n.LastIndexOf('.'); if (index == -1) return n; else return n.Substring(index + 1); diff --git a/SLThree/Expressions/FunctionDefinition.cs b/SLThree/Expressions/FunctionDefinition.cs new file mode 100644 index 0000000..9407ad7 --- /dev/null +++ b/SLThree/Expressions/FunctionDefinition.cs @@ -0,0 +1,84 @@ +using SLThree.Extensions.Cloning; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SLThree +{ + public class FunctionDefinition : BaseExpression + { + /* + ---Function defines--- + [MODS [Name]](args)[:TRet] {} + [MODS [Name]](args)[:TRet] => expr + [MODS [Name]](args)[:TRet] {} + [MODS [Name]](args)[:TRet] => expr + arg[:TRet] => {} + arg[:TRet] => expr + */ + + public string[] Modificators; + public BaseExpression FunctionName; + public NameExpression[] GenericArguments; + public NameExpression[] Arguments; + public StatementList FunctionBody; + public TypenameExpression ReturnTypeHint; + + public FunctionDefinition(string[] modificators, BaseExpression name, NameExpression[] generics, NameExpression[] args, StatementList body, TypenameExpression typehint, SourceContext context) : base(context) + { + Modificators = modificators; + FunctionName = name; + GenericArguments = generics; + Arguments = args; + FunctionBody = body; + ReturnTypeHint = typehint; + var many = Modificators.GroupBy(x => x).FirstOrDefault(x => x.Count() > 1); + if (many != null) throw new SyntaxError($"Repeated modifier \"{many.First()}\"", context); + + if (Method == null) + { + if (GenericArguments.Length == 0) Method = new Method( + FunctionName == null ? "$method" : CreatorContext.GetLastName(FunctionName), + Arguments.Select(x => x.Name).ToArray(), + FunctionBody, + Arguments.Select(x => x.TypeHint).ToArray(), + ReturnTypeHint, + null, + !Modificators.Contains("explicit"), + Modificators.Contains("recursive")); + else Method = new GenericMethod( + FunctionName == null ? "$method" : CreatorContext.GetLastName(FunctionName), + Arguments.Select(x => x.Name).ToArray(), + FunctionBody, + Arguments.Select(x => x.TypeHint).ToArray(), + ReturnTypeHint, + null, + !Modificators.Contains("explicit"), + Modificators.Contains("recursive"), + GenericArguments); + } + } + + public override string ExpressionToString() => $"MethodDefinition"; + + public Method Method; + private ExecutionContext counted_invoked; + private bool is_name_expr; + private int variable_index; + + public override object GetValue(ExecutionContext context) + { + Method.definitionplace = context.wrap; + if (FunctionName != null) + BinaryAssign.AssignToValue(context, FunctionName, Method, ref counted_invoked, ref is_name_expr, ref variable_index); + return Method; + } + + public override object Clone() + { + return new FunctionDefinition(Modificators.CloneArray(), FunctionName.CloneCast(), GenericArguments.CloneArray(), Arguments.CloneArray(), FunctionBody.CloneCast(), ReturnTypeHint.CloneCast(), SourceContext.CloneCast()); + } + } +} diff --git a/SLThree/Expressions/LambdaExpression.cs b/SLThree/Expressions/LambdaExpression.cs index 3241488..69d4261 100644 --- a/SLThree/Expressions/LambdaExpression.cs +++ b/SLThree/Expressions/LambdaExpression.cs @@ -30,8 +30,7 @@ public LambdaExpression(InvokeExpression invokeExpression, StatementList stateme ReturnTypeHint, null, !Modificators.Contains("explicit"), - Modificators.Contains("recursive"), - false); + Modificators.Contains("recursive")); } } diff --git a/SLThree/Expressions/LambdaGenericExpression.cs b/SLThree/Expressions/LambdaGenericExpression.cs index 9f6397e..070bdff 100644 --- a/SLThree/Expressions/LambdaGenericExpression.cs +++ b/SLThree/Expressions/LambdaGenericExpression.cs @@ -33,7 +33,6 @@ public LambdaGenericExpression(InvokeExpression invokeExpression, StatementList null, !Modificators.Contains("explicit"), Modificators.Contains("recursive"), - false, Generics); } } diff --git a/SLThree/Expressions/Operators/Binary/BinaryAssign.cs b/SLThree/Expressions/Operators/Binary/BinaryAssign.cs index 6016b45..e424014 100644 --- a/SLThree/Expressions/Operators/Binary/BinaryAssign.cs +++ b/SLThree/Expressions/Operators/Binary/BinaryAssign.cs @@ -28,8 +28,7 @@ public object AssignValue(ExecutionContext context, BaseExpression Left, object { var m2 = mth.CloneWithNewName(nl.Name); m2.UpdateContextName(); - if (m2.Binded) m2.definitionplace = mth.definitionplace; - else m2.definitionplace = new ContextWrap(context); + m2.definitionplace = new ContextWrap(context); right = m2; } variable_index = context.LocalVariables.SetValue(nl.Name, right); @@ -50,8 +49,7 @@ private static object InternalAssignToValue(ExecutionContext context, BaseExpres { var m2 = mth.CloneWithNewName(nl.Name); m2.UpdateContextName(); - if (m2.Binded) m2.definitionplace = mth.definitionplace; - else m2.definitionplace = new ContextWrap(context); + m2.definitionplace = new ContextWrap(context); right = m2; } context.LocalVariables.SetValue(nl.Name, right); @@ -89,8 +87,7 @@ public static object AssignToValue(ExecutionContext context, BaseExpression Left { var m2 = mth.CloneWithNewName(nl.Name); m2.UpdateContextName(); - if (m2.Binded) m2.definitionplace = mth.definitionplace; - else m2.definitionplace = new ContextWrap(context); + m2.definitionplace = new ContextWrap(context); right = m2; } variable_index = context.LocalVariables.SetValue(nl.Name, right); diff --git a/SLThree/Methods/GenericMethod.cs b/SLThree/Methods/GenericMethod.cs index 5ed7b4a..d89da5d 100644 --- a/SLThree/Methods/GenericMethod.cs +++ b/SLThree/Methods/GenericMethod.cs @@ -339,7 +339,7 @@ public static List FindAll(GenericMethod method) } } - public GenericMethod(string name, string[] paramNames, StatementList statements, TypenameExpression[] paramTypes, TypenameExpression returnType, ContextWrap definitionPlace, bool @implicit, bool recursive, bool binded, NameExpression[] generics) : base(name, paramNames, statements, paramTypes, returnType, definitionPlace, @implicit, recursive, binded) + public GenericMethod(string name, string[] paramNames, StatementList statements, TypenameExpression[] paramTypes, TypenameExpression returnType, ContextWrap definitionPlace, bool @implicit, bool recursive, NameExpression[] generics) : base(name, paramNames, statements, paramTypes, returnType, definitionPlace, @implicit, recursive) { Generics = generics; GenericsInfo = GenericFinder.FindAll(this); @@ -365,7 +365,7 @@ public Method MakeGenericMethod(Type[] args) public override Method CloneWithNewName(string name) { - return new GenericMethod(name, ParamNames?.CloneArray(), Statements.CloneCast(), ParamTypes?.CloneArray(), ReturnType.CloneCast(), definitionplace, Implicit, Recursive, Binded, Generics.CloneArray()); + return new GenericMethod(name, ParamNames?.CloneArray(), Statements.CloneCast(), ParamTypes?.CloneArray(), ReturnType.CloneCast(), definitionplace, Implicit, Recursive, Generics.CloneArray()); } } } diff --git a/SLThree/Methods/Method.cs b/SLThree/Methods/Method.cs index 123e837..4caf54b 100644 --- a/SLThree/Methods/Method.cs +++ b/SLThree/Methods/Method.cs @@ -17,7 +17,6 @@ public class Method : ICloneable public readonly StatementList Statements; public readonly bool Implicit = false; public readonly bool Recursive = false; - public readonly bool Binded = false; public bool Constructor = false; public TypenameExpression[] ParamTypes; @@ -29,7 +28,7 @@ public class Method : ICloneable public ContextWrap @this => definitionplace; internal protected Method() { } - public Method(string name, string[] paramNames, StatementList statements, TypenameExpression[] paramTypes, TypenameExpression returnType, ContextWrap definitionPlace, bool @implicit, bool recursive, bool binded) + public Method(string name, string[] paramNames, StatementList statements, TypenameExpression[] paramTypes, TypenameExpression returnType, ContextWrap definitionPlace, bool @implicit, bool recursive) { Name = name; ParamNames = paramNames; @@ -39,7 +38,6 @@ public Method(string name, string[] paramNames, StatementList statements, Typena definitionplace = definitionPlace; Implicit = @implicit; Recursive = recursive; - Binded = binded; } internal void UpdateContextName() => contextName = $"<{Name}>methodcontext"; @@ -226,7 +224,7 @@ public object InvokeWithContext(ExecutionContext from, object arg1, object arg2, public virtual Method CloneWithNewName(string name) { - return new Method(name, ParamNames?.CloneArray(), Statements.CloneCast(), ParamTypes?.CloneArray(), ReturnType.CloneCast(), definitionplace, Implicit, Recursive, Binded); + return new Method(name, ParamNames?.CloneArray(), Statements.CloneCast(), ParamTypes?.CloneArray(), ReturnType.CloneCast(), definitionplace, Implicit, Recursive); } public virtual object Clone() diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 5b6728c..f1bb16a 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.114 + 0.8.0-alpha.167 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index df63649..d53d897 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -24,6 +24,7 @@ statement / e:match_expression { new ExpressionStatement(e, state) } / e:context_expression { new ExpressionStatement(e, state) } / e:block_instance_expression { new ExpressionStatement(e, state) } + / e:method_definition_statement { new ExpressionStatement(e, state) } / expression_statement / block_statement / ";" { new EmptyStatement(state) } @@ -84,6 +85,10 @@ throw_statement = "throw" _required_ expr:expression _ ";" { new ThrowStatement(expr, state) } / "throw" _required_ expr:expression _ { Panic(new SyntaxError("Expected `;`", state)) } +expression_as_return + = block_statement + / value:expression { new ReturnStatement(value, state) } + expression_as_statement = block_statement / value:expression { new ExpressionStatement(value, state) } @@ -97,8 +102,11 @@ expression binary_9 -memoize = left:keyword _ ("=" / "+=" / "-=" / "*=" / "/=" / "%=" / "&=" / "|=" / "^=") _ right:binary_9 { Panic(new SyntaxError("Keywords is not a valid name", state)) } - / method + // method / left:binary_9 _ "|>" _ right:binary_7 { InjectFirst(left, right) } + / condition_expression + / match_expression + / method_definition_expression / "?" _ "=" _ right:binary_9 { new BinaryAssignUnknown(right, state) } / left:arg_name _ "=" _ right:binary_9 { new BinaryAssign(left, right, state) } / left:binary_7 _ "=" _ right:binary_9 { new BinaryAssign(left, right, state) } @@ -197,8 +205,6 @@ unary / "*" _ left:binary_min { new UnaryGetChooser(left, null, state) } / "@@" _ left:typename { new UnaryStaticReflection(left, state) } / "@" _ left:typename { new UnaryReflection(left, state) } - / condition_expression - / match_expression / primary condition_statement @@ -225,6 +231,12 @@ match_node , BaseStatement>> / block_statement ) { new ValueTuple, BaseStatement>(left, right) } +withoutinvokation_primary -memoize + = left:withoutinvokation_primary _ "." _ "?" _ "[" _ args:expression<1,,"," _> _ "]" { new IndexExpression(left, args.ToArray(), true, state) } + / left:withoutinvokation_primary _ "."? _ "[" _ args:expression<1,,"," _> _ "]" { new IndexExpression(left, args.ToArray(), false, state) } + / left:withoutinvokation_primary _ conditional:"?"? _ "." _ right:onlyname_access { new MemberAccess(left, right, conditional.Count == 1, state) } + / onlyname_access + primary -memoize = left:primary _ "." _ "?" _ "<" _ gen_args:typename<1,,"," _> _ ">" _ "(" _ args:expression<0,,"," _> _ ")" { new InvokeGenericExpression(left, gen_args.ToArray(), args.ToArray(), true, state) } / left:primary _ "."? _ "<" _ gen_args:typename<1,,"," _> _ ">" _ "(" _ args:expression<0,,"," _> _ ")" { new InvokeGenericExpression(left, gen_args.ToArray(), args.ToArray(), false, state) } @@ -461,9 +473,59 @@ access_right -memoize / right:access_right { right } / right:name { right } +onlyname_access -memoize + = left:name _ conditional:"?"? _ "." _ right:onlyname_access { new MemberAccess(left, right, conditional.Count == 1, state) } + / right:name { right } + using = t_name:typename { new CreatorUsing(t_name, state) } +method_definition_expression + = method_definition_statement + / mods_name:method_mods_name? + generics:method_generic_part? + "(" _ args:arg_name<0,,"," _> _ ")" + ret:( _ ":" _ t:typename {t})? _ "=>" _ value:expression + { + new FunctionDefinition(GetOptional(mods_name)?.Item1 ?? new string[0], GetOptional(mods_name)?.Item2, GetOptional(generics)?.ToArray() ?? new NameExpression[0], args.ToArray(), GetListStatement(new ReturnStatement(value, state)), GetOptional(ret), state) + } + / mods_name:method_mods_name? + generics:method_generic_part? + "(" _ args:arg_name<0,,"," _> _ ")" + ret:( _ ":" _ t:typename {t})? _ "=>" _ body:block_statement + { + new FunctionDefinition(GetOptional(mods_name)?.Item1 ?? new string[0], GetOptional(mods_name)?.Item2, GetOptional(generics)?.ToArray() ?? new NameExpression[0], args.ToArray(), body, GetOptional(ret), state) + } + / generics:method_generic_part? + arg:arg_name + ret:( _ ":" _ t:typename {t})? _ "=>" _ body:block_statement + { + new FunctionDefinition(new string[0], null, GetOptional(generics)?.ToArray() ?? new NameExpression[0], new NameExpression[1] {arg}, GetListStatement(body), GetOptional(ret), state) + } + / generics:method_generic_part? + arg:arg_name + ret:( _ ":" _ t:typename {t})? _ "=>" _ value:expression + { + new FunctionDefinition(new string[0], null, GetOptional(generics)?.ToArray() ?? new NameExpression[0], new NameExpression[1] {arg}, GetListStatement(new ReturnStatement(value, state)), GetOptional(ret), state) + } + +method_definition_statement + = mods_name:method_mods_name? + generics:method_generic_part? + "(" _ args:arg_name<0,,"," _> _ ")" + ret:( _ ":" _ t:typename {t})? _ + body:block_statement { + new FunctionDefinition(GetOptional(mods_name)?.Item1 ?? new string[0], GetOptional(mods_name)?.Item2, GetOptional(generics)?.ToArray() ?? new NameExpression[0], args.ToArray(), body, GetOptional(ret), state) + } + +method_generic_part > + = "<" _ generic_args:name<1,,"," _> _ ">" _ { generic_args } + +method_mods_name > + = mods:method_modificator<1,,_required_> _required_ name:withoutinvokation_primary _ { new Tuple(mods.ToArray(), name) } + / mods:method_modificator<1,,_required_> _ { new Tuple(mods.ToArray(), null) } + / name:withoutinvokation_primary _ { new Tuple(new string[0], name) } + generic_lambda = left:( , NameExpression[], TypenameExpression, NameExpression[]>> diff --git a/test/parsing/recursive_fibonacci.slt b/test/parsing/recursive_fibonacci.slt index 4e9b6f4..40547b5 100644 --- a/test/parsing/recursive_fibonacci.slt +++ b/test/parsing/recursive_fibonacci.slt @@ -1,4 +1,4 @@ -global.fib = recursive n => { +global.fib = recursive (n) => { if (n < 2) { return n; } From c57404c484099b65423800a0d35dd46b02622f10 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Mon, 10 Jun 2024 01:53:41 +0300 Subject: [PATCH 23/69] fix #125 --- SLThree/Expressions/InvokeExpression.cs | 18 +++++++----------- .../Expressions/InvokeGenericExpression.cs | 19 +++++++------------ SLThree/docs/versions/0.8.0 | 4 +++- 3 files changed, 17 insertions(+), 24 deletions(-) diff --git a/SLThree/Expressions/InvokeExpression.cs b/SLThree/Expressions/InvokeExpression.cs index 24e0501..e61ea41 100644 --- a/SLThree/Expressions/InvokeExpression.cs +++ b/SLThree/Expressions/InvokeExpression.cs @@ -27,10 +27,8 @@ public InvokeExpression(BaseExpression name, BaseExpression[] arguments, bool nu public override string ExpressionToString() => $"{Left}{(null_conditional ? ".?" : "")}({Arguments.JoinIntoString(", ")})"; - public object GetValue(ExecutionContext context, object[] args) + public object InvokeForObj(ExecutionContext context, object[] args, object o) { - var o = Left.GetValue(context); - if (o == null) { if (null_conditional) return null; @@ -71,6 +69,11 @@ public object GetValue(ExecutionContext context, object[] args) throw new RuntimeError($"{o.GetType().GetTypeString()} is not allow to invoke", SourceContext); } + public object GetValue(ExecutionContext context, object[] args) + { + return (context, args, Left.GetValue(context)); + } + public override object GetValue(ExecutionContext context) { return GetValue(context, Arguments.ConvertAll(x => x.GetValue(context))); @@ -96,14 +99,7 @@ public object GetValue(ExecutionContext context, object obj) if (founded == null) throw new RuntimeError($"Method `{key}({Arguments.Select(x => "_").JoinIntoString(", ")})` not found", SourceContext); return founded.Invoke(null, Arguments.ConvertAll(x => x.GetValue(context))); } - else if (obj != null) - { - return obj.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance) - .FirstOrDefault(x => x.Name == key && x.GetParameters().Length == Arguments.Length) - .Invoke(obj, Arguments.ConvertAll(x => x.GetValue(context))); - } - - return null; + else return InvokeForObj(context, Arguments.ConvertAll(x => x.GetValue(context)), obj); } public override object Clone() diff --git a/SLThree/Expressions/InvokeGenericExpression.cs b/SLThree/Expressions/InvokeGenericExpression.cs index 30ae0a6..91d7234 100644 --- a/SLThree/Expressions/InvokeGenericExpression.cs +++ b/SLThree/Expressions/InvokeGenericExpression.cs @@ -30,10 +30,8 @@ public InvokeGenericExpression(BaseExpression left, TypenameExpression[] generic public override string ExpressionToString() => $"{Left}{(null_conditional ? ".?" : "")}<{GenericArguments.JoinIntoString(", ")}>({Arguments.JoinIntoString(", ")})"; - public object GetValue(ExecutionContext context, Type[] generic_args, object[] args) + public object InvokeForObj(ExecutionContext context, Type[] generic_args, object[] args, object o) { - var o = Left.GetValue(context); - if (o == null) { if (null_conditional) return null; @@ -65,6 +63,11 @@ public object GetValue(ExecutionContext context, Type[] generic_args, object[] a throw new RuntimeError($"{o.GetType().GetTypeString()} is not allow to invoke", SourceContext); } + public object GetValue(ExecutionContext context, Type[] generic_args, object[] args) + { + return InvokeForObj(context, generic_args, args, Left.GetValue(context)); + } + public override object GetValue(ExecutionContext context) { return GetValue(context, GenericArguments.ConvertAll(x => (Type)x.GetValue(context)), Arguments.ConvertAll(x => x.GetValue(context))); @@ -91,15 +94,7 @@ public object GetValue(ExecutionContext context, object obj) if (founded == null) throw new RuntimeError($"Method `{key}({Arguments.Select(x => "_").JoinIntoString(", ")})` not found", SourceContext); return founded.MakeGenericMethod(generic_args).Invoke(null, Arguments.ConvertAll(x => x.GetValue(context))); } - else if (obj != null) - { - return obj.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance) - .FirstOrDefault(x => x.Name == key && x.GetParameters().Length == Arguments.Length) - .MakeGenericMethod(generic_args) - .Invoke(obj, Arguments.ConvertAll(x => x.GetValue(context))); - } - - return null; + else return InvokeForObj(context, generic_args, Arguments.ConvertAll(x => x.GetValue(context)), obj); } public override object Clone() diff --git a/SLThree/docs/versions/0.8.0 b/SLThree/docs/versions/0.8.0 index ba6176d..0406692 100644 --- a/SLThree/docs/versions/0.8.0 +++ b/SLThree/docs/versions/0.8.0 @@ -21,4 +21,6 @@ Language: `new context {...}` -> `context {...}` Optimization: - Wrappers refactoring, minumum 3x faster wrapping - minimum 20x faster unwrapping \ No newline at end of file + minimum 20x faster unwrapping +Bugfixes: + - Fixed object invokation (#125) \ No newline at end of file From c976ff843f18f4a197557cf52fecba88df178e30 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Mon, 10 Jun 2024 01:56:24 +0300 Subject: [PATCH 24/69] static expression --- SLThree/Expressions/StaticExpression.cs | 31 +++++++++++++++++++++++++ SLThree/docs/versions/0.8.0 | 1 + SLThree/syntax.peg | 1 + 3 files changed, 33 insertions(+) create mode 100644 SLThree/Expressions/StaticExpression.cs diff --git a/SLThree/Expressions/StaticExpression.cs b/SLThree/Expressions/StaticExpression.cs new file mode 100644 index 0000000..6d7aa95 --- /dev/null +++ b/SLThree/Expressions/StaticExpression.cs @@ -0,0 +1,31 @@ +using SLThree.Extensions.Cloning; + +namespace SLThree +{ + public class StaticExpression : BaseExpression + { + public BaseExpression Right; + + public StaticExpression(BaseExpression right, SourceContext context) : base(context) + { + Right = right; + } + + public override string ExpressionToString() => $"static {Right}"; + + private bool done; + private object obj; + + public override object GetValue(ExecutionContext context) + { + if (done) return obj; + done = true; + return obj = Right.GetValue(context); + } + + public override object Clone() + { + return new StaticExpression(Right.CloneCast(), SourceContext.CloneCast()); + } + } +} diff --git a/SLThree/docs/versions/0.8.0 b/SLThree/docs/versions/0.8.0 index 0406692..b8581bd 100644 --- a/SLThree/docs/versions/0.8.0 +++ b/SLThree/docs/versions/0.8.0 @@ -11,6 +11,7 @@ Language: - Constructor method that creates new contexts `context TBase { constructor = (f) => this.f = f; };` `T1 = TBase(5); T2 = TBase(10);` + - Static expression (will be executed only once) `static x` - Condition expression instead of condition statement - Changed context syntax: `new context Name: T {...}` -> `new T Name {...}` diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index d53d897..86de5bd 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -103,6 +103,7 @@ expression binary_9 -memoize = left:keyword _ ("=" / "+=" / "-=" / "*=" / "/=" / "%=" / "&=" / "|=" / "^=") _ right:binary_9 { Panic(new SyntaxError("Keywords is not a valid name", state)) } // method + / "static" _required_ left:expression { new StaticExpression(left, state) } / left:binary_9 _ "|>" _ right:binary_7 { InjectFirst(left, right) } / condition_expression / match_expression From fd2fcb44d49b897ff2c91307eb1fd887de9d8abb Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Mon, 10 Jun 2024 02:07:01 +0300 Subject: [PATCH 25/69] static method statement-like --- SLThree/Expressions/InvokeExpression.cs | 2 +- SLThree/syntax.peg | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/SLThree/Expressions/InvokeExpression.cs b/SLThree/Expressions/InvokeExpression.cs index e61ea41..9ab8b2c 100644 --- a/SLThree/Expressions/InvokeExpression.cs +++ b/SLThree/Expressions/InvokeExpression.cs @@ -71,7 +71,7 @@ public object InvokeForObj(ExecutionContext context, object[] args, object o) public object GetValue(ExecutionContext context, object[] args) { - return (context, args, Left.GetValue(context)); + return InvokeForObj(context, args, Left.GetValue(context)); } public override object GetValue(ExecutionContext context) diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index 86de5bd..5a88164 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -24,6 +24,8 @@ statement / e:match_expression { new ExpressionStatement(e, state) } / e:context_expression { new ExpressionStatement(e, state) } / e:block_instance_expression { new ExpressionStatement(e, state) } + / "static" _required_ e:method_definition_statement { new ExpressionStatement(new StaticExpression(e, state), state) } + / "static" _ e:method_definition_nswm { new ExpressionStatement(new StaticExpression(e, state), state) } / e:method_definition_statement { new ExpressionStatement(e, state) } / expression_statement / block_statement @@ -519,6 +521,14 @@ method_definition_statement new FunctionDefinition(GetOptional(mods_name)?.Item1 ?? new string[0], GetOptional(mods_name)?.Item2, GetOptional(generics)?.ToArray() ?? new NameExpression[0], args.ToArray(), body, GetOptional(ret), state) } +method_definition_nswm + = generics:method_generic_part? + "(" _ args:arg_name<0,,"," _> _ ")" + ret:( _ ":" _ t:typename {t})? _ + body:block_statement { + new FunctionDefinition(new string[0], null, GetOptional(generics)?.ToArray() ?? new NameExpression[0], args.ToArray(), body, GetOptional(ret), state) + } + method_generic_part > = "<" _ generic_args:name<1,,"," _> _ ">" _ { generic_args } From a6f5c42d79e9b8032f7c34eb1240d7da4f4c52be Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Mon, 10 Jun 2024 02:17:48 +0300 Subject: [PATCH 26/69] more statement-like method defs --- SLThree/syntax.peg | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index 5a88164..0461180 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -484,7 +484,7 @@ using = t_name:typename { new CreatorUsing(t_name, state) } method_definition_expression - = method_definition_statement + = method_definition_statement1 / mods_name:method_mods_name? generics:method_generic_part? "(" _ args:arg_name<0,,"," _> _ ")" @@ -492,34 +492,42 @@ method_definition_expression { new FunctionDefinition(GetOptional(mods_name)?.Item1 ?? new string[0], GetOptional(mods_name)?.Item2, GetOptional(generics)?.ToArray() ?? new NameExpression[0], args.ToArray(), GetListStatement(new ReturnStatement(value, state)), GetOptional(ret), state) } - / mods_name:method_mods_name? - generics:method_generic_part? - "(" _ args:arg_name<0,,"," _> _ ")" - ret:( _ ":" _ t:typename {t})? _ "=>" _ body:block_statement - { - new FunctionDefinition(GetOptional(mods_name)?.Item1 ?? new string[0], GetOptional(mods_name)?.Item2, GetOptional(generics)?.ToArray() ?? new NameExpression[0], args.ToArray(), body, GetOptional(ret), state) - } - / generics:method_generic_part? - arg:arg_name - ret:( _ ":" _ t:typename {t})? _ "=>" _ body:block_statement - { - new FunctionDefinition(new string[0], null, GetOptional(generics)?.ToArray() ?? new NameExpression[0], new NameExpression[1] {arg}, GetListStatement(body), GetOptional(ret), state) - } + / method_definition_statement2 + / method_definition_statement3 / generics:method_generic_part? arg:arg_name ret:( _ ":" _ t:typename {t})? _ "=>" _ value:expression { new FunctionDefinition(new string[0], null, GetOptional(generics)?.ToArray() ?? new NameExpression[0], new NameExpression[1] {arg}, GetListStatement(new ReturnStatement(value, state)), GetOptional(ret), state) } - method_definition_statement + = method_definition_statement1 + / method_definition_statement2 + / method_definition_statement3 + +method_definition_statement1 = mods_name:method_mods_name? generics:method_generic_part? "(" _ args:arg_name<0,,"," _> _ ")" - ret:( _ ":" _ t:typename {t})? _ - body:block_statement { + ret:( _ ":" _ t:typename {t})? _ body:block_statement { new FunctionDefinition(GetOptional(mods_name)?.Item1 ?? new string[0], GetOptional(mods_name)?.Item2, GetOptional(generics)?.ToArray() ?? new NameExpression[0], args.ToArray(), body, GetOptional(ret), state) } +method_definition_statement2 + = mods_name:method_mods_name? + generics:method_generic_part? + "(" _ args:arg_name<0,,"," _> _ ")" + ret:( _ ":" _ t:typename {t})? _ "=>" _ body:block_statement + { + new FunctionDefinition(GetOptional(mods_name)?.Item1 ?? new string[0], GetOptional(mods_name)?.Item2, GetOptional(generics)?.ToArray() ?? new NameExpression[0], args.ToArray(), body, GetOptional(ret), state) + } +method_definition_statement3 + = generics:method_generic_part? + arg:arg_name + ret:( _ ":" _ t:typename {t})? _ "=>" _ body:block_statement + { + new FunctionDefinition(new string[0], null, GetOptional(generics)?.ToArray() ?? new NameExpression[0], new NameExpression[1] {arg}, GetListStatement(body), GetOptional(ret), state) + } + method_definition_nswm = generics:method_generic_part? From 65dfce2995495361a312331a77885ce00461f8c1 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Mon, 10 Jun 2024 02:18:44 +0300 Subject: [PATCH 27/69] commit version and changelog --- SLThree/SLThree.csproj | 2 +- SLThree/docs/versions/0.8.0 | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index f1bb16a..e9fa072 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.167 + 0.8.0-alpha.203 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md diff --git a/SLThree/docs/versions/0.8.0 b/SLThree/docs/versions/0.8.0 index b8581bd..e055f09 100644 --- a/SLThree/docs/versions/0.8.0 +++ b/SLThree/docs/versions/0.8.0 @@ -1,5 +1,8 @@ ------ 0.8.0 ------ [~.~.~] Language: + - New method definition syntax + `[modifs][Name][](args) {...}` + `[modifs][Name][](args) => value` - You can now copy contexts with ":" in the following cases: - New initializers: // [] - optional `new T [Name][: Ancestors][{...}]` @@ -7,7 +10,7 @@ Language: `context [Name][: Ancestors] {...}` `new context [Name][: Ancestors]` - Statement-like notation (without `;`) for expressions with body: - condition, match, context, new + condition, match, context, new, methods - Constructor method that creates new contexts `context TBase { constructor = (f) => this.f = f; };` `T1 = TBase(5); T2 = TBase(10);` From 144454db93e734af47bc5124f67779949c12c58d Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Mon, 10 Jun 2024 02:20:17 +0300 Subject: [PATCH 28/69] fix context name definition --- SLThree/Expressions/Creators/CreatorContext.cs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/SLThree/Expressions/Creators/CreatorContext.cs b/SLThree/Expressions/Creators/CreatorContext.cs index 08f6a24..18729bf 100644 --- a/SLThree/Expressions/Creators/CreatorContext.cs +++ b/SLThree/Expressions/Creators/CreatorContext.cs @@ -27,13 +27,7 @@ context Name {} public CreatorContext(BaseExpression name, BaseExpression[] ancestors, CreatorContextBody body, bool is_free_creator, SourceContext context) : base(context) { - if (!is_free_creator) - { - if (!is_free_creator && name is MemberAccess access) - Name = access.Right as NameExpression; - else Name = name as NameExpression; - } - else Name = name; + Name = name; Ancestors = ancestors; CreatorBody = body; IsFreeCreator = is_free_creator; @@ -81,7 +75,7 @@ public override object GetValue(ExecutionContext context) var wrap = ret.wrap; if (HasName) { - ret.Name = IsFreeCreator ? GetName() : Name.ToString(); + ret.Name = GetName(); if (IsFreeCreator) BinaryAssign.AssignToValue(context, Name, wrap, ref counted_invoked, ref is_name_expr, ref variable_index); } From 97e8ca982d2acdbe9654f63bbee3f725db61a6a2 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Mon, 10 Jun 2024 02:30:43 +0300 Subject: [PATCH 29/69] string repr for function definition --- SLThree/Expressions/FunctionDefinition.cs | 21 ++++++++++++++++++++- SLThree/Expressions/NameExpression.cs | 2 +- SLThree/SLThree.csproj | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/SLThree/Expressions/FunctionDefinition.cs b/SLThree/Expressions/FunctionDefinition.cs index 9407ad7..7a48197 100644 --- a/SLThree/Expressions/FunctionDefinition.cs +++ b/SLThree/Expressions/FunctionDefinition.cs @@ -61,7 +61,26 @@ public FunctionDefinition(string[] modificators, BaseExpression name, NameExpres } } - public override string ExpressionToString() => $"MethodDefinition"; + public override string ExpressionToString() + { + var sb = new StringBuilder(); + + sb.Append(Modificators.JoinIntoString(" ")); + if (FunctionName != null) + { + if (Modificators.Length > 0) sb.Append(" "); + sb.Append($"{FunctionName}"); + } + if (GenericArguments.Length > 0) sb.Append($"<{GenericArguments.JoinIntoString(", ")}>"); + sb.Append($"({Arguments.JoinIntoString(", ")})"); + if (ReturnTypeHint != null) + sb.Append($": {ReturnTypeHint}"); + if (FunctionBody.Statements.Length == 1 && FunctionBody.Statements[0] is ReturnStatement statement && !statement.VoidReturn) + sb.Append($" => {statement.Expression}"); + else sb.Append($"{{{FunctionBody}}}"); + + return sb.ToString(); + } public Method Method; private ExecutionContext counted_invoked; diff --git a/SLThree/Expressions/NameExpression.cs b/SLThree/Expressions/NameExpression.cs index 6307ba7..9d0ea95 100644 --- a/SLThree/Expressions/NameExpression.cs +++ b/SLThree/Expressions/NameExpression.cs @@ -14,7 +14,7 @@ public NameExpression(string name, TypenameExpression typehint, SourceContext co TypeHint = typehint; } - public override string ExpressionToString() => Name; + public override string ExpressionToString() => $"{(TypeHint == null?"":TypeHint.ToString())}{Name}"; private ExecutionContext counted; private int variable_index; diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index e9fa072..0070f65 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.203 + 0.8.0-alpha.205 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md From cffe64ef51e1383352bb0c6522123b3d07014a6d Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Mon, 10 Jun 2024 02:45:05 +0300 Subject: [PATCH 30/69] method first binding --- SLThree/ExecutionContext.cs | 12 ++---- SLThree/Expressions/FunctionDefinition.cs | 14 +++++-- SLThree/Expressions/LambdaExpression.cs | 2 +- .../Expressions/LambdaGenericExpression.cs | 2 +- SLThree/Expressions/MemberAccess.cs | 13 +++++-- .../Operators/Binary/BinaryAssign.cs | 39 +++++++++++++------ SLThree/Methods/Method.cs | 18 ++++++--- SLThree/SLThree.csproj | 2 +- SLThree/docs/versions/0.8.0 | 1 + 9 files changed, 66 insertions(+), 37 deletions(-) diff --git a/SLThree/ExecutionContext.cs b/SLThree/ExecutionContext.cs index 5ee1cc0..43e37f6 100644 --- a/SLThree/ExecutionContext.cs +++ b/SLThree/ExecutionContext.cs @@ -121,8 +121,7 @@ public ExecutionContext CreateInstance(Method constructor, object[] args) var ret = new ExecutionContext(super.Context); ret.Name = $"{Name}@{Convert.ToString(Creations++, 16).ToUpper().PadLeft(4, '0')}"; ret.@base = wrap; - constructor.Constructor = true; - constructor.definitionplace = ret.wrap; + constructor.@this = ret.wrap; constructor.GetValue(ret, args); return ret; } @@ -135,16 +134,14 @@ public ExecutionContext CreateInstance(object[] args, SourceContext sourceContex { if (constructor.ParamNames.Length != args.Length) throw new RuntimeError("Call constructor with wrong arguments count", sourceContext); - constructor.Constructor = true; - constructor.definitionplace = ret.wrap; + constructor.@this = ret.wrap; constructor.GetValue(ret, args); } return ret; } public void Implementation(ExecutionContext ret, Method constructor, object[] args) { - constructor.Constructor = true; - constructor.definitionplace = ret.wrap; + constructor.@this = ret.wrap; constructor.GetValue(ret, args); } public void Implementation(ExecutionContext ret, object[] args, SourceContext sourceContext) @@ -153,8 +150,7 @@ public void Implementation(ExecutionContext ret, object[] args, SourceContext so { if (constructor.ParamNames.Length != args.Length) throw new RuntimeError("Call constructor with wrong arguments count", sourceContext); - constructor.Constructor = true; - constructor.definitionplace = ret.wrap; + constructor.@this = ret.wrap; constructor.GetValue(ret, args); } } diff --git a/SLThree/Expressions/FunctionDefinition.cs b/SLThree/Expressions/FunctionDefinition.cs index 7a48197..3238e28 100644 --- a/SLThree/Expressions/FunctionDefinition.cs +++ b/SLThree/Expressions/FunctionDefinition.cs @@ -1,7 +1,9 @@ -using SLThree.Extensions.Cloning; +using SLThree.Extensions; +using SLThree.Extensions.Cloning; using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; @@ -89,10 +91,14 @@ public override string ExpressionToString() public override object GetValue(ExecutionContext context) { - Method.definitionplace = context.wrap; + var method = Method.CloneCast(); + method.@this = context.wrap; if (FunctionName != null) - BinaryAssign.AssignToValue(context, FunctionName, Method, ref counted_invoked, ref is_name_expr, ref variable_index); - return Method; + { + method.Name = CreatorContext.GetLastName(FunctionName); + BinaryAssign.AssignToValue(context, FunctionName, method, ref counted_invoked, ref is_name_expr, ref variable_index); + } + return method; } public override object Clone() diff --git a/SLThree/Expressions/LambdaExpression.cs b/SLThree/Expressions/LambdaExpression.cs index 69d4261..c397b23 100644 --- a/SLThree/Expressions/LambdaExpression.cs +++ b/SLThree/Expressions/LambdaExpression.cs @@ -39,7 +39,7 @@ public LambdaExpression(InvokeExpression invokeExpression, StatementList stateme public Method Method; public override object GetValue(ExecutionContext context) { - Method.definitionplace = context.wrap; + Method.@this = context.wrap; return Method; } diff --git a/SLThree/Expressions/LambdaGenericExpression.cs b/SLThree/Expressions/LambdaGenericExpression.cs index 070bdff..55400d8 100644 --- a/SLThree/Expressions/LambdaGenericExpression.cs +++ b/SLThree/Expressions/LambdaGenericExpression.cs @@ -42,7 +42,7 @@ public LambdaGenericExpression(InvokeExpression invokeExpression, StatementList public Method Method; public override object GetValue(ExecutionContext context) { - Method.definitionplace = context.wrap; + Method.@this = context.wrap; return Method; } diff --git a/SLThree/Expressions/MemberAccess.cs b/SLThree/Expressions/MemberAccess.cs index 334892d..fb9779b 100644 --- a/SLThree/Expressions/MemberAccess.cs +++ b/SLThree/Expressions/MemberAccess.cs @@ -145,10 +145,15 @@ public void SetValue(ExecutionContext context, ref object value) counted_other_context_assign = true; if (value is Method mth) { - mth = mth.CloneWithNewName(nameExpression2.Name); - mth.UpdateContextName(); - mth.definitionplace = new ContextWrap(context); - value = mth; + if (mth.Binded) value = mth; + else + { + mth.Name = nameExpression2.Name; + mth.UpdateContextName(); + mth.@this = new ContextWrap(context); + mth.Binded = true; + value = mth; + } } context.LocalVariables.SetValue(other_context_name, value); } diff --git a/SLThree/Expressions/Operators/Binary/BinaryAssign.cs b/SLThree/Expressions/Operators/Binary/BinaryAssign.cs index e424014..6ca18b0 100644 --- a/SLThree/Expressions/Operators/Binary/BinaryAssign.cs +++ b/SLThree/Expressions/Operators/Binary/BinaryAssign.cs @@ -26,10 +26,15 @@ public object AssignValue(ExecutionContext context, BaseExpression Left, object { if (right is Method mth) { - var m2 = mth.CloneWithNewName(nl.Name); - m2.UpdateContextName(); - m2.definitionplace = new ContextWrap(context); - right = m2; + if (mth.Binded) right = mth; + else + { + mth.Name = nl.Name; + mth.UpdateContextName(); + mth.@this = new ContextWrap(context); + mth.Binded = true; + right = mth; + } } variable_index = context.LocalVariables.SetValue(nl.Name, right); is_name_expr = true; @@ -47,10 +52,15 @@ private static object InternalAssignToValue(ExecutionContext context, BaseExpres { if (right is Method mth) { - var m2 = mth.CloneWithNewName(nl.Name); - m2.UpdateContextName(); - m2.definitionplace = new ContextWrap(context); - right = m2; + if (mth.Binded) right = mth; + else + { + mth.Name = nl.Name; + mth.UpdateContextName(); + mth.@this = new ContextWrap(context); + mth.Binded = true; + right = mth; + } } context.LocalVariables.SetValue(nl.Name, right); return right; @@ -85,10 +95,15 @@ public static object AssignToValue(ExecutionContext context, BaseExpression Left { if (right is Method mth) { - var m2 = mth.CloneWithNewName(nl.Name); - m2.UpdateContextName(); - m2.definitionplace = new ContextWrap(context); - right = m2; + if (mth.Binded) right = mth; + else + { + mth.Name = nl.Name; + mth.UpdateContextName(); + mth.@this = new ContextWrap(context); + mth.Binded = true; + right = mth; + } } variable_index = context.LocalVariables.SetValue(nl.Name, right); is_name_expr = true; diff --git a/SLThree/Methods/Method.cs b/SLThree/Methods/Method.cs index 4caf54b..67157ef 100644 --- a/SLThree/Methods/Method.cs +++ b/SLThree/Methods/Method.cs @@ -12,12 +12,12 @@ namespace SLThree public class Method : ICloneable { private ExecutionContext cached_context; - public readonly string Name; + public string Name; public readonly string[] ParamNames; public readonly StatementList Statements; public readonly bool Implicit = false; public readonly bool Recursive = false; - public bool Constructor = false; + public bool Binded = false; public TypenameExpression[] ParamTypes; public TypenameExpression ReturnType; @@ -25,7 +25,14 @@ public class Method : ICloneable internal ContextWrap definitionplace; internal string contextName = ""; - public ContextWrap @this => definitionplace; + public ContextWrap @this + { + get => definitionplace; internal set + { + definitionplace = value; + cached_context = null; + } + } internal protected Method() { } public Method(string name, string[] paramNames, StatementList statements, TypenameExpression[] paramTypes, TypenameExpression returnType, ContextWrap definitionPlace, bool @implicit, bool recursive) @@ -62,7 +69,6 @@ public virtual ExecutionContext GetExecutionContext(object[] arguments, Executio if (cached_context != null) { ret = cached_context; - if (Constructor) cached_context.@this = definitionplace; ret.PrepareToInvoke(); } else @@ -98,8 +104,8 @@ public virtual object GetValue(ExecutionContext old_context, object[] args) public Method identity(ContextWrap context) { - if (Recursive) definitionplace = context; - else cached_context = null; + @this = context; + Binded = true; return this; } diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 0070f65..98bdf51 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.205 + 0.8.0-alpha.209 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md diff --git a/SLThree/docs/versions/0.8.0 b/SLThree/docs/versions/0.8.0 index e055f09..4c2ee45 100644 --- a/SLThree/docs/versions/0.8.0 +++ b/SLThree/docs/versions/0.8.0 @@ -16,6 +16,7 @@ Language: `T1 = TBase(5); T2 = TBase(10);` - Static expression (will be executed only once) `static x` - Condition expression instead of condition statement + - Strong method binding - Changed context syntax: `new context Name: T {...}` -> `new T Name {...}` `new context: T {...}` -> `new T {...}` From 9182beed315facaeeed8efb7548fe20e94750613 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Mon, 10 Jun 2024 02:49:51 +0300 Subject: [PATCH 31/69] notepadpp highlighting --- SLThree/docs/SLThree_Notepad++_highlighting.xml | 2 +- SLThree/syntax.peg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SLThree/docs/SLThree_Notepad++_highlighting.xml b/SLThree/docs/SLThree_Notepad++_highlighting.xml index 2e5d5ad..77992f4 100644 --- a/SLThree/docs/SLThree_Notepad++_highlighting.xml +++ b/SLThree/docs/SLThree_Notepad++_highlighting.xml @@ -24,7 +24,7 @@ - new as is true false null using context self this global upper super private recursive explicit + new as is true false null using context self this global upper super private recursive explicit static constructor u8 i8 u16 i16 u32 i32 u64 i64 f64 f32 string bool any char list dict tuple while return break continue if else foreach in try catch finally match throw \n \t \r \\\ diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index 0461180..b97891f 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -675,7 +675,7 @@ num_literal / i64:([0-9_]+ ("i64")?) { new LongLiteral (long.Parse (i64.Replace("i64", "").Replace("_", ""), CultureInfo.InvariantCulture), i64, state) } keyword - = "while" / "if" / "else" / "foreach" / "return" / "break" / "continue" + = "while" / "if" / "else" / "foreach" / "return" / "break" / "continue" / "static" / "using" / "context" / "new" / "match" / "self" / "upper" / "this" / "global" / "super" / "private" / "try" / "catch" / "finally" / "throw" From 2616a445409d5ef617bf8dbb934d41ac75164397 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Mon, 10 Jun 2024 13:55:35 +0300 Subject: [PATCH 32/69] fixed unwrapping 0 members types --- SLThree/SLThree.csproj | 2 +- SLThree/Wrapper.cs | 98 ++++++++++++++++++++++-------------------- 2 files changed, 52 insertions(+), 48 deletions(-) diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 98bdf51..176f3ba 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.209 + 0.8.0-alpha.213 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md diff --git a/SLThree/Wrapper.cs b/SLThree/Wrapper.cs index 2a69ad0..33eadd4 100644 --- a/SLThree/Wrapper.cs +++ b/SLThree/Wrapper.cs @@ -759,65 +759,69 @@ void SetElement(WrappingMemberInfo elem, ILGenerator il) { var unwrapper_dm = new DynamicMethod("Unwrapper", Void, new Type[] { LocalsType, type }); var unwrapper_il = unwrapper_dm.GetILGenerator(); - unwrapper_il.DeclareLocal(typeof(int)); - unwrapper_il.DeclareLocal(typeof(object[])); - unwrapper_il.DeclareLocal(typeof(ContextWrap)); - unwrapper_il.Emit(OpCodes.Ldc_I4_0); - unwrapper_il.Emit(OpCodes.Stloc_0); - unwrapper_il.Emit(OpCodes.Ldarg_0); - unwrapper_il.Emit(OpCodes.Ldfld, typeof(LocalVariablesContainer).GetField("NamedIdentificators")); - unwrapper_il.Emit(OpCodes.Ldarg_0); - unwrapper_il.Emit(OpCodes.Ldfld, typeof(LocalVariablesContainer).GetField("Variables")); - unwrapper_il.Emit(OpCodes.Stloc_1); + if (elems.Count > 0) + { + unwrapper_il.DeclareLocal(typeof(int)); + unwrapper_il.DeclareLocal(typeof(object[])); + unwrapper_il.DeclareLocal(typeof(ContextWrap)); + unwrapper_il.Emit(OpCodes.Ldc_I4_0); + unwrapper_il.Emit(OpCodes.Stloc_0); + unwrapper_il.Emit(OpCodes.Ldarg_0); + unwrapper_il.Emit(OpCodes.Ldfld, typeof(LocalVariablesContainer).GetField("NamedIdentificators")); + unwrapper_il.Emit(OpCodes.Ldarg_0); + unwrapper_il.Emit(OpCodes.Ldfld, typeof(LocalVariablesContainer).GetField("Variables")); + unwrapper_il.Emit(OpCodes.Stloc_1); - var label = default(Label); - for (var i = 0; i < elems.Count; i++) - { - if (elems[i].IsWrapReadonly) continue; - if (i < elems.Count - 1) unwrapper_il.Emit(OpCodes.Dup); + var label = default(Label); - unwrapper_il.Emit(OpCodes.Ldstr, elems[i].MemberInfo.Name); - unwrapper_il.Emit(OpCodes.Ldloca_S, 0); - unwrapper_il.Emit(OpCodes.Callvirt, typeof(Dictionary).GetMethod("TryGetValue")); - unwrapper_il.Emit(OpCodes.Brfalse_S, label = unwrapper_il.DefineLabel()); + for (var i = 0; i < elems.Count; i++) + { + if (elems[i].IsWrapReadonly) continue; + if (i < elems.Count - 1) unwrapper_il.Emit(OpCodes.Dup); + unwrapper_il.Emit(OpCodes.Ldstr, elems[i].MemberInfo.Name); + unwrapper_il.Emit(OpCodes.Ldloca_S, 0); + unwrapper_il.Emit(OpCodes.Callvirt, typeof(Dictionary).GetMethod("TryGetValue")); + unwrapper_il.Emit(OpCodes.Brfalse_S, label = unwrapper_il.DefineLabel()); - var elem_type = GetElementType(elems[i]); - if (elems[i].IsContext) - { - unwrapper_il.Emit(OpCodes.Ldloc_1); - unwrapper_il.Emit(OpCodes.Ldloc_0); - unwrapper_il.Emit(OpCodes.Ldelem_Ref); - unwrapper_il.Emit(OpCodes.Isinst, typeof(ContextWrap)); - unwrapper_il.Emit(OpCodes.Stloc_2); - unwrapper_il.Emit(OpCodes.Ldloc_2); - unwrapper_il.Emit(OpCodes.Brfalse_S, label); - unwrapper_il.Emit(OpCodes.Ldarg_1); - unwrapper_il.Emit(OpCodes.Ldloc_2); - //unwrapper_il.Emit(OpCodes.Ldfld, typeof(ContextWrap).GetField("Context")); - unwrapper_il.Emit(OpCodes.Call, typeof(Wrapper<>).MakeGenericType(new Type[] { elem_type }).GetMethod("UnwrapUnder", BindingFlags.Public | BindingFlags.Static)); - SetElement(elems[i], unwrapper_il); - } - else - { - unwrapper_il.Emit(OpCodes.Ldarg_1); - unwrapper_il.Emit(OpCodes.Ldloc_1); - unwrapper_il.Emit(OpCodes.Ldloc_0); - unwrapper_il.Emit(OpCodes.Ldelem_Ref); + var elem_type = GetElementType(elems[i]); + if (elems[i].IsContext) + { + unwrapper_il.Emit(OpCodes.Ldloc_1); + unwrapper_il.Emit(OpCodes.Ldloc_0); + unwrapper_il.Emit(OpCodes.Ldelem_Ref); + unwrapper_il.Emit(OpCodes.Isinst, typeof(ContextWrap)); + unwrapper_il.Emit(OpCodes.Stloc_2); + unwrapper_il.Emit(OpCodes.Ldloc_2); + unwrapper_il.Emit(OpCodes.Brfalse_S, label); + + unwrapper_il.Emit(OpCodes.Ldarg_1); + unwrapper_il.Emit(OpCodes.Ldloc_2); + //unwrapper_il.Emit(OpCodes.Ldfld, typeof(ContextWrap).GetField("Context")); + unwrapper_il.Emit(OpCodes.Call, typeof(Wrapper<>).MakeGenericType(new Type[] { elem_type }).GetMethod("UnwrapUnder", BindingFlags.Public | BindingFlags.Static)); + SetElement(elems[i], unwrapper_il); + } + else + { + unwrapper_il.Emit(OpCodes.Ldarg_1); + unwrapper_il.Emit(OpCodes.Ldloc_1); + unwrapper_il.Emit(OpCodes.Ldloc_0); + unwrapper_il.Emit(OpCodes.Ldelem_Ref); - if (elem_type.IsValueType) unwrapper_il.Emit(OpCodes.Unbox_Any, elem_type); - else unwrapper_il.Emit(OpCodes.Castclass, elem_type); + if (elem_type.IsValueType) unwrapper_il.Emit(OpCodes.Unbox_Any, elem_type); + else unwrapper_il.Emit(OpCodes.Castclass, elem_type); - if (!elems[i].IsStrongUnwrap && HasRecast(elem_type)) - unwrapper_il.Emit(OpCodes.Call, typeof(Wrapper).GetMethod("UnwrapCast", BindingFlags.Public | BindingFlags.Static)); + if (!elems[i].IsStrongUnwrap && HasRecast(elem_type)) + unwrapper_il.Emit(OpCodes.Call, typeof(Wrapper).GetMethod("UnwrapCast", BindingFlags.Public | BindingFlags.Static)); - SetElement(elems[i], unwrapper_il); + SetElement(elems[i], unwrapper_il); + } + unwrapper_il.MarkLabel(label); } - unwrapper_il.MarkLabel(label); } unwrapper_il.Emit(OpCodes.Ret); From 44bda6de60b297cb893239047dcb6a8134ace188 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Mon, 10 Jun 2024 13:55:56 +0300 Subject: [PATCH 33/69] Wrapper.HasInitor check --- .../Expressions/Creators/CreatorInstance.cs | 2 +- SLThree/Wrapper.cs | 71 +++++++++++-------- 2 files changed, 42 insertions(+), 31 deletions(-) diff --git a/SLThree/Expressions/Creators/CreatorInstance.cs b/SLThree/Expressions/Creators/CreatorInstance.cs index cb6384d..e71d3f1 100644 --- a/SLThree/Expressions/Creators/CreatorInstance.cs +++ b/SLThree/Expressions/Creators/CreatorInstance.cs @@ -188,7 +188,7 @@ public override object GetValue(ExecutionContext context) if (CreatorContext != null) { var created = CreatorContext.GetValue(context).Cast().Context; - if (Arguments.Length == 0) + if (Arguments.Length == 0 && type.HasInitor()) instance = type.InstanceUnwrap(created); else { diff --git a/SLThree/Wrapper.cs b/SLThree/Wrapper.cs index 33eadd4..cddb976 100644 --- a/SLThree/Wrapper.cs +++ b/SLThree/Wrapper.cs @@ -864,35 +864,37 @@ void SetElement(WrappingMemberInfo elem, ILGenerator il) } var initor = default(Delegate); - if (explicit_constructor == null) throw new NotSupportedException($"Type {type.Name} must have parameterless constructor"); - if (explicit_constructor.GetParameters().Length > 0) + if (explicit_constructor != null) { - var initor_dm = new DynamicMethod("Initor", type, new Type[1] { ContextType }, true); - var initor_il = initor_dm.GetILGenerator(); - initor_il.Emit(OpCodes.Ldarg_0); - initor_il.Emit(OpCodes.Call, explicit_constructor_args); - initor_il.DeclareLocal(typeof(object[])); - initor_il.Emit(OpCodes.Stloc_0); - var i = 0; - foreach (var p in explicit_constructor.GetParameters()) + if (explicit_constructor.GetParameters().Length > 0) { - initor_il.Emit(OpCodes.Ldloc_0); - initor_il.Emit(OpCodes.Ldc_I4, i++); - initor_il.Emit(OpCodes.Ldelem_Ref); - if (p.ParameterType.IsValueType) initor_il.Emit(OpCodes.Unbox_Any, p.ParameterType); - else initor_il.Emit(OpCodes.Castclass, p.ParameterType); + var initor_dm = new DynamicMethod("Initor", type, new Type[1] { ContextType }, true); + var initor_il = initor_dm.GetILGenerator(); + initor_il.Emit(OpCodes.Ldarg_0); + initor_il.Emit(OpCodes.Call, explicit_constructor_args); + initor_il.DeclareLocal(typeof(object[])); + initor_il.Emit(OpCodes.Stloc_0); + var i = 0; + foreach (var p in explicit_constructor.GetParameters()) + { + initor_il.Emit(OpCodes.Ldloc_0); + initor_il.Emit(OpCodes.Ldc_I4, i++); + initor_il.Emit(OpCodes.Ldelem_Ref); + if (p.ParameterType.IsValueType) initor_il.Emit(OpCodes.Unbox_Any, p.ParameterType); + else initor_il.Emit(OpCodes.Castclass, p.ParameterType); + } + initor_il.Emit(OpCodes.Newobj, explicit_constructor); + initor_il.Emit(OpCodes.Ret); + initor = initor_dm.CreateDelegate(typeof(Func<,>).MakeGenericType(new Type[] { ContextType, type })); + } + else + { + var initor_dm = new DynamicMethod("Initor", type, new Type[1] { ContextType }, true); + var initor_il = initor_dm.GetILGenerator(); + initor_il.Emit(OpCodes.Newobj, explicit_constructor); + initor_il.Emit(OpCodes.Ret); + initor = initor_dm.CreateDelegate(typeof(Func<,>).MakeGenericType(new Type[] { ContextType, type })); } - initor_il.Emit(OpCodes.Newobj, explicit_constructor); - initor_il.Emit(OpCodes.Ret); - initor = initor_dm.CreateDelegate(typeof(Func<,>).MakeGenericType(new Type[] { ContextType, type })); - } - else - { - var initor_dm = new DynamicMethod("Initor", type, new Type[1] { ContextType }, true); - var initor_il = initor_dm.GetILGenerator(); - initor_il.Emit(OpCodes.Newobj, explicit_constructor); - initor_il.Emit(OpCodes.Ret); - initor = initor_dm.CreateDelegate(typeof(Func<,>).MakeGenericType(new Type[] { ContextType, type })); } return (quickwrapper, safewrapper, unwrapper, wrapname, unwrapname, initor, elems.ToDictionary(x => x.MemberInfo.Name, x => x.id)); @@ -925,6 +927,7 @@ void SetElement(WrappingMemberInfo elem, ILGenerator il) public static void InstanceWrapIn(this Type T, object obj, ExecutionContext context) => NonGeneric[T].WrapIn(obj, context); public static void UnwrapIn(this ExecutionContext context, Type T, object obj) => NonGeneric[T].UnwrapIn(context, obj); public static void InstanceUnwrapIn(this Type T, ExecutionContext context, object obj) => NonGeneric[T].UnwrapIn(context, obj); + public static bool HasInitor(this Type T) => NonGeneric[T].HasInitior; public sealed class NonGenericStaticWrapper { public readonly MethodInfo mWrap; @@ -963,6 +966,7 @@ public sealed class NonGenericWrapper public readonly MethodInfo mUnwrap; public readonly MethodInfo mWrapIn; public readonly MethodInfo mUnwrapIn; + public readonly bool HasInitior; internal NonGenericWrapper(Type T) { @@ -971,6 +975,7 @@ internal NonGenericWrapper(Type T) mUnwrap = type.GetMethod("Unwrap"); mWrapIn = type.GetMethod("WrapIn"); mUnwrapIn = type.GetMethod("UnwrapIn"); + HasInitior = (bool)type.GetField("HasInitor").GetValue(null); nongeneric_wrappers[T] = this; } @@ -995,6 +1000,7 @@ public NonGenericWrapper this[Type type] public static class Wrapper { public static readonly Func Initor; + public static readonly bool HasInitor; //Быстрое оборачивание заполняет переменные по отступу public static readonly Action QuickWrapper; @@ -1018,6 +1024,7 @@ static Wrapper() WrapName = (Action)d.Item4; UnwrapName = (Action)d.Item5; Initor = (Func)d.Item6; + HasInitor = Initor != null; ContextNames = d.Item7; Names = ContextNames.Keys.ToArray(); ContextSize = ContextNames.Count; @@ -1043,10 +1050,14 @@ public static ContextWrap WrapUnder(T obj, ExecutionContext context) } public static T Unwrap(ExecutionContext context) { - var ret = Initor(context); - UnwrapName(context, ret); - Unwrapper(context.LocalVariables, ret); - return ret; + if (HasInitor) + { + var ret = Initor(context); + UnwrapName(context, ret); + Unwrapper(context.LocalVariables, ret); + return ret; + } + throw new NotSupportedException($"{typeof(T)} should have constructor"); } public static T UnwrapUnder(ContextWrap context) => Unwrap(context.Context); public static void WrapIn(T obj, ExecutionContext context) From fc9e087465417887067c6398ca2017bfedab4a0c Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Mon, 10 Jun 2024 14:19:59 +0300 Subject: [PATCH 34/69] mda --- SLThree/Expressions/InvokeExpression.cs | 2 +- SLThree/Expressions/InvokeGenericExpression.cs | 2 +- SLThree/SLThree.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SLThree/Expressions/InvokeExpression.cs b/SLThree/Expressions/InvokeExpression.cs index 9ab8b2c..68eb09e 100644 --- a/SLThree/Expressions/InvokeExpression.cs +++ b/SLThree/Expressions/InvokeExpression.cs @@ -61,7 +61,7 @@ public object InvokeForObj(ExecutionContext context, object[] args, object o) else { var type = o.GetType(); - type.GetMethods() + return type.GetMethods() .FirstOrDefault(x => x.Name == Left.ExpressionToString().Replace(" ", "") && x.GetParameters().Length == Arguments.Length) ?.Invoke(o, args); } diff --git a/SLThree/Expressions/InvokeGenericExpression.cs b/SLThree/Expressions/InvokeGenericExpression.cs index 91d7234..0459e9b 100644 --- a/SLThree/Expressions/InvokeGenericExpression.cs +++ b/SLThree/Expressions/InvokeGenericExpression.cs @@ -54,7 +54,7 @@ public object InvokeForObj(ExecutionContext context, Type[] generic_args, object else { var type = o.GetType(); - type.GetMethods() + return type.GetMethods() .FirstOrDefault(x => x.Name == Left.ExpressionToString().Replace(" ", "") && x.GetParameters().Length == Arguments.Length) ?.MakeGenericMethod(generic_args) .Invoke(o, args); diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 176f3ba..3291393 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.213 + 0.8.0-alpha.217 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md From 33a163e5f1ef0ba20199ed2d93d0735b332ab890 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Mon, 10 Jun 2024 14:33:31 +0300 Subject: [PATCH 35/69] code cleanup --- .../Expressions/Creators/CreatorContextOld.cs | 61 ------------------- SLThree/Expressions/LambdaExpression.cs | 51 ---------------- .../Expressions/LambdaGenericExpression.cs | 54 ---------------- SLThree/Expressions/NewExpression.cs | 33 ---------- SLThree/JIT/NETGenerator.cs | 2 +- SLThree/JIT/NameCollector.cs | 2 +- SLThree/Methods/GenericMethod.cs | 8 +-- SLThree/SLThree.csproj | 2 +- SLThree/Statements/ConditionStatement.cs | 56 ----------------- SLThree/Statements/ContextStatement.cs | 29 --------- .../CreatorContextBody.cs | 0 .../Visitors/Definition/AbstractVisitor.cs | 53 ++++++---------- .../Visitors/Definition/IExpressionVisitor.cs | 8 +-- .../Visitors/Definition/IStatementVisitor.cs | 2 - SLThree/syntax.peg | 44 ------------- 15 files changed, 29 insertions(+), 376 deletions(-) delete mode 100644 SLThree/Expressions/Creators/CreatorContextOld.cs delete mode 100644 SLThree/Expressions/LambdaExpression.cs delete mode 100644 SLThree/Expressions/LambdaGenericExpression.cs delete mode 100644 SLThree/Expressions/NewExpression.cs delete mode 100644 SLThree/Statements/ConditionStatement.cs delete mode 100644 SLThree/Statements/ContextStatement.cs rename SLThree/{Expressions/Creators => Statements}/CreatorContextBody.cs (100%) diff --git a/SLThree/Expressions/Creators/CreatorContextOld.cs b/SLThree/Expressions/Creators/CreatorContextOld.cs deleted file mode 100644 index 4d8bc31..0000000 --- a/SLThree/Expressions/Creators/CreatorContextOld.cs +++ /dev/null @@ -1,61 +0,0 @@ -using SLThree.Extensions; -using SLThree.Extensions.Cloning; -using System; -using System.Linq; - -namespace SLThree -{ - public class CreatorContextOld : BaseExpression - { - public NameExpression Name; - public TypenameExpression Typecast; - public BaseStatement[] Body; - - public bool HasCast => Typecast != null; - public bool HasName => Name != null; - public bool HasBody => Body.Length > 0; - - public CreatorContextOld(SourceContext context) : this(null, null, new BaseStatement[0], context) { } - - public CreatorContextOld(NameExpression name, SourceContext context) : this(name, null, new BaseStatement[0], context) { } - - public CreatorContextOld(NameExpression name, TypenameExpression typecast, SourceContext context) : this(name, typecast, new BaseStatement[0], context) { } - - public CreatorContextOld(BaseStatement[] body, SourceContext context) : this(null, null, body, context) { } - - public CreatorContextOld(TypenameExpression typecast, SourceContext context) : this(null, typecast, new BaseStatement[0], context) { } - - public CreatorContextOld(NameExpression name, TypenameExpression typecast, BaseStatement[] body, SourceContext context) : base(context) - { - Name = name; - Typecast = typecast; - Body = body; - } - - public override string ExpressionToString() => $"new context {(HasName ? Name.Name : "")} {(HasCast ? $": {Typecast}" : "")} {{\n{Body.JoinIntoString("\n")}\n}}"; - - private string last_context_name; - public string LastContextName => last_context_name; - - public override object GetValue(ExecutionContext context) - { - var ret = new ExecutionContext(context); - if (HasName) ret.Name = Name.Name; - last_context_name = ret.Name; - if (HasBody) - { - for (var i = 0; i < Body.Length; i++) - { - if (Body[i] is ExpressionStatement es && es.Expression is BinaryAssign assign) - assign.AssignValue(ret, assign.Left, assign.Right.GetValue(context)); - else if (Body[i] is ContextStatement cs) - cs.GetValue(ret); - } - } - if (HasCast) return new ContextWrap(ret).CastToType(Typecast.GetValue(context).Cast()); - return new ContextWrap(ret); - } - - public override object Clone() => new CreatorContextOld(Name.CloneCast(), Typecast.CloneCast(), Body?.CloneArray(), SourceContext.CloneCast()); - } -} diff --git a/SLThree/Expressions/LambdaExpression.cs b/SLThree/Expressions/LambdaExpression.cs deleted file mode 100644 index c397b23..0000000 --- a/SLThree/Expressions/LambdaExpression.cs +++ /dev/null @@ -1,51 +0,0 @@ -using SLThree.Extensions.Cloning; -using System.Collections.Generic; -using System.Linq; - -namespace SLThree -{ - public class LambdaExpression : BaseExpression - { - public InvokeExpression Left; - public StatementList Right; - public IList Modificators; - public TypenameExpression ReturnTypeHint; - - public LambdaExpression(InvokeExpression invokeExpression, StatementList statements, TypenameExpression typehint, IList modificators, SourceContext context) : base(context) - { - Left = invokeExpression; - Right = statements; - ReturnTypeHint = typehint; - Modificators = modificators; - var many = Modificators.GroupBy(x => x).FirstOrDefault(x => x.Count() > 1); - if (many != null) throw new SyntaxError($"Repeated modifier \"{many.First()}\"", context); - - if (Method == null) - { - Method = new Method( - "$method", - Left.Arguments.Select(x => (x as NameExpression).Name).ToArray(), - Right, - Left.Arguments.Select(x => (x as NameExpression).TypeHint).ToArray(), - ReturnTypeHint, - null, - !Modificators.Contains("explicit"), - Modificators.Contains("recursive")); - } - } - - public override string ExpressionToString() => $"{Left} => {Right}"; - - public Method Method; - public override object GetValue(ExecutionContext context) - { - Method.@this = context.wrap; - return Method; - } - - public override object Clone() - { - return new LambdaExpression(Left.CloneCast(), Right.CloneCast(), ReturnTypeHint.CloneCast(), Modificators.ToArray().CloneArray(), SourceContext.CloneCast()); - } - } -} diff --git a/SLThree/Expressions/LambdaGenericExpression.cs b/SLThree/Expressions/LambdaGenericExpression.cs deleted file mode 100644 index 55400d8..0000000 --- a/SLThree/Expressions/LambdaGenericExpression.cs +++ /dev/null @@ -1,54 +0,0 @@ -using SLThree.Extensions.Cloning; -using System.Collections.Generic; -using System.Linq; - -namespace SLThree -{ - public class LambdaGenericExpression : BaseExpression - { - public InvokeExpression Left; - public StatementList Right; - public NameExpression[] Generics; - public IList Modificators; - public TypenameExpression ReturnTypeHint; - - public LambdaGenericExpression(InvokeExpression invokeExpression, StatementList statements, TypenameExpression typehint, IList modificators, NameExpression[] generics, SourceContext context) : base(context) - { - Left = invokeExpression; - Right = statements; - Generics = generics; - ReturnTypeHint = typehint; - Modificators = modificators; - var many = Modificators.GroupBy(x => x).FirstOrDefault(x => x.Count() > 1); - if (many != null) throw new SyntaxError($"Repeated modifier \"{many.First()}\"", context); - - if (Method == null) - { - Method = new GenericMethod( - "$method", - Left.Arguments.Select(x => (x as NameExpression).Name).ToArray(), - Right, - Left.Arguments.Select(x => (x as NameExpression).TypeHint).ToArray(), - ReturnTypeHint, - null, - !Modificators.Contains("explicit"), - Modificators.Contains("recursive"), - Generics); - } - } - - public override string ExpressionToString() => $"{Left} => {Right}"; - - public Method Method; - public override object GetValue(ExecutionContext context) - { - Method.@this = context.wrap; - return Method; - } - - public override object Clone() - { - return new LambdaGenericExpression(Left.CloneCast(), Right.CloneCast(), ReturnTypeHint.CloneCast(), Modificators.ToArray().CloneArray(), Generics.CloneArray(), SourceContext.CloneCast()); - } - } -} diff --git a/SLThree/Expressions/NewExpression.cs b/SLThree/Expressions/NewExpression.cs deleted file mode 100644 index af70ce4..0000000 --- a/SLThree/Expressions/NewExpression.cs +++ /dev/null @@ -1,33 +0,0 @@ -using SLThree.Extensions; -using SLThree.Extensions.Cloning; -using System; -using System.Linq; - -namespace SLThree -{ - public class NewExpression : BaseExpression - { - public TypenameExpression Typename; - public BaseExpression[] Arguments; - - public NewExpression(TypenameExpression typename, BaseExpression[] arguments, SourceContext context) : base(context) - { - Typename = typename; - Arguments = arguments; - } - - public NewExpression(TypenameExpression typename, SourceContext context) : this(typename, new BaseExpression[0], context) { } - - public override string ExpressionToString() => $"new {Typename}({Arguments.JoinIntoString(", ")})"; - - public override object GetValue(ExecutionContext context) - { - return Activator.CreateInstance(Typename.GetValue(context).Cast(), Arguments.ConvertAll(x => x.GetValue(context))); - } - - public override object Clone() - { - return new NewExpression(Typename.CloneCast(), Arguments.CloneArray(), SourceContext.CloneCast()); - } - } -} diff --git a/SLThree/JIT/NETGenerator.cs b/SLThree/JIT/NETGenerator.cs index 050cc0e..2bd8bdf 100644 --- a/SLThree/JIT/NETGenerator.cs +++ b/SLThree/JIT/NETGenerator.cs @@ -363,7 +363,7 @@ public void MakeBRCondition(BaseExpression expression, Label label) } } - public override void VisitStatement(ConditionStatement statement) + public override void VisitExpression(ConditionExpression statement) { var ifbody = statement.IfBody; var elsebody = statement.ElseBody; diff --git a/SLThree/JIT/NameCollector.cs b/SLThree/JIT/NameCollector.cs index 0784629..2c7764f 100644 --- a/SLThree/JIT/NameCollector.cs +++ b/SLThree/JIT/NameCollector.cs @@ -40,7 +40,7 @@ public Type GetAutotype(BaseExpression expression, bool throws = true) return bt.GetGenericArguments()[0]; } if (expression is InterpolatedString) return typeof(string); - if (expression is NewExpression newExpression) return (Type)newExpression.Typename.GetValue(temporary_method_context); + //if (expression is NewExpression newExpression) return (Type)newExpression.Typename.GetValue(temporary_method_context); if (expression is NameExpression name) { var vname = variables.LastOrDefault(x => x.Name == name.Name); diff --git a/SLThree/Methods/GenericMethod.cs b/SLThree/Methods/GenericMethod.cs index d89da5d..6117030 100644 --- a/SLThree/Methods/GenericMethod.cs +++ b/SLThree/Methods/GenericMethod.cs @@ -113,14 +113,14 @@ public CastGenericInfo(CastExpression concrete, int position) : base(concrete, p public override ref TypenameExpression GetPlacer() => ref Concrete.Type; } - public class New : GenericInfo + /*public class New : GenericInfo { public New(NewExpression concrete, int position) : base(concrete, position) { } public override ref TypenameExpression GetPlacer() => ref Concrete.Typename; - } + }*/ public class ArrayCreator : GenericInfo { public ArrayCreator(CreatorArray concrete, int position) : base(concrete, position) @@ -145,14 +145,14 @@ public RangeCreator(CreatorRange concrete, int position) : base(concrete, positi public override ref TypenameExpression GetPlacer() => ref Concrete.RangeType; } - public class ContextCreator : GenericInfo +/* public class ContextCreator : GenericInfo { public ContextCreator(CreatorContextOld concrete, int position) : base(concrete, position) { } public override ref TypenameExpression GetPlacer() => ref Concrete.Typecast; - } + }*/ public class Chooser : GenericInfo { public Chooser(UnaryGetChooser concrete, int position) : base(concrete, position) diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 3291393..2bb2697 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.217 + 0.8.0-alpha.220 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md diff --git a/SLThree/Statements/ConditionStatement.cs b/SLThree/Statements/ConditionStatement.cs deleted file mode 100644 index d920f0b..0000000 --- a/SLThree/Statements/ConditionStatement.cs +++ /dev/null @@ -1,56 +0,0 @@ -using SLThree.Extensions.Cloning; -using System.Linq; - -namespace SLThree -{ - public class ConditionStatement : BaseStatement - { - public BaseExpression Condition { get; set; } - public BaseStatement[] Body { get; set; } - - public ConditionStatement() { } - public ConditionStatement(BaseExpression condition, BaseStatement[] body, int falsestart, SourceContext context) : base(context) - { - Condition = condition; - Body = body; - count = Body.Length; - this.falsestart = falsestart; - } - - public ConditionStatement(BaseExpression condition, StatementList trueBlock, StatementList falseBlock, SourceContext context) : base(context) - { - Condition = condition; - count = trueBlock.Statements.Length + falseBlock.Statements.Length; - Body = new BaseStatement[count]; - trueBlock.Statements.CopyTo(Body, 0); - falsestart = trueBlock.Statements.Length; - falseBlock.Statements.CopyTo(Body, falsestart); - } - private int count; - private int falsestart; - - public BaseStatement[] IfBody => Body.Take(falsestart).ToArray(); - public BaseStatement[] ElseBody => Body.Skip(falsestart).ToArray(); - - public override string ToString() => $"if ({Condition}) {{{Body}}}"; - - public override object GetValue(ExecutionContext context) - { - var ret = default(object); - var cond = (bool)Condition.GetValue(context); - var start = cond ? 0 : falsestart; - var end = cond ? falsestart : count; - for (var i = start; i < end; i++) - { - ret = Body[i].GetValue(context); - if (context.Returned || context.Broken || context.Continued) break; - } - return ret; - } - - public override object Clone() - { - return new ConditionStatement(Condition.CloneCast(), Body.CloneArray(), falsestart, SourceContext.CloneCast()); - } - } -} diff --git a/SLThree/Statements/ContextStatement.cs b/SLThree/Statements/ContextStatement.cs deleted file mode 100644 index 5fa109c..0000000 --- a/SLThree/Statements/ContextStatement.cs +++ /dev/null @@ -1,29 +0,0 @@ -using SLThree.Extensions; -using SLThree.Extensions.Cloning; - -namespace SLThree -{ - public class ContextStatement : BaseStatement - { - public CreatorContextOld Creator; - - public ContextStatement(CreatorContextOld creator, SourceContext context) : base(context) - { - Creator = creator; - } - - public override string ToString() => $"context {(Creator.HasName ? Creator.Name.Name : "")} {(Creator.HasCast ? $": {Creator.Typecast}" : "")} {{\n{Creator.Body.JoinIntoString("\n")}\n}}"; - - public override object GetValue(ExecutionContext context) - { - var created_context = Creator.GetValue(context); - context.LocalVariables.SetValue(Creator.LastContextName, created_context); - return created_context; - } - - public override object Clone() - { - return new ContextStatement(Creator.CloneCast(), SourceContext.CloneCast()); - } - } -} diff --git a/SLThree/Expressions/Creators/CreatorContextBody.cs b/SLThree/Statements/CreatorContextBody.cs similarity index 100% rename from SLThree/Expressions/Creators/CreatorContextBody.cs rename to SLThree/Statements/CreatorContextBody.cs diff --git a/SLThree/Visitors/Definition/AbstractVisitor.cs b/SLThree/Visitors/Definition/AbstractVisitor.cs index dcb18fd..d182e84 100644 --- a/SLThree/Visitors/Definition/AbstractVisitor.cs +++ b/SLThree/Visitors/Definition/AbstractVisitor.cs @@ -52,10 +52,11 @@ public virtual void VisitExpression(BaseExpression expression) case UnaryOperator expr: VisitExpression(expr); return; case Special expr: VisitExpression(expr); return; case Literal expr: VisitExpression(expr); return; - case NewExpression expr: VisitExpression(expr); return; + case CreatorInstance expr: VisitExpression(expr); return; case NameExpression expr: VisitExpression(expr); return; - case LambdaExpression expr: VisitExpression(expr); return; - case LambdaGenericExpression expr: VisitExpression(expr); return; + case ConditionExpression expr: VisitExpression(expr); return; + case FunctionDefinition expr: VisitExpression(expr); return; + case StaticExpression expr: VisitExpression(expr); return; case InvokeExpression expr: VisitExpression(expr); return; case InvokeGenericExpression expr: VisitExpression(expr); return; case InterpolatedString expr: VisitExpression(expr); return; @@ -68,7 +69,7 @@ public virtual void VisitExpression(BaseExpression expression) case TypenameExpression expr: VisitExpression(expr); return; case CreatorNewArray expr: VisitExpression(expr); return; case CreatorArray expr: VisitExpression(expr); return; - case CreatorContextOld expr: VisitExpression(expr); return; + case CreatorContext expr: VisitExpression(expr); return; case CreatorRange expr: VisitExpression(expr); return; case MatchExpression expr: VisitExpression(expr); return; } @@ -170,11 +171,7 @@ public virtual void VisitExpression(InvokeGenericExpression expression) VisitExpression(x); } } - public virtual void VisitExpression(LambdaExpression expression) - { - Visit(expression.Method); - } - public virtual void VisitExpression(LambdaGenericExpression expression) + public virtual void VisitExpression(FunctionDefinition expression) { Visit(expression.Method); } @@ -189,13 +186,9 @@ public virtual void VisitExpression(NameExpression expression) } } - public virtual void VisitExpression(NewExpression expression) + public virtual void VisitExpression(CreatorInstance expression) { - Executables.Add(expression); - VisitExpression(expression.Typename); - Executables.Remove(expression); - for (var i = 0; i < expression.Arguments.Length; i++) - VisitExpression(expression.Arguments[i]); + throw new NotImplementedException(); } public virtual void VisitExpression(Special expression) @@ -291,13 +284,11 @@ public virtual void VisitStatement(BaseStatement statement) case ForeachLoopStatement st: VisitStatement(st); return; case WhileLoopStatement st: VisitStatement(st); return; case ExpressionStatement st: VisitStatement(st); return; - case ConditionStatement st: VisitStatement(st); return; case ReturnStatement st: VisitStatement(st); return; case UsingStatement st: VisitStatement(st); return; case StatementList st: VisitStatement(st); return; case BreakStatement st: VisitStatement(st); return; case ContinueStatement st: VisitStatement(st); return; - case ContextStatement st: VisitStatement(st); return; case TryStatement st: VisitStatement(st); return; case ThrowStatement st: VisitStatement(st); return; } @@ -324,10 +315,10 @@ public virtual void VisitStatement(ExpressionStatement statement) VisitExpression(statement.Expression); } - public virtual void VisitStatement(ConditionStatement statement) + public virtual void VisitExpression(ConditionExpression expression) { - VisitExpression(statement.Condition); - foreach (var x in statement.Body) + VisitExpression(expression.Condition); + foreach (var x in expression.Body) VisitStatement(x); } @@ -336,11 +327,6 @@ public virtual void VisitStatement(ReturnStatement statement) if (!statement.VoidReturn) VisitExpression(statement.Expression); } - public virtual void VisitStatement(ContextStatement statement) - { - VisitExpression(statement.Creator); - } - public virtual void VisitStatement(UsingStatement statement) { VisitExpression(statement.Using); @@ -368,17 +354,9 @@ public virtual void VisitExpression(CreatorNewArray expression) VisitExpression(expression.Size); } - public virtual void VisitExpression(CreatorContextOld expression) + public virtual void VisitExpression(CreatorContext expression) { - if (expression.Typecast != null) - { - Executables.Add(expression); - VisitExpression(expression.Typecast); - Executables.Remove(expression); - } - if (expression.Body != null) - foreach (var x in expression.Body) - VisitStatement(x); + throw new NotImplementedException(); } public virtual void VisitExpression(CreatorRange expression) @@ -409,5 +387,10 @@ public virtual void VisitStatement(ThrowStatement statement) { VisitExpression(statement.ThrowExpression); } + + public void VisitExpression(StaticExpression expression) + { + VisitExpression(expression.Right); + } } } diff --git a/SLThree/Visitors/Definition/IExpressionVisitor.cs b/SLThree/Visitors/Definition/IExpressionVisitor.cs index 767b894..30d9da5 100644 --- a/SLThree/Visitors/Definition/IExpressionVisitor.cs +++ b/SLThree/Visitors/Definition/IExpressionVisitor.cs @@ -6,26 +6,26 @@ public interface IExpressionVisitor void VisitExpression(CreatorArray expression); void VisitExpression(CreatorNewArray expression); - void VisitExpression(CreatorContextOld expression); void VisitExpression(CreatorDictionary expression); void VisitExpression(CreatorList expression); void VisitExpression(CreatorRange expression); void VisitExpression(CreatorTuple expression); void VisitExpression(CreatorUsing expression); + void VisitExpression(CreatorInstance expression); void VisitExpression(CastExpression expression); + void VisitExpression(ConditionExpression expression); void VisitExpression(IndexExpression expression); void VisitExpression(InterpolatedString expression); void VisitExpression(InvokeExpression expression); void VisitExpression(InvokeGenericExpression expression); - void VisitExpression(LambdaExpression expression); - void VisitExpression(LambdaGenericExpression expression); + void VisitExpression(FunctionDefinition expression); void VisitExpression(MemberAccess expression); void VisitExpression(NameExpression expression); - void VisitExpression(NewExpression expression); void VisitExpression(ReflectionExpression expression); void VisitExpression(TypenameExpression expression); void VisitExpression(MatchExpression expression); + void VisitExpression(StaticExpression expression); void VisitExpression(Special expression); void VisitExpression(Literal expression); diff --git a/SLThree/Visitors/Definition/IStatementVisitor.cs b/SLThree/Visitors/Definition/IStatementVisitor.cs index b9307d0..046bbf3 100644 --- a/SLThree/Visitors/Definition/IStatementVisitor.cs +++ b/SLThree/Visitors/Definition/IStatementVisitor.cs @@ -5,8 +5,6 @@ public interface IStatementVisitor void VisitStatement(BaseStatement statement); void VisitStatement(BreakStatement statement); - void VisitStatement(ContextStatement statement); - void VisitStatement(ConditionStatement statement); void VisitStatement(ContinueStatement statement); void VisitStatement(ExpressionStatement statement); void VisitStatement(ForeachLoopStatement statement); diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index b97891f..6c322ab 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -104,7 +104,6 @@ expression binary_9 -memoize = left:keyword _ ("=" / "+=" / "-=" / "*=" / "/=" / "%=" / "&=" / "|=" / "^=") _ right:binary_9 { Panic(new SyntaxError("Keywords is not a valid name", state)) } - // method / "static" _required_ left:expression { new StaticExpression(left, state) } / left:binary_9 _ "|>" _ right:binary_7 { InjectFirst(left, right) } / condition_expression @@ -122,10 +121,6 @@ binary_9 -memoize / left:binary_7 _ "|=" _ right:binary_9 { new BinaryAssign(left, new BinaryBitOr(left, right, state), state) } / left:binary_7 _ "^=" _ right:binary_9 { new BinaryAssign(left, new BinaryBitXor(left, right, state), state) } / ternary_0 - -method - = generic_lambda - / lambda ternary_0 -memoize = cond:ternary_0 _ "?" _ t:expression _ ":" _ f:expression { new TernaryOperator(cond, t, f, state) } @@ -545,45 +540,6 @@ method_mods_name > / mods:method_modificator<1,,_required_> _ { new Tuple(mods.ToArray(), null) } / name:withoutinvokation_primary _ { new Tuple(new string[0], name) } -generic_lambda - = left:( - , NameExpression[], TypenameExpression, NameExpression[]>> - mods:(> mods_i:method_modificator<1,,_required_> _required_ { mods_i })? - _ "<" _ generic_args:name<1,,"," _> _ ">" _ - args:( - > "(" _ args_i:arg_name<0,,"," _> _ ")" { args_i } - / a:arg_name { new NameExpression[1] { a } } - ) - ret:( _ ":" _ t:typename {t})? { - new ValueTuple, NameExpression[], TypenameExpression, NameExpression[]>(GetOptional(mods) ?? new string[0], args.ToArray(), GetOptional(ret), generic_args.ToArray()) - } - ) _ "=>" _ right:( - - expr:expression { GetListStatement(new ReturnStatement(expr, state)) } - / block_statement - ) { - new LambdaGenericExpression(new InvokeExpression(null, left.Item2, state), right, left.Item3, left.Item1, left.Item4, state) - } - -lambda - = left:( - , NameExpression[], TypenameExpression>> - mods:(> mods_i:method_modificator<1,,_required_> _required_ { mods_i })? - args:( - > "(" _ args_i:arg_name<0,,"," _> _ ")" { args_i } - / a:arg_name { new NameExpression[1] { a } } - ) - ret:( _ ":" _ t:typename {t})? { - new ValueTuple, NameExpression[], TypenameExpression>(GetOptional(mods) ?? new string[0], args.ToArray(), GetOptional(ret)) - } - ) _ "=>" _ right:( - - expr:expression { GetListStatement(new ReturnStatement(expr, state)) } - / block_statement - ) { - new LambdaExpression(new InvokeExpression(null, left.Item2, state), right, left.Item3, left.Item1, state) - } - method_modificator = "recursive" / "explicit" From b05ecbb71e6473054a6656675a4c93ef0b807f53 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Mon, 10 Jun 2024 17:51:04 +0300 Subject: [PATCH 36/69] context creators improves --- SLThree/ContextWrap.cs | 38 +++++++++--- SLThree/ExecutionContext.cs | 2 + .../Expressions/Creators/CreatorContext.cs | 15 ++--- SLThree/SLThree.csproj | 2 +- SLThree/Statements/CreatorContextBody.cs | 59 +++++++++++++++++-- 5 files changed, 94 insertions(+), 22 deletions(-) diff --git a/SLThree/ContextWrap.cs b/SLThree/ContextWrap.cs index 7e07687..5449852 100644 --- a/SLThree/ContextWrap.cs +++ b/SLThree/ContextWrap.cs @@ -26,15 +26,16 @@ public string ToDetailedString(int index, List outed_contexts) sb.AppendLine($"context {Context.Name} {{"); foreach (var x in Context.LocalVariables.GetAsDictionary()) { - - sb.Append($"{(index == 0 ? "" : new string(' ', index * 4))}{x.Key} = "); + sb.Append($"{(index == 0 ? "" : new string(' ', index * 4))}"); if (x.Value is ContextWrap wrap) { + if (wrap.Context.Name != x.Key) sb.Append($"{x.Key} = "); if (outed_contexts.Contains(wrap)) sb.AppendLine($"context {wrap.Context.Name}; //already printed"); else sb.AppendLine(wrap.ToDetailedString(index + 1, outed_contexts) + ";"); } else if (x.Value is ClassAccess ca) { + sb.Append($"{x.Key} = "); var first = false; foreach (var line in ca.ToString().Split(new string[1] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)) { @@ -43,7 +44,14 @@ public string ToDetailedString(int index, List outed_contexts) first = true; } } - else sb.AppendLine(Decoration(x.Value)?.ToString() ?? "null" + ";"); + else + { + if (!(x.Value is Method m && m.Name == x.Key)) + { + sb.Append($"{x.Key} = "); + } + sb.AppendLine(Decoration(x.Value)?.ToString() ?? "null" + ";"); + } } index -= 1; sb.Append($"{(index == 0 ? "" : new string(' ', index * 4))}}}"); @@ -60,11 +68,25 @@ public string ToShortString() sb.AppendLine($"context {Context.Name} {{"); foreach (var x in Context.LocalVariables.GetAsDictionary()) { - - sb.Append($"{(index == 0 ? "" : new string(' ', index * 4))}{x.Key} = "); - if (x.Value is ContextWrap wrap) sb.AppendLine($"context {wrap.Context.Name};"); - else if (x.Value is ClassAccess maca) sb.AppendLine($"access to {maca.Name.GetTypeString()};"); - else sb.AppendLine((Decoration(x.Value)?.ToString() ?? "null") + ";"); + sb.Append($"{(index == 0 ? "" : new string(' ', index * 4))}"); + if (x.Value is ContextWrap wrap) + { + if (wrap.Context.Name != x.Key) sb.Append($"{x.Key} = "); + sb.AppendLine($"context {wrap.Context.Name};"); + } + else if (x.Value is ClassAccess maca) + { + sb.Append($"{x.Key} = "); + sb.AppendLine($"access to {maca.Name.GetTypeString()};"); + } + else + { + if (!(x.Value is Method m && m.Name == x.Key)) + { + sb.Append($"{x.Key} = "); + } + sb.AppendLine((Decoration(x.Value)?.ToString() ?? "null") + ";"); + } } index -= 1; sb.Append($"{(index == 0 ? "" : new string(' ', index * 4))}}}"); diff --git a/SLThree/ExecutionContext.cs b/SLThree/ExecutionContext.cs index 43e37f6..286bedd 100644 --- a/SLThree/ExecutionContext.cs +++ b/SLThree/ExecutionContext.cs @@ -160,6 +160,8 @@ public void Implementation(ExecutionContext ret, object[] args, SourceContext so internal ExecutionContext copy(ExecutionContext context) { LocalVariables.FillOther(context.LocalVariables); + //if (context.@private != null && @private != null) + // @private.Context.LocalVariables.FillOther(context.@private.Context.LocalVariables); return this; } } diff --git a/SLThree/Expressions/Creators/CreatorContext.cs b/SLThree/Expressions/Creators/CreatorContext.cs index 18729bf..f3e8b89 100644 --- a/SLThree/Expressions/Creators/CreatorContext.cs +++ b/SLThree/Expressions/Creators/CreatorContext.cs @@ -64,24 +64,25 @@ public static string GetLastName(BaseExpression name) if (index == -1) return n; else return n.Substring(index + 1); } - public override object GetValue(ExecutionContext context) + + public object GetValue(ExecutionContext target, ExecutionContext context) { - ExecutionContext ret; - if (Ancestors.Length > 0) ret = Ancestors[0].GetValue(context).Cast().Context; - else ret = new ExecutionContext(context); - for (var i = 1; i < Ancestors.Length; i++) - ret.copy(Ancestors[i].GetValue(context).Cast().Context); + var ret = new ExecutionContext(target); + for (var i = 0; i < Ancestors.Length; i++) + ret.copy(Ancestors[i].GetValue(target).Cast().Context); CreatorBody?.GetValue(ret, context); var wrap = ret.wrap; if (HasName) { ret.Name = GetName(); if (IsFreeCreator) - BinaryAssign.AssignToValue(context, Name, wrap, ref counted_invoked, ref is_name_expr, ref variable_index); + BinaryAssign.AssignToValue(target, Name, wrap, ref counted_invoked, ref is_name_expr, ref variable_index); } return wrap; } + public override object GetValue(ExecutionContext context) => GetValue(context, context); + public override object Clone() => new CreatorContext(Name.CloneCast(), Ancestors.CloneArray(), CreatorBody.CloneCast(), IsFreeCreator, SourceContext.CloneCast()); } } diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 2bb2697..fd63877 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.220 + 0.8.0-alpha.232 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md diff --git a/SLThree/Statements/CreatorContextBody.cs b/SLThree/Statements/CreatorContextBody.cs index 6d1b481..36320e9 100644 --- a/SLThree/Statements/CreatorContextBody.cs +++ b/SLThree/Statements/CreatorContextBody.cs @@ -6,6 +6,10 @@ namespace SLThree { public class CreatorContextBody : StatementList, ICloneable { + private ExecutionContext counted_invoked; + private bool is_name_expr; + private int variable_index; + public CreatorContextBody() : base() { } public CreatorContextBody(IList statements, SourceContext context) : base(statements, context) { @@ -13,25 +17,68 @@ public CreatorContextBody(IList statements, SourceContext context CheckOnContextStatements(x); } - public ExecutionContext GetValue(ExecutionContext target, ExecutionContext call) + public ExecutionContext GetValue(ExecutionContext target, ExecutionContext context) { for (var i = 0; i < count; i++) { - if (Statements[i] is ExpressionStatement es && es.Expression is BinaryAssign assign) - assign.AssignValue(target, assign.Left, assign.Right.GetValue(call)); + if (Statements[i] is ExpressionStatement es) + { + if (es.Expression is BinaryAssign assign) + { + if (assign.Left is MemberAccess @private) + BinaryAssign.AssignToValue(target.@private.Context, @private.Right, assign.Right.GetValue(context), ref counted_invoked, ref is_name_expr, ref variable_index); + else + BinaryAssign.AssignToValue(target, assign.Left, assign.Right.GetValue(context), ref counted_invoked, ref is_name_expr, ref variable_index); + } + else if (es.Expression is CreatorContext creator) + { + if (creator.Name is MemberAccess @private) + BinaryAssign.AssignToValue(target.@private.Context, @private.Right, creator.GetValue(target, context), ref counted_invoked, ref is_name_expr, ref variable_index); + else + BinaryAssign.AssignToValue(target, creator.Name, creator.GetValue(target, context), ref counted_invoked, ref is_name_expr, ref variable_index); + } + else if (es.Expression is FunctionDefinition function) + { + if (function.FunctionName is MemberAccess @private) + BinaryAssign.AssignToValue(target.@private.Context, @private.Right, function.GetValue(target.@private.Context), ref counted_invoked, ref is_name_expr, ref variable_index); + else + BinaryAssign.AssignToValue(target, function.FunctionName, function.GetValue(target), ref counted_invoked, ref is_name_expr, ref variable_index); + } + } } return target; } + private static bool CheckName(BaseExpression expression) + { + if (expression is NameExpression) return true; + if (expression is MemberAccess memberAccess && memberAccess.Right is NameExpression && memberAccess.Left is PrivateLiteral) return true; + + throw new LogicalError($"Expected name or private.name, found \"{expression}\"", expression.SourceContext); + } + private static BaseStatement CheckOnContextStatements(BaseStatement statement) { if (statement is ExpressionStatement expressionStatement) { - if (expressionStatement.Expression is BinaryAssign) + if (expressionStatement.Expression is BinaryAssign assign) + { + if (CheckName(assign.Left)) return statement; + } + if (expressionStatement.Expression is CreatorContext creator) + { + if (creator.Name == null) throw new LogicalError($"Nested context definitions should be named", expressionStatement.Expression.SourceContext); + if (CheckName(creator.Name)) return statement; return statement; - throw new SyntaxError($"Expected assign expression, found {expressionStatement.Expression.GetType().Name}", expressionStatement.Expression.SourceContext); + } + if (expressionStatement.Expression is FunctionDefinition function) + { + if (function.FunctionName == null) throw new LogicalError($"Methods should be named", expressionStatement.Expression.SourceContext); + if (CheckName(function.FunctionName)) return statement; + } + throw new SyntaxError($"Expected assign/context/method, found \"{expressionStatement.Expression}\"", expressionStatement.Expression.SourceContext); } - throw new SyntaxError($"Expected assign expression, found {statement.GetType().Name}", statement.SourceContext); + throw new SyntaxError($"Expected assign/context/method, found \"{statement}\"", statement.SourceContext); } public override object GetValue(ExecutionContext context) From f18da192ac129dd88d87ab5648cc6a9634964b59 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Wed, 12 Jun 2024 15:24:35 +0300 Subject: [PATCH 37/69] slt.html cleanup --- SLThree.HTMLCreator/HTMLCreator.cs | 118 ++++++----------------------- 1 file changed, 23 insertions(+), 95 deletions(-) diff --git a/SLThree.HTMLCreator/HTMLCreator.cs b/SLThree.HTMLCreator/HTMLCreator.cs index 0bd4af8..1c0095b 100644 --- a/SLThree.HTMLCreator/HTMLCreator.cs +++ b/SLThree.HTMLCreator/HTMLCreator.cs @@ -114,42 +114,7 @@ public override void VisitExpression(TypenameExpression expression) CurrentString.Append(Replace(">")); } } - public void VisitExpression(CreatorContextOld expression, bool newline, bool hasnew) - { - if (hasnew) - CurrentString.Append(GetKeyword1("new context ")); - else - CurrentString.Append(GetKeyword1("context ")); - if (expression.HasName) - { - CurrentString.Append(expression.Name + " "); - } - if (expression.HasCast) - { - CurrentString.Append(": "); - VisitExpression(expression.Typecast); - CurrentString.Append(" "); - } - if (expression.HasBody) - { - CurrentString.Append("{ "); - CurrentTab += 1; - foreach (var x in expression.Body) - { - if (newline) Newline(); - else CurrentString.Append(" "); - VisitStatement(x); - } - CurrentTab -= 1; - if (newline) Newline(); - else CurrentString.Append(" "); - CurrentString.Append("}"); - } - } - public override void VisitExpression(CreatorContextOld expression) - { - VisitExpression(expression, ContextElementNewLine, true); - } + public override void VisitExpression(MemberAccess expression) { VisitExpression(expression.Left); @@ -167,7 +132,7 @@ public override void VisitExpression(InvokeExpression expression) if (memberAccess.Right is NameExpression nameExpression1) CurrentString.Append(GetCall(nameExpression1.Name)); } - else if (expression.Left is LambdaExpression lambda) + else if (expression.Left is FunctionDefinition lambda) { CurrentString.Append("("); VisitExpression(lambda); @@ -479,63 +444,28 @@ public override void VisitExpression(InterpolatedString expression) CurrentString = sb; CurrentString.Append(GetString("$\"" + string.Format(expression.Value, arr) + "\"")); } - public override void VisitExpression(LambdaExpression expression) + public override void VisitExpression(FunctionDefinition expression) { foreach (var x in expression.Modificators) { CurrentString.Append(GetKeyword1(x)); CurrentString.Append(" "); } - CurrentString.Append("("); - for (var i = 0; i < expression.Left.Arguments.Length; i++) - { - VisitExpression(expression.Left.Arguments[i]); - if (i != expression.Left.Arguments.Length - 1) CurrentString.Append(", "); - } - CurrentString.Append(")"); - if (expression.ReturnTypeHint != null) - { - CurrentString.Append(": "); - VisitExpression(expression.ReturnTypeHint); - } - CurrentString.Append(Replace(" => ")); - if (expression.Right.Statements.Length == 1 && expression.Right.Statements[0] is ReturnStatement ret && ret.Expression != null) - { - VisitExpression(ret.Expression); - } - else + if (expression.GenericArguments.Length > 0) { - CurrentString.Append(" {"); - CurrentTab += 1; - foreach (var x in expression.Right.Statements) + CurrentString.Append(Replace("<")); + for (var i = 0; i < expression.GenericArguments.Length; i++) { - Newline(); - VisitStatement(x); + CurrentString.Append(GetTypeSpan(expression.GenericArguments[i].Name)); + if (i != expression.GenericArguments.Length - 1) CurrentString.Append(", "); } - CurrentTab -= 1; - Newline(); - CurrentString.Append("}"); - } - } - public override void VisitExpression(LambdaGenericExpression expression) - { - foreach (var x in expression.Modificators) - { - CurrentString.Append(GetKeyword1(x)); - CurrentString.Append(" "); - } - CurrentString.Append(Replace("<")); - for (var i = 0; i < expression.Generics.Length; i++) - { - CurrentString.Append(GetTypeSpan(expression.Generics[i].Name)); - if (i != expression.Generics.Length - 1) CurrentString.Append(", "); + CurrentString.Append(Replace(">")); } - CurrentString.Append(Replace(">")); CurrentString.Append("("); - for (var i = 0; i < expression.Left.Arguments.Length; i++) + for (var i = 0; i < expression.Arguments.Length; i++) { - VisitExpression(expression.Left.Arguments[i]); - if (i != expression.Left.Arguments.Length - 1) CurrentString.Append(", "); + VisitExpression(expression.Arguments[i]); + if (i != expression.Arguments.Length - 1) CurrentString.Append(", "); } CurrentString.Append(")"); if (expression.ReturnTypeHint != null) @@ -544,7 +474,7 @@ public override void VisitExpression(LambdaGenericExpression expression) VisitExpression(expression.ReturnTypeHint); } CurrentString.Append(Replace(" => ")); - if (expression.Right.Statements.Length == 1 && expression.Right.Statements[0] is ReturnStatement ret) + if (expression.FunctionBody.Statements.Length == 1 && expression.FunctionBody.Statements[0] is ReturnStatement ret && ret.Expression != null) { VisitExpression(ret.Expression); } @@ -552,7 +482,7 @@ public override void VisitExpression(LambdaGenericExpression expression) { CurrentString.Append(" {"); CurrentTab += 1; - foreach (var x in expression.Right.Statements) + foreach (var x in expression.FunctionBody.Statements) { Newline(); VisitStatement(x); @@ -562,6 +492,7 @@ public override void VisitExpression(LambdaGenericExpression expression) CurrentString.Append("}"); } } + public void VisitExpression(CreatorUsing expression, bool hasnew) { if (hasnew) @@ -573,9 +504,10 @@ public override void VisitExpression(CreatorUsing expression) { VisitExpression(expression, true); } - public override void VisitExpression(NewExpression expression) + public override void VisitExpression(CreatorInstance expression) { - CurrentString.Append(GetKeyword1("new ")); + throw new NotImplementedException(); + /*CurrentString.Append(GetKeyword1("new ")); VisitExpression(expression.Typename); CurrentString.Append("("); for (var i = 0; i < expression.Arguments.Length; i++) @@ -583,7 +515,7 @@ public override void VisitExpression(NewExpression expression) VisitExpression(expression.Arguments[i]); if (i < expression.Arguments.Length - 1) CurrentString.Append(", "); } - CurrentString.Append(")"); + CurrentString.Append(")");*/ } public override void VisitExpression(ReflectionExpression expression) { @@ -613,10 +545,6 @@ public override void VisitExpression(ReflectionExpression expression) } } - public override void VisitStatement(ContextStatement statement) - { - VisitExpression(statement.Creator, ContextElementNewLine, false); - } public override void VisitStatement(BreakStatement statement) { CurrentString.Append(GetKeyword2("break") + ";"); @@ -736,13 +664,13 @@ public override void VisitStatement(ForeachLoopStatement statement) CurrentString.Append("}"); } } - public override void VisitStatement(ConditionStatement statement) + public override void VisitExpression(ConditionExpression expression) { CurrentString.Append(GetKeyword2("if") + " ("); - VisitExpression(statement.Condition); + VisitExpression(expression.Condition); CurrentString.Append(")"); - var ifbody = statement.IfBody; + var ifbody = expression.IfBody; if (ifbody.Length < 2) { CurrentTab += 1; @@ -765,7 +693,7 @@ public override void VisitStatement(ConditionStatement statement) } - var elsebody = statement.ElseBody; + var elsebody = expression.ElseBody; if (elsebody.Length == 0) return; Newline(); CurrentString.Append(GetKeyword2("else ")); From 7f70f2ff3b48da3937539e027babd7717694be99 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Wed, 12 Jun 2024 15:25:11 +0300 Subject: [PATCH 38/69] fix #125 (2) --- SLThree/Expressions/InvokeExpression.cs | 14 +++++++++++++- SLThree/Expressions/InvokeGenericExpression.cs | 13 ++++++++++++- SLThree/SLThree.csproj | 2 +- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/SLThree/Expressions/InvokeExpression.cs b/SLThree/Expressions/InvokeExpression.cs index 68eb09e..48bde43 100644 --- a/SLThree/Expressions/InvokeExpression.cs +++ b/SLThree/Expressions/InvokeExpression.cs @@ -3,6 +3,7 @@ using System; using System.Linq; using System.Reflection; +using System.Runtime.CompilerServices; namespace SLThree { @@ -69,11 +70,13 @@ public object InvokeForObj(ExecutionContext context, object[] args, object o) throw new RuntimeError($"{o.GetType().GetTypeString()} is not allow to invoke", SourceContext); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public object GetValue(ExecutionContext context, object[] args) { return InvokeForObj(context, args, Left.GetValue(context)); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override object GetValue(ExecutionContext context) { return GetValue(context, Arguments.ConvertAll(x => x.GetValue(context))); @@ -99,7 +102,16 @@ public object GetValue(ExecutionContext context, object obj) if (founded == null) throw new RuntimeError($"Method `{key}({Arguments.Select(x => "_").JoinIntoString(", ")})` not found", SourceContext); return founded.Invoke(null, Arguments.ConvertAll(x => x.GetValue(context))); } - else return InvokeForObj(context, Arguments.ConvertAll(x => x.GetValue(context)), obj); + else if (obj != null) + { + var method = obj.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance) + .FirstOrDefault(x => x.Name == key && x.GetParameters().Length == Arguments.Length); + if (method != null) + return method.Invoke(obj, Arguments.ConvertAll(x => x.GetValue(context))); + else return InvokeForObj(context, Arguments.ConvertAll(x => x.GetValue(context)), obj); + } + + return null; } public override object Clone() diff --git a/SLThree/Expressions/InvokeGenericExpression.cs b/SLThree/Expressions/InvokeGenericExpression.cs index 0459e9b..7db1202 100644 --- a/SLThree/Expressions/InvokeGenericExpression.cs +++ b/SLThree/Expressions/InvokeGenericExpression.cs @@ -3,6 +3,7 @@ using System; using System.Linq; using System.Reflection; +using System.Runtime.CompilerServices; namespace SLThree { @@ -63,11 +64,13 @@ public object InvokeForObj(ExecutionContext context, Type[] generic_args, object throw new RuntimeError($"{o.GetType().GetTypeString()} is not allow to invoke", SourceContext); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public object GetValue(ExecutionContext context, Type[] generic_args, object[] args) { return InvokeForObj(context, generic_args, args, Left.GetValue(context)); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public override object GetValue(ExecutionContext context) { return GetValue(context, GenericArguments.ConvertAll(x => (Type)x.GetValue(context)), Arguments.ConvertAll(x => x.GetValue(context))); @@ -94,7 +97,15 @@ public object GetValue(ExecutionContext context, object obj) if (founded == null) throw new RuntimeError($"Method `{key}({Arguments.Select(x => "_").JoinIntoString(", ")})` not found", SourceContext); return founded.MakeGenericMethod(generic_args).Invoke(null, Arguments.ConvertAll(x => x.GetValue(context))); } - else return InvokeForObj(context, generic_args, Arguments.ConvertAll(x => x.GetValue(context)), obj); + else if (obj != null) + { + var method = obj.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance) + .FirstOrDefault(x => x.Name == key && x.GetParameters().Length == Arguments.Length); + if (method != null) return method.MakeGenericMethod(generic_args).Invoke(obj, Arguments.ConvertAll(x => x.GetValue(context))); + else return InvokeForObj(context, generic_args, Arguments.ConvertAll(x => x.GetValue(context)), obj); + } + + return null; } public override object Clone() diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index fd63877..614dc07 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.232 + 0.8.0-alpha.235 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md From 9a30df97d539ecc24166cf80760e5351a76108a5 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Wed, 12 Jun 2024 15:42:08 +0300 Subject: [PATCH 39/69] rename JIT -> Native --- SLThree/{JIT => Native}/AbstractNameInfo.cs | 2 +- SLThree/{JIT => Native}/NETGenerator.cs | 2 +- SLThree/{JIT => Native}/NameCollector.cs | 2 +- SLThree/{JIT => Native}/NameType.cs | 2 +- SLThree/SLThree.csproj | 2 +- SLThree/Wrapper.cs | 2 +- SLThree/sys/jit.cs | 6 +++--- SLThree/sys/language.cs | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) rename SLThree/{JIT => Native}/AbstractNameInfo.cs (99%) rename SLThree/{JIT => Native}/NETGenerator.cs (99%) rename SLThree/{JIT => Native}/NameCollector.cs (99%) rename SLThree/{JIT => Native}/NameType.cs (72%) diff --git a/SLThree/JIT/AbstractNameInfo.cs b/SLThree/Native/AbstractNameInfo.cs similarity index 99% rename from SLThree/JIT/AbstractNameInfo.cs rename to SLThree/Native/AbstractNameInfo.cs index f9a5afd..9bb1b24 100644 --- a/SLThree/JIT/AbstractNameInfo.cs +++ b/SLThree/Native/AbstractNameInfo.cs @@ -2,7 +2,7 @@ using System; using System.Reflection.Emit; -namespace SLThree.JIT +namespace SLThree.Native { public class AbstractNameInfo { diff --git a/SLThree/JIT/NETGenerator.cs b/SLThree/Native/NETGenerator.cs similarity index 99% rename from SLThree/JIT/NETGenerator.cs rename to SLThree/Native/NETGenerator.cs index 2bd8bdf..23858bc 100644 --- a/SLThree/JIT/NETGenerator.cs +++ b/SLThree/Native/NETGenerator.cs @@ -7,7 +7,7 @@ using System.Reflection; using System.Reflection.Emit; -namespace SLThree.JIT +namespace SLThree.Native { public class NETGenerator : AbstractVisitor { diff --git a/SLThree/JIT/NameCollector.cs b/SLThree/Native/NameCollector.cs similarity index 99% rename from SLThree/JIT/NameCollector.cs rename to SLThree/Native/NameCollector.cs index 2c7764f..a678017 100644 --- a/SLThree/JIT/NameCollector.cs +++ b/SLThree/Native/NameCollector.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; -namespace SLThree.JIT +namespace SLThree.Native { public class NameCollector : AbstractVisitor { diff --git a/SLThree/JIT/NameType.cs b/SLThree/Native/NameType.cs similarity index 72% rename from SLThree/JIT/NameType.cs rename to SLThree/Native/NameType.cs index 3c1d825..59d00be 100644 --- a/SLThree/JIT/NameType.cs +++ b/SLThree/Native/NameType.cs @@ -1,4 +1,4 @@ -namespace SLThree.JIT +namespace SLThree.Native { public enum NameType { diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 614dc07..3a4ee6a 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.235 + 0.8.0-alpha.240 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md diff --git a/SLThree/Wrapper.cs b/SLThree/Wrapper.cs index cddb976..0a90a1d 100644 --- a/SLThree/Wrapper.cs +++ b/SLThree/Wrapper.cs @@ -1,5 +1,5 @@ using SLThree.Extensions; -using SLThree.JIT; +using SLThree.Native; using SLThree.sys; using System; using System.Collections; diff --git a/SLThree/sys/jit.cs b/SLThree/sys/jit.cs index 1cd65d4..37a7a00 100644 --- a/SLThree/sys/jit.cs +++ b/SLThree/sys/jit.cs @@ -31,9 +31,9 @@ static jit() #endif } - public static List collect_vars(Method method, ExecutionContext context) + public static List collect_vars(Method method, ExecutionContext context) { - return JIT.NameCollector.Collect(method, context).Item1; + return Native.NameCollector.Collect(method, context).Item1; } public static MethodInfo opt(Method method, ContextWrap context) @@ -47,7 +47,7 @@ public static MethodInfo opt(Method method, ContextWrap context) try { mb = dt.DefineMethod(method.Name, MethodAttributes.Public | MethodAttributes.Static, rettype, ptypes); - var ng = new JIT.NETGenerator(method, context.Context, mb, mb.GetILGenerator()); + var ng = new Native.NETGenerator(method, context.Context, mb, mb.GetILGenerator()); ng.Visit(method); } catch (Exception e) diff --git a/SLThree/sys/language.cs b/SLThree/sys/language.cs index 7836419..598bdf8 100644 --- a/SLThree/sys/language.cs +++ b/SLThree/sys/language.cs @@ -1,4 +1,4 @@ -using SLThree.JIT; +using SLThree.Native; using SLThree.Visitors; using System; using System.Collections.Generic; From aca66bcf854ebca6e2e72b2ab9fe4ea0db170096 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Wed, 12 Jun 2024 15:45:15 +0300 Subject: [PATCH 40/69] repl switch to alpha --- slt/Program.cs | 20 ++++++++++++-------- slt/slt.csproj | 2 +- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/slt/Program.cs b/slt/Program.cs index a97001a..0e20210 100644 --- a/slt/Program.cs +++ b/slt/Program.cs @@ -55,7 +55,7 @@ private static Dictionary EncodingAliases } #endif ; - internal static Assembly SLThreeAssembly; + internal static Assembly SLThreeAssembly, REPLAssembly; private static SLTVersion.Reflected SLThreeVersion; private static REPLVersion.Reflected SLTREPLVersion; private static SortedDictionary SLThreeVersions; @@ -68,6 +68,7 @@ private static bool TryGetArgument(string arg, out string value, Func no private static void InitSLThreeAssemblyInfo() { SLThreeAssembly = Assembly.GetAssembly(typeof(SLTVersion)); + REPLAssembly = Assembly.GetAssembly(typeof(Program)); SLThreeVersion = new SLTVersion.Reflected(); SLTREPLVersion = new REPLVersion.Reflected(); var sltver = SLThreeAssembly.GetType("SLTVersion"); @@ -125,9 +126,9 @@ public static string GetArgument(this string[] arguments, string arg, Dictionary public static void OutCurrentVersion() { Console.ForegroundColor = ConsoleColor.Green; - Console.Write(REPLVersion.Name); + Console.Write("REPL"); Console.ForegroundColor = ConsoleColor.White; - Console.WriteLine($" {SLTREPLVersion.VersionWithoutRevision} "); + Console.WriteLine($" {GetVersionOfREPL()} "); Console.ResetColor(); Console.ForegroundColor = ConsoleColor.Green; @@ -853,16 +854,19 @@ public static void REPLCommand(string command) #endregion private static string VersionGetted = null; - private static string GetVersionOfLanguage() + private static string REPLVersionGetted = null; + private static string GetVersionOf(Assembly assembly, ref string getted) { - if (string.IsNullOrEmpty(VersionGetted)) + if (string.IsNullOrEmpty(getted)) { - var fileVersionInfo = FileVersionInfo.GetVersionInfo(SLThreeAssembly.Location).ProductVersion; + var fileVersionInfo = FileVersionInfo.GetVersionInfo(assembly.Location).ProductVersion; var index = fileVersionInfo.IndexOf('+'); - VersionGetted = index != -1 ? fileVersionInfo.Substring(0, index) : fileVersionInfo; + getted = index != -1 ? fileVersionInfo.Substring(0, index) : fileVersionInfo; } - return VersionGetted; + return getted; } + private static string GetVersionOfLanguage() => GetVersionOf(SLThreeAssembly, ref VersionGetted); + private static string GetVersionOfREPL() => GetVersionOf(REPLAssembly, ref REPLVersionGetted); public static void REPLShortVersion() { diff --git a/slt/slt.csproj b/slt/slt.csproj index a706146..65a71a9 100644 --- a/slt/slt.csproj +++ b/slt/slt.csproj @@ -6,7 +6,7 @@ net471;net6.0;net7.0;net8.0 disable disable - 3.0.0 + 3.0.0-alpha ..\bin slthree.ico AnyCPU From 872e71f14e7e1c2a77963b2ed5af19f55b926e4d Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Wed, 12 Jun 2024 17:14:48 +0300 Subject: [PATCH 41/69] native methods --- SLThree/Expressions/FunctionDefinition.cs | 30 +++++++-- SLThree/Native/Builder.cs | 33 ++++++++++ SLThree/Native/NETGenerator.cs | 22 +++++++ SLThree/Native/Support.cs | 74 +++++++++++++++++++++++ SLThree/Native/TypeInferencer.cs | 39 ++++++++++++ SLThree/SLThree.csproj | 2 +- SLThree/syntax.peg | 1 + 7 files changed, 194 insertions(+), 7 deletions(-) create mode 100644 SLThree/Native/Builder.cs create mode 100644 SLThree/Native/Support.cs create mode 100644 SLThree/Native/TypeInferencer.cs diff --git a/SLThree/Expressions/FunctionDefinition.cs b/SLThree/Expressions/FunctionDefinition.cs index 3238e28..11e7cd9 100644 --- a/SLThree/Expressions/FunctionDefinition.cs +++ b/SLThree/Expressions/FunctionDefinition.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Reflection.Emit; using System.Text; using System.Threading.Tasks; @@ -27,6 +28,7 @@ [MODS [Name]](args)[:TRet] => expr public NameExpression[] Arguments; public StatementList FunctionBody; public TypenameExpression ReturnTypeHint; + private bool not_native; public FunctionDefinition(string[] modificators, BaseExpression name, NameExpression[] generics, NameExpression[] args, StatementList body, TypenameExpression typehint, SourceContext context) : base(context) { @@ -61,6 +63,13 @@ public FunctionDefinition(string[] modificators, BaseExpression name, NameExpres Modificators.Contains("recursive"), GenericArguments); } + + not_native = !Modificators.Contains("native"); + } + + internal DynamicMethod RebuildNative(ExecutionContext context) + { + return Native.Builder.Build(Method, context); } public override string ExpressionToString() @@ -91,14 +100,23 @@ public override string ExpressionToString() public override object GetValue(ExecutionContext context) { - var method = Method.CloneCast(); - method.@this = context.wrap; - if (FunctionName != null) + if (not_native) + { + var method = Method.CloneCast(); + method.@this = context.wrap; + if (FunctionName != null) + { + BinaryAssign.AssignToValue(context, FunctionName, method, ref counted_invoked, ref is_name_expr, ref variable_index); + } + return method; + } + else { - method.Name = CreatorContext.GetLastName(FunctionName); - BinaryAssign.AssignToValue(context, FunctionName, method, ref counted_invoked, ref is_name_expr, ref variable_index); + var native = RebuildNative(context); + if (FunctionName != null) + BinaryAssign.AssignToValue(context, FunctionName, native, ref counted_invoked, ref is_name_expr, ref variable_index); + return native; } - return method; } public override object Clone() diff --git a/SLThree/Native/Builder.cs b/SLThree/Native/Builder.cs new file mode 100644 index 0000000..e0ec1de --- /dev/null +++ b/SLThree/Native/Builder.cs @@ -0,0 +1,33 @@ +using SLThree.Extensions; +using System; +using System.Collections.Generic; +using System.Dynamic; +using System.Linq; +using System.Reflection.Emit; +using System.Text; +using System.Threading.Tasks; + +namespace SLThree.Native +{ + public static class Builder + { + public static DynamicMethod Build(Method method, ExecutionContext context) + { + Support.CheckOnSupporting(method); + var ret_type = default(Type); + if (method.ReturnType != null) + ret_type = method.ReturnType.GetValue(context).Cast(); + else ret_type = TypeInferencer.ReconstructReturnType(method); + + var dyn_method = new DynamicMethod( + method.Name, + ret_type, + method.ParamTypes.ConvertAll(x => x.GetValue(context).Cast()), + true); + var ngen = new NETGenerator(method, context, dyn_method.GetILGenerator()); + ngen.Visit(method); + + return dyn_method; + } + } +} diff --git a/SLThree/Native/NETGenerator.cs b/SLThree/Native/NETGenerator.cs index 23858bc..214405f 100644 --- a/SLThree/Native/NETGenerator.cs +++ b/SLThree/Native/NETGenerator.cs @@ -277,6 +277,11 @@ public override void VisitStatement(ExpressionStatement statement) public override void Visit(Method method) { var count = method.Statements.Statements.Length; + if (count == 0) + { + IL.Emit(OpCodes.Ret); + return; + } var current = 0; foreach (var x in method.Statements.Statements) { @@ -437,6 +442,23 @@ public override void VisitStatement(ReturnStatement statement) IL.Emit(OpCodes.Ret); } + public NETGenerator(Method method, ExecutionContext context, ILGenerator generator) + { + (Variables, VariablesMap) = NameCollector.Collect(method, context); + IL = generator; + var paramid = 1; + foreach (var x in Variables) + { + if (x.NameType == NameType.Local) + { + var lb = IL.DeclareLocal(x.Type); +#if NETFRAMEWORK + lb.SetLocalSymInfo(x.Name); +#endif + index++; + } + } + } public NETGenerator(Method method, ExecutionContext context, MethodBuilder mb, ILGenerator generator) { (Variables, VariablesMap) = NameCollector.Collect(method, context); diff --git a/SLThree/Native/Support.cs b/SLThree/Native/Support.cs new file mode 100644 index 0000000..0e76b63 --- /dev/null +++ b/SLThree/Native/Support.cs @@ -0,0 +1,74 @@ +using SLThree.Extensions; +using SLThree.Visitors; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace SLThree.Native +{ + public sealed class Support : AbstractVisitor + { + private List Exceptions = new List(); + + static Type[] SupportedExpressions, SupportedStatements; + private Support() { } + static Support() + { + SupportedExpressions = new Type[] + { + typeof(LongLiteral), + typeof(NameExpression), + + typeof(BinaryAdd), + typeof(BinaryRem), + typeof(BinaryMultiply), + typeof(BinaryDivide), + }; + SupportedStatements = new Type[] + { + typeof(ExpressionStatement), + typeof(ReturnStatement), + }; + } + + public override void VisitExpression(BaseExpression expression) + { + var type = expression.GetType(); + if (!SupportedExpressions.Contains(type)) + Exceptions.Add(new SupportException($"{type}", expression.SourceContext)); + base.VisitExpression(expression); + } + public override void VisitStatement(BaseStatement statement) + { + var type = statement.GetType(); + if (!SupportedStatements.Contains(type)) + Exceptions.Add(new SupportException($"{type}", statement.SourceContext)); + base.VisitStatement(statement); + } + + public static void CheckOnSupporting(Method method) + { + var sup = new Support(); + sup.Visit(method); + if (sup.Exceptions.Count > 0) + throw new NotSupportedException($"Method {method.Name} contains unsupported elements\n{sup.Exceptions.JoinIntoString("\n")}"); + } + } + + + [Serializable] + public class SupportException : LogicalError + { + public SupportException() { } + + public SupportException(SourceContext context) : base(context) { } + + public SupportException(string message, SourceContext context) : base(message, context) { } + + public SupportException(string message, Exception inner, SourceContext context) : base(message, inner, context) { } + } +} diff --git a/SLThree/Native/TypeInferencer.cs b/SLThree/Native/TypeInferencer.cs new file mode 100644 index 0000000..ea287ca --- /dev/null +++ b/SLThree/Native/TypeInferencer.cs @@ -0,0 +1,39 @@ +using SLThree.Visitors; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SLThree.Native +{ + public class TypeInferencer + { + public class ReturnCollector : AbstractVisitor + { + public List Returns = new List(); + + public override void VisitStatement(ReturnStatement statement) + { + Returns.Add(statement); + base.VisitStatement(statement); + } + + public static List Collect(IList statements) + { + var visitor = new ReturnCollector(); + foreach (var x in statements) + visitor.VisitStatement(x); + return visitor.Returns; + } + } + + public static Type ReconstructReturnType(Method method) + { + var statements = method.Statements.Statements; + var returns = ReturnCollector.Collect(statements); + if (returns.Count == 0 || returns.All(x => x.Expression == null)) return typeof(void); + throw new NotSupportedException("Non-void returns not supported right now"); + } + } +} diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 3a4ee6a..2cac290 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.240 + 0.8.0-alpha.252 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index 6c322ab..7adb559 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -543,6 +543,7 @@ method_mods_name > method_modificator = "recursive" / "explicit" + / "native" typename = t_node:typename_node _ "<" _ t_list:typename<1,,"," _> _ ">" { new TypenameExpression(t_node, t_list.ToArray(), state) } From 9baf8af9cb708d57f8735d1c760df1e2b136ab48 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 13 Jun 2024 00:32:06 +0300 Subject: [PATCH 42/69] fix #125 (3) --- SLThree/Expressions/InvokeExpression.cs | 2 +- .../Expressions/InvokeGenericExpression.cs | 2 +- SLThree/Expressions/MemberAccess.cs | 39 +++++++++++++++++++ SLThree/SLThree.csproj | 2 +- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/SLThree/Expressions/InvokeExpression.cs b/SLThree/Expressions/InvokeExpression.cs index 48bde43..cb983ae 100644 --- a/SLThree/Expressions/InvokeExpression.cs +++ b/SLThree/Expressions/InvokeExpression.cs @@ -108,7 +108,7 @@ public object GetValue(ExecutionContext context, object obj) .FirstOrDefault(x => x.Name == key && x.GetParameters().Length == Arguments.Length); if (method != null) return method.Invoke(obj, Arguments.ConvertAll(x => x.GetValue(context))); - else return InvokeForObj(context, Arguments.ConvertAll(x => x.GetValue(context)), obj); + else return InvokeForObj(context, Arguments.ConvertAll(x => x.GetValue(context)), MemberAccess.GetNameExprValue(context, obj, Left as NameExpression)); } return null; diff --git a/SLThree/Expressions/InvokeGenericExpression.cs b/SLThree/Expressions/InvokeGenericExpression.cs index 7db1202..eeefedb 100644 --- a/SLThree/Expressions/InvokeGenericExpression.cs +++ b/SLThree/Expressions/InvokeGenericExpression.cs @@ -102,7 +102,7 @@ public object GetValue(ExecutionContext context, object obj) var method = obj.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance) .FirstOrDefault(x => x.Name == key && x.GetParameters().Length == Arguments.Length); if (method != null) return method.MakeGenericMethod(generic_args).Invoke(obj, Arguments.ConvertAll(x => x.GetValue(context))); - else return InvokeForObj(context, generic_args, Arguments.ConvertAll(x => x.GetValue(context)), obj); + else return InvokeForObj(context, generic_args, Arguments.ConvertAll(x => x.GetValue(context)), MemberAccess.GetNameExprValue(context, obj, Left as NameExpression)); } return null; diff --git a/SLThree/Expressions/MemberAccess.cs b/SLThree/Expressions/MemberAccess.cs index fb9779b..b219bb1 100644 --- a/SLThree/Expressions/MemberAccess.cs +++ b/SLThree/Expressions/MemberAccess.cs @@ -4,6 +4,7 @@ using System.Collections; using System.Linq; using System.Reflection; +using System.Runtime.InteropServices.ComTypes; using System.Text; namespace SLThree @@ -32,6 +33,44 @@ public MemberAccess() : base() { } private bool is_unwrap; private bool is_super; private bool is_upper; + + public static object GetNameExprValue(ExecutionContext context, object left, NameExpression Right) + { + if (left != null) + { + if (left is ContextWrap pred) + { + if (Right is NameExpression predName) + { + if (predName.Name == "super") + { + return pred.Context.super; + } + else if (predName.Name == "upper") + { + return pred.Context.PreviousContext?.wrap; + } + return pred.Context.LocalVariables.GetValue(predName.Name).Item1; + } + } + var has_access = left is ClassAccess access; + var type = has_access ? (left as ClassAccess).Name : left.GetType(); + + var field = type.GetField(Right.Name); + if (field != null) return field.GetValue(left); + var prop = type.GetProperty(Right.Name); + if (prop != null) return prop.GetValue(left); + var nest_type = type.GetNestedType(Right.Name); + if (nest_type != null) return new ClassAccess(nest_type); + if (left is IDictionary dict) + return dict[Right.Name]; + + throw new RuntimeError($"Name \"{Right.Name}\" not found in {type.GetTypeString()}", Right.SourceContext); + } + + return null; + } + public override object GetValue(ExecutionContext context) { var left = Left.GetValue(context); diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 2cac290..107d2e8 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.252 + 0.8.0-alpha.254 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md From f661a05d04bc7abbc6a017d6354a70b6166a94fe Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 13 Jun 2024 01:37:40 +0300 Subject: [PATCH 43/69] base fix --- SLThree/Expressions/Literals/Special/BaseLiteral.cs | 2 +- SLThree/SLThree.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SLThree/Expressions/Literals/Special/BaseLiteral.cs b/SLThree/Expressions/Literals/Special/BaseLiteral.cs index 4d0f63d..f30afaf 100644 --- a/SLThree/Expressions/Literals/Special/BaseLiteral.cs +++ b/SLThree/Expressions/Literals/Special/BaseLiteral.cs @@ -8,7 +8,7 @@ public BaseLiteral(SourceContext context) : base(context) { } public BaseLiteral(Cursor cursor) : base(cursor) { } public override string ExpressionToString() => "base"; - public override object GetValue(ExecutionContext context) => context.@base; + public override object GetValue(ExecutionContext context) => context.@this.Context.@base; public override object Clone() => new BaseLiteral(SourceContext); } } diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 107d2e8..1ce788b 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.254 + 0.8.0-alpha.255 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md From 8282e4fe66d7ba7aeff41ea7d273667070f9a6c2 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 13 Jun 2024 16:18:08 +0300 Subject: [PATCH 44/69] base -> parent --- SLThree/ExecutionContext.cs | 6 +++--- .../Expressions/Literals/Special/BaseLiteral.cs | 14 -------------- .../Expressions/Literals/Special/ParentLiteral.cs | 14 ++++++++++++++ SLThree/Expressions/MemberAccess.cs | 12 ++++++++++++ SLThree/Parser.cs | 2 +- SLThree/SLThree.csproj | 2 +- 6 files changed, 31 insertions(+), 19 deletions(-) delete mode 100644 SLThree/Expressions/Literals/Special/BaseLiteral.cs create mode 100644 SLThree/Expressions/Literals/Special/ParentLiteral.cs diff --git a/SLThree/ExecutionContext.cs b/SLThree/ExecutionContext.cs index 286bedd..2ae9d27 100644 --- a/SLThree/ExecutionContext.cs +++ b/SLThree/ExecutionContext.cs @@ -74,7 +74,7 @@ public ExecutionContext() : this(true, true, null) { } public readonly ContextWrap wrap; public ContextWrap super; public ContextWrap @private; - public ContextWrap @base; + public ContextWrap parent; internal ExecutionContext SuperContext { get => super?.Context; set => super = new ContextWrap(value); } public IEnumerable GetHierarchy() @@ -120,7 +120,7 @@ public ExecutionContext CreateInstance(Method constructor, object[] args) { var ret = new ExecutionContext(super.Context); ret.Name = $"{Name}@{Convert.ToString(Creations++, 16).ToUpper().PadLeft(4, '0')}"; - ret.@base = wrap; + ret.parent = wrap; constructor.@this = ret.wrap; constructor.GetValue(ret, args); return ret; @@ -129,7 +129,7 @@ public ExecutionContext CreateInstance(object[] args, SourceContext sourceContex { var ret = new ExecutionContext(super.Context); ret.Name = $"{Name}@{Convert.ToString(Creations++, 16).ToUpper().PadLeft(4, '0')}"; - ret.@base = wrap; + ret.parent = wrap; if (LocalVariables.GetValue("constructor").Item1 is Method constructor) { if (constructor.ParamNames.Length != args.Length) diff --git a/SLThree/Expressions/Literals/Special/BaseLiteral.cs b/SLThree/Expressions/Literals/Special/BaseLiteral.cs deleted file mode 100644 index f30afaf..0000000 --- a/SLThree/Expressions/Literals/Special/BaseLiteral.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Pegasus.Common; - -namespace SLThree -{ - public class BaseLiteral : Special - { - public BaseLiteral(SourceContext context) : base(context) { } - public BaseLiteral(Cursor cursor) : base(cursor) { } - - public override string ExpressionToString() => "base"; - public override object GetValue(ExecutionContext context) => context.@this.Context.@base; - public override object Clone() => new BaseLiteral(SourceContext); - } -} diff --git a/SLThree/Expressions/Literals/Special/ParentLiteral.cs b/SLThree/Expressions/Literals/Special/ParentLiteral.cs new file mode 100644 index 0000000..d6aec18 --- /dev/null +++ b/SLThree/Expressions/Literals/Special/ParentLiteral.cs @@ -0,0 +1,14 @@ +using Pegasus.Common; + +namespace SLThree +{ + public class ParentLiteral : Special + { + public ParentLiteral(SourceContext context) : base(context) { } + public ParentLiteral(Cursor cursor) : base(cursor) { } + + public override string ExpressionToString() => "parent"; + public override object GetValue(ExecutionContext context) => context.@this.Context.parent; + public override object Clone() => new ParentLiteral(SourceContext); + } +} diff --git a/SLThree/Expressions/MemberAccess.cs b/SLThree/Expressions/MemberAccess.cs index b219bb1..1ffb36b 100644 --- a/SLThree/Expressions/MemberAccess.cs +++ b/SLThree/Expressions/MemberAccess.cs @@ -33,6 +33,7 @@ public MemberAccess() : base() { } private bool is_unwrap; private bool is_super; private bool is_upper; + private bool is_parent; public static object GetNameExprValue(ExecutionContext context, object left, NameExpression Right) { @@ -46,6 +47,10 @@ public static object GetNameExprValue(ExecutionContext context, object left, Nam { return pred.Context.super; } + else if (predName.Name == "parent") + { + return pred.Context.parent; + } else if (predName.Name == "upper") { return pred.Context.PreviousContext?.wrap; @@ -78,6 +83,7 @@ public override object GetValue(ExecutionContext context) if (counted_contextwrapcache) { if (is_super) return (left as ContextWrap).Context.super; + else if (is_parent) return (left as ContextWrap).Context.parent; else if (is_upper) return (left as ContextWrap).Context.PreviousContext.wrap; else return (left as ContextWrap).Context.LocalVariables.GetValue(variable_name).Item1; } @@ -99,6 +105,12 @@ public override object GetValue(ExecutionContext context) is_super = true; return pred.Context.super; } + else if (predName.Name == "parent") + { + counted_contextwrapcache = true; + is_parent = true; + return pred.Context.parent; + } else if (predName.Name == "upper") { counted_contextwrapcache = true; diff --git a/SLThree/Parser.cs b/SLThree/Parser.cs index 2adf5db..43b89fd 100644 --- a/SLThree/Parser.cs +++ b/SLThree/Parser.cs @@ -51,7 +51,7 @@ private BaseExpression GetSpecialName(NameExpression expression) { switch (expression.Name) { - case "base": return new BaseLiteral(expression.SourceContext); + case "parent": return new ParentLiteral(expression.SourceContext); case "global": return new GlobalLiteral(expression.SourceContext); case "self": return new SelfLiteral(expression.SourceContext); case "this": return new ThisLiteral(expression.SourceContext); diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 1ce788b..21ac3c8 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.255 + 0.8.0-alpha.257 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md From db59d77ce5c45a2a4fe6ba5f62cea4f4ffed6473 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 13 Jun 2024 16:22:59 +0300 Subject: [PATCH 45/69] changelog append --- SLThree/docs/versions/0.8.0 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SLThree/docs/versions/0.8.0 b/SLThree/docs/versions/0.8.0 index 4c2ee45..a192c27 100644 --- a/SLThree/docs/versions/0.8.0 +++ b/SLThree/docs/versions/0.8.0 @@ -14,6 +14,8 @@ Language: - Constructor method that creates new contexts `context TBase { constructor = (f) => this.f = f; };` `T1 = TBase(5); T2 = TBase(10);` + - Parent keyword in constructed contexts + `T1.parent == TBase;` - Static expression (will be executed only once) `static x` - Condition expression instead of condition statement - Strong method binding From f07a98513398660abffd0706b7492e062df50022 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 13 Jun 2024 16:45:05 +0300 Subject: [PATCH 46/69] visitor realization for 0.8.0 creators --- SLThree/SLThree.csproj | 2 +- SLThree/Visitors/Definition/AbstractVisitor.cs | 17 +++++++++++++++-- .../Visitors/Definition/IExpressionVisitor.cs | 2 +- SLThree/docs/versions/0.8.0 | 3 +++ 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 21ac3c8..859697e 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.257 + 0.8.0-alpha.258 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md diff --git a/SLThree/Visitors/Definition/AbstractVisitor.cs b/SLThree/Visitors/Definition/AbstractVisitor.cs index d182e84..24f29e4 100644 --- a/SLThree/Visitors/Definition/AbstractVisitor.cs +++ b/SLThree/Visitors/Definition/AbstractVisitor.cs @@ -188,7 +188,15 @@ public virtual void VisitExpression(NameExpression expression) public virtual void VisitExpression(CreatorInstance expression) { - throw new NotImplementedException(); + Executables.Add(expression); + VisitExpression(expression.Type); + Executables.Remove(expression); + if (expression.Name != null) + VisitExpression(expression.Name); + foreach (var x in expression.Arguments) + VisitExpression(x); + if (expression.CreatorContext != null) + VisitExpression(expression.CreatorContext); } public virtual void VisitExpression(Special expression) @@ -356,7 +364,12 @@ public virtual void VisitExpression(CreatorNewArray expression) public virtual void VisitExpression(CreatorContext expression) { - throw new NotImplementedException(); + if (expression.HasName) + VisitExpression(expression.Name); + foreach (var x in expression.Ancestors) + VisitExpression(x); + if (expression.CreatorBody != null) + VisitStatement(expression.CreatorBody); } public virtual void VisitExpression(CreatorRange expression) diff --git a/SLThree/Visitors/Definition/IExpressionVisitor.cs b/SLThree/Visitors/Definition/IExpressionVisitor.cs index 30d9da5..836faf9 100644 --- a/SLThree/Visitors/Definition/IExpressionVisitor.cs +++ b/SLThree/Visitors/Definition/IExpressionVisitor.cs @@ -11,6 +11,7 @@ public interface IExpressionVisitor void VisitExpression(CreatorRange expression); void VisitExpression(CreatorTuple expression); void VisitExpression(CreatorUsing expression); + void VisitExpression(CreatorContext expression); void VisitExpression(CreatorInstance expression); void VisitExpression(CastExpression expression); @@ -32,6 +33,5 @@ public interface IExpressionVisitor void VisitExpression(UnaryOperator expression); void VisitExpression(BinaryOperator expression); void VisitExpression(TernaryOperator expression); - } } diff --git a/SLThree/docs/versions/0.8.0 b/SLThree/docs/versions/0.8.0 index a192c27..82c5df1 100644 --- a/SLThree/docs/versions/0.8.0 +++ b/SLThree/docs/versions/0.8.0 @@ -14,6 +14,9 @@ Language: - Constructor method that creates new contexts `context TBase { constructor = (f) => this.f = f; };` `T1 = TBase(5); T2 = TBase(10);` + - The right side of the nested context initializer + assignations now always refers to the self context + `x = 1; context A { context B { x = x; }}` - Parent keyword in constructed contexts `T1.parent == TBase;` - Static expression (will be executed only once) `static x` From a80d17443c5880c181d2501bc50cd3a264772b2d Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 13 Jun 2024 17:26:36 +0300 Subject: [PATCH 47/69] contextbody cache bugfix --- SLThree/Expressions/Creators/CreatorTuple.cs | 2 +- SLThree/Statements/CreatorContextBody.cs | 18 ++++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/SLThree/Expressions/Creators/CreatorTuple.cs b/SLThree/Expressions/Creators/CreatorTuple.cs index 4b18757..7049977 100644 --- a/SLThree/Expressions/Creators/CreatorTuple.cs +++ b/SLThree/Expressions/Creators/CreatorTuple.cs @@ -9,7 +9,7 @@ namespace SLThree public class CreatorTuple : BaseExpression { public BaseExpression[] Expressions; - public (ExecutionContext, bool, int)[] Caches; + private (ExecutionContext, bool, int)[] Caches; public CreatorTuple(BaseExpression[] expressions, SourceContext context) : base(context) { diff --git a/SLThree/Statements/CreatorContextBody.cs b/SLThree/Statements/CreatorContextBody.cs index 36320e9..3285f7b 100644 --- a/SLThree/Statements/CreatorContextBody.cs +++ b/SLThree/Statements/CreatorContextBody.cs @@ -6,15 +6,14 @@ namespace SLThree { public class CreatorContextBody : StatementList, ICloneable { - private ExecutionContext counted_invoked; - private bool is_name_expr; - private int variable_index; + private (ExecutionContext, bool, int)[] Caches; public CreatorContextBody() : base() { } public CreatorContextBody(IList statements, SourceContext context) : base(statements, context) { foreach (var x in Statements) CheckOnContextStatements(x); + Caches = new (ExecutionContext, bool, int)[Statements.Length]; } public ExecutionContext GetValue(ExecutionContext target, ExecutionContext context) @@ -26,23 +25,23 @@ public ExecutionContext GetValue(ExecutionContext target, ExecutionContext conte if (es.Expression is BinaryAssign assign) { if (assign.Left is MemberAccess @private) - BinaryAssign.AssignToValue(target.@private.Context, @private.Right, assign.Right.GetValue(context), ref counted_invoked, ref is_name_expr, ref variable_index); + BinaryAssign.AssignToValue(target.@private.Context, @private.Right, assign.Right.GetValue(context), ref Caches[i].Item1, ref Caches[i].Item2, ref Caches[i].Item3); else - BinaryAssign.AssignToValue(target, assign.Left, assign.Right.GetValue(context), ref counted_invoked, ref is_name_expr, ref variable_index); + BinaryAssign.AssignToValue(target, assign.Left, assign.Right.GetValue(context), ref Caches[i].Item1, ref Caches[i].Item2, ref Caches[i].Item3); } else if (es.Expression is CreatorContext creator) { if (creator.Name is MemberAccess @private) - BinaryAssign.AssignToValue(target.@private.Context, @private.Right, creator.GetValue(target, context), ref counted_invoked, ref is_name_expr, ref variable_index); + BinaryAssign.AssignToValue(target.@private.Context, @private.Right, creator.GetValue(target, context), ref Caches[i].Item1, ref Caches[i].Item2, ref Caches[i].Item3); else - BinaryAssign.AssignToValue(target, creator.Name, creator.GetValue(target, context), ref counted_invoked, ref is_name_expr, ref variable_index); + BinaryAssign.AssignToValue(target, creator.Name, creator.GetValue(target, context), ref Caches[i].Item1, ref Caches[i].Item2, ref Caches[i].Item3); } else if (es.Expression is FunctionDefinition function) { if (function.FunctionName is MemberAccess @private) - BinaryAssign.AssignToValue(target.@private.Context, @private.Right, function.GetValue(target.@private.Context), ref counted_invoked, ref is_name_expr, ref variable_index); + BinaryAssign.AssignToValue(target.@private.Context, @private.Right, function.GetValue(target.@private.Context), ref Caches[i].Item1, ref Caches[i].Item2, ref Caches[i].Item3); else - BinaryAssign.AssignToValue(target, function.FunctionName, function.GetValue(target), ref counted_invoked, ref is_name_expr, ref variable_index); + BinaryAssign.AssignToValue(target, function.FunctionName, function.GetValue(target), ref Caches[i].Item1, ref Caches[i].Item2, ref Caches[i].Item3); } } } @@ -69,7 +68,6 @@ private static BaseStatement CheckOnContextStatements(BaseStatement statement) { if (creator.Name == null) throw new LogicalError($"Nested context definitions should be named", expressionStatement.Expression.SourceContext); if (CheckName(creator.Name)) return statement; - return statement; } if (expressionStatement.Expression is FunctionDefinition function) { From bed2e3139d3f8b9d5e79c498632b63e330ef0daa Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 13 Jun 2024 17:29:55 +0300 Subject: [PATCH 48/69] using expression instead statement --- SLThree.HTMLCreator/HTMLCreator.cs | 4 +- SLThree/Expressions/UsingExpression.cs | 48 +++++++++++++++++++ SLThree/SLThree.csproj | 2 +- SLThree/Statements/ReturnStatement.cs | 2 +- SLThree/Statements/UsingStatement.cs | 42 ---------------- .../Visitors/Definition/AbstractVisitor.cs | 6 ++- .../Visitors/Definition/IExpressionVisitor.cs | 1 + .../Visitors/Definition/IStatementVisitor.cs | 1 - SLThree/docs/versions/0.8.0 | 3 +- SLThree/syntax.peg | 15 +++--- 10 files changed, 66 insertions(+), 58 deletions(-) create mode 100644 SLThree/Expressions/UsingExpression.cs delete mode 100644 SLThree/Statements/UsingStatement.cs diff --git a/SLThree.HTMLCreator/HTMLCreator.cs b/SLThree.HTMLCreator/HTMLCreator.cs index 1c0095b..4486c13 100644 --- a/SLThree.HTMLCreator/HTMLCreator.cs +++ b/SLThree.HTMLCreator/HTMLCreator.cs @@ -553,13 +553,13 @@ public override void VisitStatement(ContinueStatement statement) { CurrentString.Append(GetKeyword2("continue") + ";"); } - public override void VisitStatement(UsingStatement statement) + public override void VisitExpression(UsingExpression statement) { VisitExpression(statement.Using, false); if (statement.Alias != null) { CurrentString.Append(GetKeyword1( " as ")); - CurrentString.Append(statement.Alias.Name); + VisitExpression(statement.Alias); } CurrentString.Append(";"); } diff --git a/SLThree/Expressions/UsingExpression.cs b/SLThree/Expressions/UsingExpression.cs new file mode 100644 index 0000000..ad4d17f --- /dev/null +++ b/SLThree/Expressions/UsingExpression.cs @@ -0,0 +1,48 @@ +using SLThree.Extensions; +using SLThree.Extensions.Cloning; +using System.Linq; + +namespace SLThree +{ + public class UsingExpression : BaseExpression + { + public BaseExpression Alias; + public CreatorUsing Using; + private ExecutionContext counted_invoked; + private bool is_name_expr; + private int variable_index; + + public UsingExpression(BaseExpression alias, CreatorUsing usingBody, SourceContext context) : base(context) + { + Alias = alias; + Using = usingBody; + } + + public UsingExpression(CreatorUsing @using, SourceContext context) : this(null, @using, context) { } + + public override string ExpressionToString() => $"using {Using.Type} as {Alias}"; + + public override object GetValue(ExecutionContext context) + { + var @using = Using.GetValue(context).Cast(); + string name; + if (Alias == null) + { + var type_name = Using.GetTypenameWithoutGenerics(); + name = type_name.Contains(".") ? @using.Name.Name : type_name; + name = name.Contains("`") ? name.Substring(0, name.IndexOf("`")) : name; + variable_index = context.LocalVariables.SetValue(name, @using); + } + else { + BinaryAssign.AssignToValue(context, Alias, @using, ref counted_invoked, ref is_name_expr, ref variable_index); + } + + return @using; + } + + public override object Clone() + { + return new UsingExpression(Alias.CloneCast(), Using.CloneCast(), SourceContext.CloneCast()); + } + } +} diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 859697e..f1bb369 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.258 + 0.8.0-alpha.268 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md diff --git a/SLThree/Statements/ReturnStatement.cs b/SLThree/Statements/ReturnStatement.cs index 28d7090..b1670df 100644 --- a/SLThree/Statements/ReturnStatement.cs +++ b/SLThree/Statements/ReturnStatement.cs @@ -18,7 +18,7 @@ public ReturnStatement(SourceContext context) : base(context) VoidReturn = true; } - public override string ToString() => $"{Expression}"; + public override string ToString() => VoidReturn ? "return;" : $"return {Expression};"; public override object GetValue(ExecutionContext context) { if (VoidReturn) diff --git a/SLThree/Statements/UsingStatement.cs b/SLThree/Statements/UsingStatement.cs deleted file mode 100644 index f976d5e..0000000 --- a/SLThree/Statements/UsingStatement.cs +++ /dev/null @@ -1,42 +0,0 @@ -using SLThree.Extensions; -using SLThree.Extensions.Cloning; -using System.Linq; - -namespace SLThree -{ - public class UsingStatement : BaseStatement - { - public NameExpression Alias; - public CreatorUsing Using; - - public UsingStatement(NameExpression alias, CreatorUsing usingBody, SourceContext context) : base(context) - { - Alias = alias; - Using = usingBody; - } - - public UsingStatement(CreatorUsing @using, SourceContext context) : this(null, @using, context) { } - - public override string ToString() => $"using {Using.Type} as {Alias}"; - - public override object GetValue(ExecutionContext context) - { - var @using = Using.GetValue(context).Cast(); - string name; - if (Alias == null) - { - var type_name = Using.GetTypenameWithoutGenerics(); - name = type_name.Contains(".") ? @using.Name.Name : type_name; - name = name.Contains("`") ? name.Substring(0, name.IndexOf("`")) : name; - } - else name = Alias.Name; - context.LocalVariables.SetValue(name, @using); - return null; - } - - public override object Clone() - { - return new UsingStatement(Using.CloneCast(), SourceContext.CloneCast()); - } - } -} diff --git a/SLThree/Visitors/Definition/AbstractVisitor.cs b/SLThree/Visitors/Definition/AbstractVisitor.cs index 24f29e4..565504b 100644 --- a/SLThree/Visitors/Definition/AbstractVisitor.cs +++ b/SLThree/Visitors/Definition/AbstractVisitor.cs @@ -72,6 +72,7 @@ public virtual void VisitExpression(BaseExpression expression) case CreatorContext expr: VisitExpression(expr); return; case CreatorRange expr: VisitExpression(expr); return; case MatchExpression expr: VisitExpression(expr); return; + case UsingExpression expr: VisitExpression(expr); return; } Executables.Remove(expression); } @@ -293,7 +294,6 @@ public virtual void VisitStatement(BaseStatement statement) case WhileLoopStatement st: VisitStatement(st); return; case ExpressionStatement st: VisitStatement(st); return; case ReturnStatement st: VisitStatement(st); return; - case UsingStatement st: VisitStatement(st); return; case StatementList st: VisitStatement(st); return; case BreakStatement st: VisitStatement(st); return; case ContinueStatement st: VisitStatement(st); return; @@ -335,9 +335,11 @@ public virtual void VisitStatement(ReturnStatement statement) if (!statement.VoidReturn) VisitExpression(statement.Expression); } - public virtual void VisitStatement(UsingStatement statement) + public virtual void VisitExpression(UsingExpression statement) { VisitExpression(statement.Using); + if (statement.Alias != null) + VisitExpression(statement.Alias); } public virtual void VisitStatement(StatementList statement) diff --git a/SLThree/Visitors/Definition/IExpressionVisitor.cs b/SLThree/Visitors/Definition/IExpressionVisitor.cs index 836faf9..03ac3b5 100644 --- a/SLThree/Visitors/Definition/IExpressionVisitor.cs +++ b/SLThree/Visitors/Definition/IExpressionVisitor.cs @@ -27,6 +27,7 @@ public interface IExpressionVisitor void VisitExpression(TypenameExpression expression); void VisitExpression(MatchExpression expression); void VisitExpression(StaticExpression expression); + void VisitExpression(UsingExpression statement); void VisitExpression(Special expression); void VisitExpression(Literal expression); diff --git a/SLThree/Visitors/Definition/IStatementVisitor.cs b/SLThree/Visitors/Definition/IStatementVisitor.cs index 046bbf3..1454cc7 100644 --- a/SLThree/Visitors/Definition/IStatementVisitor.cs +++ b/SLThree/Visitors/Definition/IStatementVisitor.cs @@ -12,7 +12,6 @@ public interface IStatementVisitor void VisitStatement(StatementList statement); void VisitStatement(ThrowStatement statement); void VisitStatement(TryStatement statement); - void VisitStatement(UsingStatement statement); void VisitStatement(WhileLoopStatement statement); } } diff --git a/SLThree/docs/versions/0.8.0 b/SLThree/docs/versions/0.8.0 index 82c5df1..ba860bd 100644 --- a/SLThree/docs/versions/0.8.0 +++ b/SLThree/docs/versions/0.8.0 @@ -20,7 +20,8 @@ Language: - Parent keyword in constructed contexts `T1.parent == TBase;` - Static expression (will be executed only once) `static x` - - Condition expression instead of condition statement + - Condition statement is now expression + - Using statement is now expression - Strong method binding - Changed context syntax: `new context Name: T {...}` -> `new T Name {...}` diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index 7adb559..c8e08a1 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -15,7 +15,6 @@ statement = return_statement / break_statement / continue_statement - / using_statement / foreach_statement / while_statement / try_statement @@ -31,13 +30,6 @@ statement / block_statement / ";" { new EmptyStatement(state) } -using_statement - = "using" _required_ u:using - using_alias:( _required_ "as" _required_ n:name {n})? - _ ";" { - new UsingStatement(GetOptional(using_alias), u, state) - } - return_statement = "return" _ expr:expression _ ";" { new ReturnStatement(expr, state) } / "return" _ ";" { new ReturnStatement(state) } @@ -205,6 +197,12 @@ unary / "@" _ left:typename { new UnaryReflection(left, state) } / primary +using_expression + = "using" _required_ u:using + using_alias:( _required_ "as" _required_ name:primary {name})? { + new UsingExpression(GetOptional(using_alias), u, state) + } + condition_statement = "if" _ "(" _ cond:expression _ ")" _ t:statement _ "else" _ f:block_statement { new ConditionExpression(cond, GetListStatement(t), GetListStatement(f), state) } / "if" _ "(" _ cond:expression _ ")" _ t:block_statement { new ConditionExpression(cond, GetListStatement(t), new StatementList(new BaseStatement[0], state), state) } @@ -249,6 +247,7 @@ primary -memoize / "new" _required_ tp:typename _ "[" _ size:expression _ "]" { new CreatorNewArray(tp, size, state) } // "new" _required_ "context" c: context { c } / "new" _required_ "using" _required_ u: using { u } + / using_expression / new_context_expression / context_expression / instance_expression From 7be8aa5c702d4403df2b3f47731a90f65e07ec2f Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 13 Jun 2024 17:32:57 +0300 Subject: [PATCH 49/69] switch to 0.8.0 beta --- SLThree/SLThree.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index f1bb369..a057974 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-alpha.268 + 0.8.0-beta.1 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md From 96b21fa50a5e89201e1f4a1bb0aab1b90134cf8f Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 13 Jun 2024 18:48:11 +0300 Subject: [PATCH 50/69] html creator update --- SLThree.HTMLCreator/HTMLCreator.cs | 88 ++++++++++++++++--- SLThree/SLThree.csproj | 2 +- .../Visitors/Definition/AbstractVisitor.cs | 2 +- 3 files changed, 77 insertions(+), 15 deletions(-) diff --git a/SLThree.HTMLCreator/HTMLCreator.cs b/SLThree.HTMLCreator/HTMLCreator.cs index 4486c13..fa4a25e 100644 --- a/SLThree.HTMLCreator/HTMLCreator.cs +++ b/SLThree.HTMLCreator/HTMLCreator.cs @@ -385,7 +385,8 @@ public override void VisitExpression(NameExpression expression) VisitExpression(expression.TypeHint); CurrentString.Append(" "); } - CurrentString.Append(expression.Name); + if (expression.Name == "constructor") CurrentString.Append(GetKeyword1("constructor")); + else CurrentString.Append(expression.Name); } public override void VisitExpression(UnaryOperator expression) { @@ -449,7 +450,11 @@ public override void VisitExpression(FunctionDefinition expression) foreach (var x in expression.Modificators) { CurrentString.Append(GetKeyword1(x)); - CurrentString.Append(" "); + } + if (expression.FunctionName != null) + { + if (expression.Modificators.Length > 0) CurrentString.Append(" "); + VisitExpression(expression.FunctionName); } if (expression.GenericArguments.Length > 0) { @@ -473,9 +478,9 @@ public override void VisitExpression(FunctionDefinition expression) CurrentString.Append(": "); VisitExpression(expression.ReturnTypeHint); } - CurrentString.Append(Replace(" => ")); if (expression.FunctionBody.Statements.Length == 1 && expression.FunctionBody.Statements[0] is ReturnStatement ret && ret.Expression != null) { + CurrentString.Append(Replace(" => ")); VisitExpression(ret.Expression); } else @@ -500,22 +505,66 @@ public void VisitExpression(CreatorUsing expression, bool hasnew) CurrentString.Append(GetKeyword1("using ")); VisitExpression(expression.Type); } + public override void VisitExpression(CreatorContext expression) + { + CurrentString.Append(GetKeyword1(expression.CreatorBody == null || expression.CreatorBody.Statements.Length == 0 ? "new context" : "context")); + if (expression.HasName) + { + CurrentString.Append(" "); + VisitExpression(expression.Name); + } + RestOfContext(expression); + } + public void RestOfContext(CreatorContext expression) + { + if (expression.Ancestors.Length > 0) + { + CurrentString.Append(": "); + for (var i = 0; i < expression.Ancestors.Length; i++) + { + VisitExpression(expression.Ancestors[i]); + if (i != expression.Ancestors.Length - 1) CurrentString.Append(", "); + } + } + if (expression.CreatorBody != null && expression.CreatorBody.Statements.Length > 0) + { + CurrentString.Append(" {\n"); + CurrentTab += 1; + foreach (var x in (expression.CreatorBody).Statements) + { + Newline(); + VisitStatement(x); + } + CurrentTab -= 1; + Newline(); + CurrentString.Append("}"); + } + } public override void VisitExpression(CreatorUsing expression) { VisitExpression(expression, true); } public override void VisitExpression(CreatorInstance expression) { - throw new NotImplementedException(); - /*CurrentString.Append(GetKeyword1("new ")); - VisitExpression(expression.Typename); - CurrentString.Append("("); - for (var i = 0; i < expression.Arguments.Length; i++) + CurrentString.Append(GetKeyword1("new ")); + VisitExpression(expression.Type); + if (expression.Arguments.Length > 0) { - VisitExpression(expression.Arguments[i]); - if (i < expression.Arguments.Length - 1) CurrentString.Append(", "); + CurrentString.Append("("); + for (var i = 0; i < expression.Arguments.Length; i++) + { + VisitExpression(expression.Arguments[i]); + if (i < expression.Arguments.Length - 1) CurrentString.Append(", "); + } + CurrentString.Append(")"); + } + if (expression.Name != null) + { + CurrentString.Append(" "); + VisitExpression(expression.Name); } - CurrentString.Append(")");*/ + if (expression.CreatorContext != null) + RestOfContext(expression.CreatorContext); } public override void VisitExpression(ReflectionExpression expression) { @@ -524,13 +573,13 @@ public override void VisitExpression(ReflectionExpression expression) VisitExpression(expression.Right); if (expression.MethodGenericArguments?.Length > 0) { - CurrentString.Append("<"); + CurrentString.Append(Replace("<")); for (var i = 0; i < expression.MethodGenericArguments.Length; i++) { VisitExpression(expression.MethodGenericArguments[i]); if (i < expression.MethodGenericArguments.Length - 1) CurrentString.Append(", "); } - CurrentString.Append(">"); + CurrentString.Append(Replace(">")); } if (expression.MethodArguments?.Length > 0) { @@ -544,6 +593,11 @@ public override void VisitExpression(ReflectionExpression expression) CurrentString.Append(")"); } } + public override void VisitExpression(StaticExpression expression) + { + CurrentString.Append(GetKeyword1("static ")); + VisitExpression(expression.Right); + } public override void VisitStatement(BreakStatement statement) { @@ -749,6 +803,14 @@ public override void VisitStatement(WhileLoopStatement statement) public override void VisitStatement(ExpressionStatement statement) { base.VisitExpression(statement.Expression); + if (statement.Expression is ConditionExpression + || (statement.Expression is CreatorContext cont && (cont.CreatorBody != null && cont.CreatorBody.Statements.Length > 0)) + || (statement.Expression is CreatorInstance inst && inst.CreatorContext?.CreatorBody != null) + || statement.Expression is MatchExpression + || (statement.Expression is FunctionDefinition func && !(func.FunctionBody.Statements.Length == 1 && func.FunctionBody.Statements[0] is ReturnStatement ret && !ret.VoidReturn))) + { + return; + } CurrentString.Append(";"); } diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index a057974..9c6bea9 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-beta.1 + 0.8.0-beta.6 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md diff --git a/SLThree/Visitors/Definition/AbstractVisitor.cs b/SLThree/Visitors/Definition/AbstractVisitor.cs index 565504b..4fc983e 100644 --- a/SLThree/Visitors/Definition/AbstractVisitor.cs +++ b/SLThree/Visitors/Definition/AbstractVisitor.cs @@ -403,7 +403,7 @@ public virtual void VisitStatement(ThrowStatement statement) VisitExpression(statement.ThrowExpression); } - public void VisitExpression(StaticExpression expression) + public virtual void VisitExpression(StaticExpression expression) { VisitExpression(expression.Right); } From 349406272eed93af1950743a26ab1632bb39e3ac Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Fri, 14 Jun 2024 16:33:59 +0300 Subject: [PATCH 51/69] fix unnamed instance --- SLThree/Expressions/Creators/CreatorInstance.cs | 2 +- SLThree/SLThree.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SLThree/Expressions/Creators/CreatorInstance.cs b/SLThree/Expressions/Creators/CreatorInstance.cs index e71d3f1..c5f02e8 100644 --- a/SLThree/Expressions/Creators/CreatorInstance.cs +++ b/SLThree/Expressions/Creators/CreatorInstance.cs @@ -98,7 +98,7 @@ public static CreatorInstance NamedCaseTypeBody(TypenameExpression type, BaseExp type, name, new BaseExpression[0], - new CreatorContext(null, new BaseExpression[0], body, false, context), + new CreatorContext(name, new BaseExpression[0], body, false, context), context); public static CreatorInstance NamedCaseTypeArgs(TypenameExpression type, BaseExpression name, BaseExpression[] args, SourceContext context) => new CreatorInstance( diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 9c6bea9..bc7fc91 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-beta.6 + 0.8.0-beta.10 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md From b3caebe81723e3dbad6e454dd8af4032f520761e Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Tue, 18 Jun 2024 13:22:21 +0300 Subject: [PATCH 52/69] switch ot rc --- SLThree/SLThree.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index bc7fc91..b3a9b81 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-beta.10 + 0.8.0-rc.1 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md From 14b8b7b3fb0de96595e390fde09a1446c4a6f607 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Tue, 18 Jun 2024 17:36:00 +0300 Subject: [PATCH 53/69] Binding&Naming Update --- SLThree/Properties/AssemblyInfo.cs | 2 +- SLThree/SLThree.csproj | 2 +- SLThree/docs/versions/0.8.0 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SLThree/Properties/AssemblyInfo.cs b/SLThree/Properties/AssemblyInfo.cs index 5d454a8..8ec6527 100644 --- a/SLThree/Properties/AssemblyInfo.cs +++ b/SLThree/Properties/AssemblyInfo.cs @@ -62,7 +62,7 @@ static SLTVersion() } } - public static string Edition { get; } = "Typing Update"; + public static string Edition { get; } = "Binding&Naming Update"; public static string GetTitle() { diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index b3a9b81..293452c 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-rc.1 + 0.8.0-rc.3 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md diff --git a/SLThree/docs/versions/0.8.0 b/SLThree/docs/versions/0.8.0 index ba860bd..298648a 100644 --- a/SLThree/docs/versions/0.8.0 +++ b/SLThree/docs/versions/0.8.0 @@ -1,4 +1,4 @@ ------- 0.8.0 ------ [~.~.~] +------ 0.8.0 Binding&Naming Update ------ [~.~.~] Language: - New method definition syntax `[modifs][Name][](args) {...}` From 59e935e1b17065191421e6215b84c2d1fd0d1799 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Tue, 18 Jun 2024 22:51:04 +0300 Subject: [PATCH 54/69] using expr to string --- SLThree/Expressions/UsingExpression.cs | 2 +- SLThree/SLThree.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SLThree/Expressions/UsingExpression.cs b/SLThree/Expressions/UsingExpression.cs index ad4d17f..d725b6b 100644 --- a/SLThree/Expressions/UsingExpression.cs +++ b/SLThree/Expressions/UsingExpression.cs @@ -20,7 +20,7 @@ public UsingExpression(BaseExpression alias, CreatorUsing usingBody, SourceConte public UsingExpression(CreatorUsing @using, SourceContext context) : this(null, @using, context) { } - public override string ExpressionToString() => $"using {Using.Type} as {Alias}"; + public override string ExpressionToString() => $"using {Using.Type}{(Alias == null ? "" : $" as {Alias}")}"; public override object GetValue(ExecutionContext context) { diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 293452c..2924fa6 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-rc.3 + 0.8.0-rc.4 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md From 88f1d7aada49ae0d196f45f617a816f563035cf2 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Wed, 19 Jun 2024 11:09:23 +0300 Subject: [PATCH 55/69] abstract methods --- SLThree/Expressions/FunctionDefinition.cs | 9 +++++++++ SLThree/syntax.peg | 17 +++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/SLThree/Expressions/FunctionDefinition.cs b/SLThree/Expressions/FunctionDefinition.cs index 11e7cd9..e71273b 100644 --- a/SLThree/Expressions/FunctionDefinition.cs +++ b/SLThree/Expressions/FunctionDefinition.cs @@ -40,6 +40,15 @@ public FunctionDefinition(string[] modificators, BaseExpression name, NameExpres ReturnTypeHint = typehint; var many = Modificators.GroupBy(x => x).FirstOrDefault(x => x.Count() > 1); if (many != null) throw new SyntaxError($"Repeated modifier \"{many.First()}\"", context); + if (FunctionBody == null) + { + if (Modificators.Contains("abstract")) + { + FunctionBody = new StatementList(new BaseStatement[] { new ThrowStatement(new StaticExpression(new RuntimeError("You cannot call an abstract method", null)), context) }, context); + } + else throw new LogicalError("Abstract method without abstract modifier", context); + } + else if (Modificators.Contains("abstract")) throw new LogicalError("An abstract method shouldn't have a body", context); if (Method == null) { diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index c8e08a1..5ba98fc 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -478,7 +478,8 @@ using = t_name:typename { new CreatorUsing(t_name, state) } method_definition_expression - = method_definition_statement1 + = abstract_method_expression + / method_definition_statement1 / mods_name:method_mods_name? generics:method_generic_part? "(" _ args:arg_name<0,,"," _> _ ")" @@ -495,10 +496,21 @@ method_definition_expression new FunctionDefinition(new string[0], null, GetOptional(generics)?.ToArray() ?? new NameExpression[0], new NameExpression[1] {arg}, GetListStatement(new ReturnStatement(value, state)), GetOptional(ret), state) } method_definition_statement - = method_definition_statement1 + = abstract_method_statement + / method_definition_statement1 / method_definition_statement2 / method_definition_statement3 +abstract_method_statement = func:abstract_method_expression _ ";" { func } +abstract_method_expression + = "abstract" _required_ + name:withoutinvokation_primary _ + generics:method_generic_part? + "(" _ args:func_arg<0,,"," _> _ ")" + ret:( _ ":" _ t:typename {t})? + { + new FunctionDefinition(new string[1] { "abstract" }, name, GetOptional(generics)?.ToArray() ?? new NameExpression[0], args.ToArray(), null, GetOptional(ret), state) + } method_definition_statement1 = mods_name:method_mods_name? generics:method_generic_part? @@ -542,6 +554,7 @@ method_mods_name > method_modificator = "recursive" / "explicit" + / "abstract" / "native" typename From a779b027b0996d75d4a83d8921d1f23c7cc4fed7 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Wed, 19 Jun 2024 11:09:50 +0300 Subject: [PATCH 56/69] arificial statics --- SLThree/Expressions/StaticExpression.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/SLThree/Expressions/StaticExpression.cs b/SLThree/Expressions/StaticExpression.cs index 6d7aa95..bb2cfd7 100644 --- a/SLThree/Expressions/StaticExpression.cs +++ b/SLThree/Expressions/StaticExpression.cs @@ -6,15 +6,22 @@ public class StaticExpression : BaseExpression { public BaseExpression Right; + public StaticExpression(object obj) : base(new SourceContext()) + { + artificial = true; + this.obj = obj; + done = true; + } public StaticExpression(BaseExpression right, SourceContext context) : base(context) { Right = right; } - public override string ExpressionToString() => $"static {Right}"; + public override string ExpressionToString() => $"static {Right ?? obj}"; private bool done; private object obj; + private bool artificial; public override object GetValue(ExecutionContext context) { @@ -25,7 +32,7 @@ public override object GetValue(ExecutionContext context) public override object Clone() { - return new StaticExpression(Right.CloneCast(), SourceContext.CloneCast()); + return artificial ? new StaticExpression(obj) : new StaticExpression(Right.CloneCast(), SourceContext.CloneCast()); } } } From 4a8a0fb5ddb531f334812ccc7699ae072850188f Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Wed, 19 Jun 2024 16:33:30 +0300 Subject: [PATCH 57/69] context implementation, abstract methods --- SLThree/ExecutionContext.cs | 26 +++++++++++++++++-- .../Expressions/Creators/CreatorContext.cs | 2 +- SLThree/Expressions/FunctionDefinition.cs | 2 +- SLThree/Expressions/InvokeExpression.cs | 2 +- SLThree/Parser.cs | 14 ++++++++++ SLThree/SLThree.csproj | 2 +- .../docs/SLThree_Notepad++_highlighting.xml | 2 +- SLThree/docs/versions/0.8.0 | 5 ++-- SLThree/syntax.peg | 6 ++--- 9 files changed, 49 insertions(+), 12 deletions(-) diff --git a/SLThree/ExecutionContext.cs b/SLThree/ExecutionContext.cs index 2ae9d27..1442a4c 100644 --- a/SLThree/ExecutionContext.cs +++ b/SLThree/ExecutionContext.cs @@ -116,9 +116,9 @@ public void DefaultEnvironment() } - public ExecutionContext CreateInstance(Method constructor, object[] args) + public ExecutionContext CreateInstance(ExecutionContext definitioncontext, Method constructor, object[] args) { - var ret = new ExecutionContext(super.Context); + var ret = new ExecutionContext(definitioncontext); ret.Name = $"{Name}@{Convert.ToString(Creations++, 16).ToUpper().PadLeft(4, '0')}"; ret.parent = wrap; constructor.@this = ret.wrap; @@ -164,6 +164,28 @@ internal ExecutionContext copy(ExecutionContext context) // @private.Context.LocalVariables.FillOther(context.@private.Context.LocalVariables); return this; } + + public static object virtualize(object o, ExecutionContext context) + { + if (o is Method method) + { + method = method.CloneWithNewName(method.Name); + method.identity(context.wrap); + return method; + } + return o; + } + + internal ExecutionContext implement(ExecutionContext context) + { + var vars = context.LocalVariables.Variables; + foreach (var x in context.LocalVariables.NamedIdentificators) + { + var o = vars[x.Value]; + LocalVariables.SetValue(x.Key, virtualize(o, this)); + } + return this; + } } #pragma warning restore IDE1006 // Стили именования } diff --git a/SLThree/Expressions/Creators/CreatorContext.cs b/SLThree/Expressions/Creators/CreatorContext.cs index f3e8b89..8b025f2 100644 --- a/SLThree/Expressions/Creators/CreatorContext.cs +++ b/SLThree/Expressions/Creators/CreatorContext.cs @@ -69,7 +69,7 @@ public object GetValue(ExecutionContext target, ExecutionContext context) { var ret = new ExecutionContext(target); for (var i = 0; i < Ancestors.Length; i++) - ret.copy(Ancestors[i].GetValue(target).Cast().Context); + ret.implement(Ancestors[i].GetValue(target).Cast().Context); CreatorBody?.GetValue(ret, context); var wrap = ret.wrap; if (HasName) diff --git a/SLThree/Expressions/FunctionDefinition.cs b/SLThree/Expressions/FunctionDefinition.cs index e71273b..242db2d 100644 --- a/SLThree/Expressions/FunctionDefinition.cs +++ b/SLThree/Expressions/FunctionDefinition.cs @@ -48,7 +48,7 @@ public FunctionDefinition(string[] modificators, BaseExpression name, NameExpres } else throw new LogicalError("Abstract method without abstract modifier", context); } - else if (Modificators.Contains("abstract")) throw new LogicalError("An abstract method shouldn't have a body", context); + else if (Modificators.Contains("abstract") && !(FunctionBody.Statements.FirstOrDefault() is ThrowStatement)) throw new LogicalError("An abstract method shouldn't have a body", context); if (Method == null) { diff --git a/SLThree/Expressions/InvokeExpression.cs b/SLThree/Expressions/InvokeExpression.cs index cb983ae..22e3fed 100644 --- a/SLThree/Expressions/InvokeExpression.cs +++ b/SLThree/Expressions/InvokeExpression.cs @@ -46,7 +46,7 @@ public object InvokeForObj(ExecutionContext context, object[] args, object o) if (wrap.Context.LocalVariables.GetValue("constructor").Item1 is Method constructor) { if (constructor.ParamNames.Length != args.Length) throw new RuntimeError("Call constructor with wrong arguments count", SourceContext); - return wrap.Context.CreateInstance(constructor, args).wrap; + return wrap.Context.CreateInstance(context, constructor, args).wrap; } } else if (o is MethodInfo mi) diff --git a/SLThree/Parser.cs b/SLThree/Parser.cs index 43b89fd..9908172 100644 --- a/SLThree/Parser.cs +++ b/SLThree/Parser.cs @@ -1,5 +1,6 @@ using SLThree.Extensions; using SLThree.Visitors; +using System; using System.Collections.Generic; using System.Linq; @@ -103,6 +104,19 @@ private static BaseExpression InjectFirst(BaseExpression left, BaseExpression ri return right; } + private static BaseExpression ReorderStatic(StaticExpression expression) + { + var ret = expression; + if (ret.Right is BinaryAssign) + { + var left = ret.Right; + while (left is BinaryAssign assign) + left = assign.Right; + + } + throw new NotImplementedException(); + } + private static T Panic(SLTException exception) { throw exception; diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 2924fa6..6dd9691 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-rc.4 + 0.8.0-rc.14 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md diff --git a/SLThree/docs/SLThree_Notepad++_highlighting.xml b/SLThree/docs/SLThree_Notepad++_highlighting.xml index 77992f4..0ae5584 100644 --- a/SLThree/docs/SLThree_Notepad++_highlighting.xml +++ b/SLThree/docs/SLThree_Notepad++_highlighting.xml @@ -24,7 +24,7 @@ - new as is true false null using context self this global upper super private recursive explicit static constructor + new as is true false null using context self this global upper super private recursive explicit static constructor abstract u8 i8 u16 i16 u32 i32 u64 i64 f64 f32 string bool any char list dict tuple while return break continue if else foreach in try catch finally match throw \n \t \r \\\ diff --git a/SLThree/docs/versions/0.8.0 b/SLThree/docs/versions/0.8.0 index 298648a..c240287 100644 --- a/SLThree/docs/versions/0.8.0 +++ b/SLThree/docs/versions/0.8.0 @@ -3,7 +3,7 @@ Language: - New method definition syntax `[modifs][Name][](args) {...}` `[modifs][Name][](args) => value` - - You can now copy contexts with ":" in the following cases: + - You can now implements contexts with ":" in the following cases: - New initializers: // [] - optional `new T [Name][: Ancestors][{...}]` - New context creators: @@ -16,9 +16,10 @@ Language: `T1 = TBase(5); T2 = TBase(10);` - The right side of the nested context initializer assignations now always refers to the self context - `x = 1; context A { context B { x = x; }}` + `x = 1; context A { context B { x = x; }}` - Parent keyword in constructed contexts `T1.parent == TBase;` + - Abstract methods (withoud body) - Static expression (will be executed only once) `static x` - Condition statement is now expression - Using statement is now expression diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index 5ba98fc..6620683 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -471,8 +471,8 @@ access_right -memoize / right:name { right } onlyname_access -memoize - = left:name _ conditional:"?"? _ "." _ right:onlyname_access { new MemberAccess(left, right, conditional.Count == 1, state) } - / right:name { right } + = left:special _ conditional:"?"? _ "." _ right:onlyname_access { new MemberAccess(left, right, conditional.Count == 1, state) } + / right:special { right } using = t_name:typename { new CreatorUsing(t_name, state) } @@ -506,7 +506,7 @@ abstract_method_expression = "abstract" _required_ name:withoutinvokation_primary _ generics:method_generic_part? - "(" _ args:func_arg<0,,"," _> _ ")" + "(" _ args:arg_name<0,,"," _> _ ")" ret:( _ ":" _ t:typename {t})? { new FunctionDefinition(new string[1] { "abstract" }, name, GetOptional(generics)?.ToArray() ?? new NameExpression[0], args.ToArray(), null, GetOptional(ret), state) From 6030e6a73b7ef7f89fcfee18e22e253cbd140ec3 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Wed, 19 Jun 2024 18:24:07 +0300 Subject: [PATCH 58/69] static reorder --- SLThree/Parser.cs | 107 +++++++++++++++++++++++++++++++++++++---- SLThree/SLThree.csproj | 2 +- SLThree/syntax.peg | 6 +-- 3 files changed, 102 insertions(+), 13 deletions(-) diff --git a/SLThree/Parser.cs b/SLThree/Parser.cs index 9908172..df4ee5f 100644 --- a/SLThree/Parser.cs +++ b/SLThree/Parser.cs @@ -1,4 +1,5 @@ using SLThree.Extensions; +using SLThree.Extensions.Cloning; using SLThree.Visitors; using System; using System.Collections.Generic; @@ -10,14 +11,22 @@ public partial class Parser { public static readonly Parser This = new Parser(); - public BaseExpression ParseExpression(string s) => this.Parse("#EXPR# " + s).Cast().Expression; + public BaseExpression ParseExpression(string s) + { + var ret = this.Parse("#EXPR# " + s).Cast().Expression; + return ret; + } public object EvalExpression(string s, ExecutionContext context = null) { if (context == null) context = new ExecutionContext(); return ParseExpression(s).GetValue(context); } - public BaseStatement ParseScript(string s, string filename = null) => this.Parse("#SLT# " + s, filename); + public BaseStatement ParseScript(string s, string filename = null) + { + var ret = this.Parse("#SLT# " + s, filename); + return ret; + } public ExecutionContext RunScript(string s, string filename = null, ExecutionContext context = null) { var parsed = ParseScript(s, filename); @@ -104,17 +113,97 @@ private static BaseExpression InjectFirst(BaseExpression left, BaseExpression ri return right; } - private static BaseExpression ReorderStatic(StaticExpression expression) + private sealed class VFirst: AbstractVisitor where T: class, ExecutionContext.IExecutable { - var ret = expression; - if (ret.Right is BinaryAssign) + public T Found = null; + public Func Predicate = x => true; + + public override void VisitExpression(BaseExpression expression) { - var left = ret.Right; - while (left is BinaryAssign assign) - left = assign.Right; + if (expression is T t && Predicate(t)) + { + Found = t; + return; + } + base.VisitExpression(expression); + } + public override void VisitStatement(BaseStatement statement) + { + if (statement is T t && Predicate(t)) + { + Found = t; + return; + } + base.VisitStatement(statement); + } + } + private static bool Any(object o) where T : class, ExecutionContext.IExecutable + { + var has = new VFirst(); + has.VisitAny(o); + return has.Found != null; + } + private static bool Any(object o, out T ret) where T : class, ExecutionContext.IExecutable + { + var has = new VFirst(); + has.VisitAny(o); + ret = has.Found; + return ret != null; + } + private static bool Any(object o, Func predicate) where T : class, ExecutionContext.IExecutable + { + var has = new VFirst(); + has.Predicate = predicate; + has.VisitAny(o); + return has.Found != null; + } + private static bool Any(object o, Func predicate, out T ret) where T : class, ExecutionContext.IExecutable + { + var has = new VFirst(); + has.Predicate = predicate; + has.VisitAny(o); + ret = has.Found; + return has.Found != null; + } + public static void UncachebleCheck(object o, string suffix = " after static") + { + if (Any(o, out var wrongassign)) + throw new LogicalError($"Unexpected assign {wrongassign}{suffix}", wrongassign.SourceContext); + if (Any(o, func => func.FunctionName != null, out var wrongmethod)) + throw new LogicalError($"Unexpected named method{suffix}", wrongmethod.SourceContext); + if (Any(o, context => context.Name != null, out var wrongcontext)) + throw new LogicalError($"Unexpected named context{suffix}", wrongassign.SourceContext); + if (Any(o, instance => instance.Name != null, out var wronginstance)) + throw new LogicalError($"Unexpected named instance{suffix}", wronginstance.SourceContext); + } + private BaseExpression ReorderStatic(StaticExpression expression) + { + //if (did.TryGetValue(expression, out var expr)) return expr; + if (expression.Right is BinaryAssign) + { + var input = expression.CloneCast(); + var left = input.Right as BinaryAssign; + while (left is BinaryAssign assign && assign.Right is BinaryAssign) + left = assign.Right as BinaryAssign; + UncachebleCheck(left.Right); + var ret = input.Right; + input.Right = left.Right; + left.Right = input; + return ret; } - throw new NotImplementedException(); + if (expression.Right is CreatorContext context && context.HasName) + return new BinaryAssign(context.Name.CloneCast(), expression, context.SourceContext); + if (expression.Right is CreatorInstance instance && instance.Name != null) + return new BinaryAssign(instance.Name.CloneCast(), expression, instance.SourceContext); + return ReorderStaticMethod(expression); + } + private BaseExpression ReorderStaticMethod(StaticExpression expression) + { + if (expression.Right is FunctionDefinition func && func.FunctionName != null) + return new BinaryAssign(func.FunctionName.CloneCast(), expression, expression.Right.SourceContext); + UncachebleCheck(expression.Right); + return expression; } private static T Panic(SLTException exception) diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 6dd9691..4f370dd 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-rc.14 + 0.8.0-rc.46 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index 6620683..fe79a02 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -23,8 +23,8 @@ statement / e:match_expression { new ExpressionStatement(e, state) } / e:context_expression { new ExpressionStatement(e, state) } / e:block_instance_expression { new ExpressionStatement(e, state) } - / "static" _required_ e:method_definition_statement { new ExpressionStatement(new StaticExpression(e, state), state) } - / "static" _ e:method_definition_nswm { new ExpressionStatement(new StaticExpression(e, state), state) } + / "static" _required_ e:method_definition_statement { new ExpressionStatement(ReorderStaticMethod(new StaticExpression(e, state)), state) } + / "static" _ e:method_definition_nswm { new ExpressionStatement(ReorderStaticMethod(new StaticExpression(e, state)), state) } / e:method_definition_statement { new ExpressionStatement(e, state) } / expression_statement / block_statement @@ -96,8 +96,8 @@ expression binary_9 -memoize = left:keyword _ ("=" / "+=" / "-=" / "*=" / "/=" / "%=" / "&=" / "|=" / "^=") _ right:binary_9 { Panic(new SyntaxError("Keywords is not a valid name", state)) } - / "static" _required_ left:expression { new StaticExpression(left, state) } / left:binary_9 _ "|>" _ right:binary_7 { InjectFirst(left, right) } + / "static" _required_ left:expression { ReorderStatic(new StaticExpression(left, state)) } / condition_expression / match_expression / method_definition_expression From 5581bdc11b222e26d41bddd001e6739c3bf4c123 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 20 Jun 2024 14:02:49 +0300 Subject: [PATCH 59/69] optimization --- SLThree/Methods/Method.cs | 7 +++++-- SLThree/docs/versions/0.8.0 | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/SLThree/Methods/Method.cs b/SLThree/Methods/Method.cs index 67157ef..d24a4ca 100644 --- a/SLThree/Methods/Method.cs +++ b/SLThree/Methods/Method.cs @@ -93,10 +93,13 @@ public virtual ExecutionContext GetExecutionContext(object[] arguments, Executio public virtual object GetValue(ExecutionContext old_context, object[] args) { var context = GetExecutionContext(args, old_context); - for (var i = 0; i < Statements.Statements.Length; i++) + var i = 0; + var bs = Statements.Statements; + var count = bs.Length; + while (i < count) { if (context.Returned) return context.ReturnedValue; - else Statements.Statements[i].GetValue(context); + else bs[i++].GetValue(context); } if (context.Returned) return context.ReturnedValue; return null; diff --git a/SLThree/docs/versions/0.8.0 b/SLThree/docs/versions/0.8.0 index c240287..d51238d 100644 --- a/SLThree/docs/versions/0.8.0 +++ b/SLThree/docs/versions/0.8.0 @@ -32,6 +32,7 @@ Language: `new context Name {...}` -> `context Name {...}` `new context {...}` -> `context {...}` Optimization: + - Executing method performance has been increased by ~10% - Wrappers refactoring, minumum 3x faster wrapping minimum 20x faster unwrapping Bugfixes: From f66638bec5855e99c7c61040bbc3ae2e648c2f4e Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 20 Jun 2024 16:39:17 +0300 Subject: [PATCH 60/69] new parsing tests --- test/parsing/char_based_interface.slt | 2 +- test/parsing/e_abstractmethod.slt | 1 + test/parsing/e_binary.slt | 1 + test/parsing/e_cast.slt | 3 ++ test/parsing/e_condition.slt | 8 ++++ test/parsing/e_cr_array.slt | 2 + test/parsing/e_cr_context.slt | 9 +++++ test/parsing/e_cr_dictionary.slt | 3 ++ test/parsing/e_cr_instance.slt | 17 ++++++++ test/parsing/e_cr_list.slt | 2 + test/parsing/e_cr_newarray.slt | 2 + test/parsing/e_cr_range.slt | 2 + test/parsing/e_cr_tuple.slt | 2 + test/parsing/e_cr_using.slt | 1 + test/parsing/e_formatstr.slt | 2 + test/parsing/e_funcdef.slt | 57 +++++++++++++++++++++++++++ test/parsing/e_invoke.slt | 7 ++++ test/parsing/e_literal.slt | 13 ++++++ test/parsing/e_match.slt | 5 +++ test/parsing/e_name.slt | 2 + test/parsing/e_reflection.slt | 2 + test/parsing/e_static.slt | 4 ++ test/parsing/e_ternary.slt | 1 + test/parsing/e_unary.slt | 1 + test/parsing/e_using.slt | 2 + test/parsing/literals.slt | 4 -- test/parsing/st_break.slt | 1 + test/parsing/st_condition.slt | 3 ++ test/parsing/st_context.slt | 4 ++ test/parsing/st_continue.slt | 1 + test/parsing/st_empty.slt | 1 + test/parsing/st_expression.slt | 4 ++ test/parsing/st_foreach.slt | 7 ++++ test/parsing/st_intance.slt | 9 +++++ test/parsing/st_return.slt | 6 +++ test/parsing/st_throw.slt | 2 + test/parsing/st_try.slt | 6 +++ test/parsing/st_while.slt | 4 ++ 38 files changed, 198 insertions(+), 5 deletions(-) create mode 100644 test/parsing/e_abstractmethod.slt create mode 100644 test/parsing/e_binary.slt create mode 100644 test/parsing/e_cast.slt create mode 100644 test/parsing/e_condition.slt create mode 100644 test/parsing/e_cr_array.slt create mode 100644 test/parsing/e_cr_context.slt create mode 100644 test/parsing/e_cr_dictionary.slt create mode 100644 test/parsing/e_cr_instance.slt create mode 100644 test/parsing/e_cr_list.slt create mode 100644 test/parsing/e_cr_newarray.slt create mode 100644 test/parsing/e_cr_range.slt create mode 100644 test/parsing/e_cr_tuple.slt create mode 100644 test/parsing/e_cr_using.slt create mode 100644 test/parsing/e_formatstr.slt create mode 100644 test/parsing/e_funcdef.slt create mode 100644 test/parsing/e_invoke.slt create mode 100644 test/parsing/e_literal.slt create mode 100644 test/parsing/e_match.slt create mode 100644 test/parsing/e_name.slt create mode 100644 test/parsing/e_reflection.slt create mode 100644 test/parsing/e_static.slt create mode 100644 test/parsing/e_ternary.slt create mode 100644 test/parsing/e_unary.slt create mode 100644 test/parsing/e_using.slt delete mode 100644 test/parsing/literals.slt create mode 100644 test/parsing/st_break.slt create mode 100644 test/parsing/st_condition.slt create mode 100644 test/parsing/st_context.slt create mode 100644 test/parsing/st_continue.slt create mode 100644 test/parsing/st_empty.slt create mode 100644 test/parsing/st_expression.slt create mode 100644 test/parsing/st_foreach.slt create mode 100644 test/parsing/st_intance.slt create mode 100644 test/parsing/st_return.slt create mode 100644 test/parsing/st_throw.slt create mode 100644 test/parsing/st_try.slt create mode 100644 test/parsing/st_while.slt diff --git a/test/parsing/char_based_interface.slt b/test/parsing/char_based_interface.slt index 9d269a1..6ac9601 100644 --- a/test/parsing/char_based_interface.slt +++ b/test/parsing/char_based_interface.slt @@ -21,7 +21,7 @@ while (true) { console.write(">>> "); input = console.readln().Trim(); match (input) { - "0" ==> { break; }; + "0" ==> break; "h" ==> out_help(); "+" ==> console.writeln($"Вывод: {global.a + global.b}"); "*" ==> console.writeln($"Вывод: {global.a * global.b}"); diff --git a/test/parsing/e_abstractmethod.slt b/test/parsing/e_abstractmethod.slt new file mode 100644 index 0000000..b1a3f69 --- /dev/null +++ b/test/parsing/e_abstractmethod.slt @@ -0,0 +1 @@ +f = abstract f(x); \ No newline at end of file diff --git a/test/parsing/e_binary.slt b/test/parsing/e_binary.slt new file mode 100644 index 0000000..9286857 --- /dev/null +++ b/test/parsing/e_binary.slt @@ -0,0 +1 @@ +2 + 2 - 2 * 2 / 2 % 2 == 2 != 2 && 2 || 2 & 2 | 2 ^ 2; \ No newline at end of file diff --git a/test/parsing/e_cast.slt b/test/parsing/e_cast.slt new file mode 100644 index 0000000..9034951 --- /dev/null +++ b/test/parsing/e_cast.slt @@ -0,0 +1,3 @@ +2 as i64; +(1, 2, 3) as tuple; +new context A as context; \ No newline at end of file diff --git a/test/parsing/e_condition.slt b/test/parsing/e_condition.slt new file mode 100644 index 0000000..ace0f81 --- /dev/null +++ b/test/parsing/e_condition.slt @@ -0,0 +1,8 @@ +x = if (true) 2 else 3; +x = if (true) { 2; } else 3; +x = if (true) 2 else { 3; }; +x = if (true) { 2; } else { 3; }; +if (true) 2 else 3; +if (true) { 2; } else 3; +if (true) 2 else { 3; }; +if (true) { 2; } else { 3; }; \ No newline at end of file diff --git a/test/parsing/e_cr_array.slt b/test/parsing/e_cr_array.slt new file mode 100644 index 0000000..3cdf913 --- /dev/null +++ b/test/parsing/e_cr_array.slt @@ -0,0 +1,2 @@ +-[1, 2, 3]; +-[,]; \ No newline at end of file diff --git a/test/parsing/e_cr_context.slt b/test/parsing/e_cr_context.slt new file mode 100644 index 0000000..f3ccea1 --- /dev/null +++ b/test/parsing/e_cr_context.slt @@ -0,0 +1,9 @@ +new context; +new context A; +new context: B; +new context A: B; + +context {}; +context A {}; +context: B {}; +context A: B {}; \ No newline at end of file diff --git a/test/parsing/e_cr_dictionary.slt b/test/parsing/e_cr_dictionary.slt new file mode 100644 index 0000000..bdb10aa --- /dev/null +++ b/test/parsing/e_cr_dictionary.slt @@ -0,0 +1,3 @@ +{}; +{2:3}; +{(new context): (new context)}; \ No newline at end of file diff --git a/test/parsing/e_cr_instance.slt b/test/parsing/e_cr_instance.slt new file mode 100644 index 0000000..ce94f00 --- /dev/null +++ b/test/parsing/e_cr_instance.slt @@ -0,0 +1,17 @@ +new T; +new T(args); +new T: A; +new T(args): A; +new T {}; +new T(args) {}; +new T: A {}; +new T(args): A {}; + +new T Name; +new T(args) Name; +new T Name: A; +new T(args) Name: A; +new T Name {}; +new T(args) Name {}; +new T Name: A {}; +new T(args) Name: A {}; \ No newline at end of file diff --git a/test/parsing/e_cr_list.slt b/test/parsing/e_cr_list.slt new file mode 100644 index 0000000..e7bfd16 --- /dev/null +++ b/test/parsing/e_cr_list.slt @@ -0,0 +1,2 @@ +[1, 2, 3]; +[,]; \ No newline at end of file diff --git a/test/parsing/e_cr_newarray.slt b/test/parsing/e_cr_newarray.slt new file mode 100644 index 0000000..b90b60c --- /dev/null +++ b/test/parsing/e_cr_newarray.slt @@ -0,0 +1,2 @@ +new T[100]; +new T[new T[10].Length]; \ No newline at end of file diff --git a/test/parsing/e_cr_range.slt b/test/parsing/e_cr_range.slt new file mode 100644 index 0000000..d36afe6 --- /dev/null +++ b/test/parsing/e_cr_range.slt @@ -0,0 +1,2 @@ +1..100; +(^1..50)..(^50..100); \ No newline at end of file diff --git a/test/parsing/e_cr_tuple.slt b/test/parsing/e_cr_tuple.slt new file mode 100644 index 0000000..6ac9796 --- /dev/null +++ b/test/parsing/e_cr_tuple.slt @@ -0,0 +1,2 @@ +(1, ) == (1, ); +(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); \ No newline at end of file diff --git a/test/parsing/e_cr_using.slt b/test/parsing/e_cr_using.slt new file mode 100644 index 0000000..638f68d --- /dev/null +++ b/test/parsing/e_cr_using.slt @@ -0,0 +1 @@ +new using linq; \ No newline at end of file diff --git a/test/parsing/e_formatstr.slt b/test/parsing/e_formatstr.slt new file mode 100644 index 0000000..b2cb853 --- /dev/null +++ b/test/parsing/e_formatstr.slt @@ -0,0 +1,2 @@ +$"{x} {a ? b : c} {2 + 3 + 4}"; +$"{$"{$"{$""}"}"}"; \ No newline at end of file diff --git a/test/parsing/e_funcdef.slt b/test/parsing/e_funcdef.slt new file mode 100644 index 0000000..1f4606e --- /dev/null +++ b/test/parsing/e_funcdef.slt @@ -0,0 +1,57 @@ +recursive explicit Name(args): Ret {}; +recursive explicit Name(args): Ret {}; +recursive explicit (args): Ret {}; +recursive explicit (args): Ret {}; +recursive explicit Name(args) {}; +recursive explicit Name(args) {}; +recursive explicit (args) {}; +recursive explicit (args) {}; +Name(args): Ret {}; +Name(args): Ret {}; +(args): Ret {}; +(args): Ret {}; +Name(args) {}; +Name(args) {}; +(args) {}; +(args) {}; +recursive explicit Name(args): Ret => { 2; }; +recursive explicit Name(args): Ret => { 2; }; +recursive explicit (args): Ret => { 2; }; +recursive explicit (args): Ret => { 2; }; +recursive explicit Name(args) => { 2; }; +recursive explicit Name(args) => { 2; }; +recursive explicit (args) => { 2; }; +recursive explicit (args) => { 2; }; +Name(args): Ret => { 2; }; +Name(args): Ret => { 2; }; +(args): Ret => { 2; }; +(args): Ret => { 2; }; +Name(args) => { 2; }; +Name(args) => { 2; }; +(args) => { 2; }; +(args) => { 2; }; +recursive explicit Name(args): Ret => 2; +recursive explicit Name(args): Ret => 2; +recursive explicit (args): Ret => 2; +recursive explicit (args): Ret => 2; +recursive explicit Name(args) => 2; +recursive explicit Name(args) => 2; +recursive explicit (args) => 2; +recursive explicit (args) => 2; +Name(args): Ret => 2; +Name(args): Ret => 2; +(args): Ret => 2; +(args): Ret => 2; +Name(args) => 2; +Name(args) => 2; +(args) => 2; +(args) => 2; + +ArgT arg: Ret => { 2; }; +ArgT arg => { 2; }; +arg: Ret => { 2; }; +arg => { 2; }; +ArgT arg: Ret => 2; +ArgT arg => 2; +arg: Ret => 2; +arg => 2; \ No newline at end of file diff --git a/test/parsing/e_invoke.slt b/test/parsing/e_invoke.slt new file mode 100644 index 0000000..8222e78 --- /dev/null +++ b/test/parsing/e_invoke.slt @@ -0,0 +1,7 @@ +x(); +x(1, 2, 3); +x(1, 2, 3)(1, 2, 3); + +x(); +x(1, 2, 3); +x(1, 2, 3)(1, 2, 3); \ No newline at end of file diff --git a/test/parsing/e_literal.slt b/test/parsing/e_literal.slt new file mode 100644 index 0000000..34981ed --- /dev/null +++ b/test/parsing/e_literal.slt @@ -0,0 +1,13 @@ +1; 1.0; + +-128i8; -32768i16; -2147483648i32; -9223372036854775808i64; + +0b11; 0b11i8; 0b11u8; +0o11; 0o11i8; 0o11u8; +0x11; 0x11i8; 0x11u8; + +1f32; 1.0f32; 1f64; 1.0f64; + +false; true; +"str"; +null; \ No newline at end of file diff --git a/test/parsing/e_match.slt b/test/parsing/e_match.slt new file mode 100644 index 0000000..c66c561 --- /dev/null +++ b/test/parsing/e_match.slt @@ -0,0 +1,5 @@ +match (1) { 1 ==> 2; () ==> 3; }; +match (match (^50%) { false ==> 1; true ==> 2; }) { + 1 ==> 2; + () ==> 3; +}; \ No newline at end of file diff --git a/test/parsing/e_name.slt b/test/parsing/e_name.slt new file mode 100644 index 0000000..b5c13eb --- /dev/null +++ b/test/parsing/e_name.slt @@ -0,0 +1,2 @@ +a; +self; this; super; upper; parent; global; private; \ No newline at end of file diff --git a/test/parsing/e_reflection.slt b/test/parsing/e_reflection.slt new file mode 100644 index 0000000..67cb875 --- /dev/null +++ b/test/parsing/e_reflection.slt @@ -0,0 +1,2 @@ +@i64; +parse = @i64::Parse(string); \ No newline at end of file diff --git a/test/parsing/e_static.slt b/test/parsing/e_static.slt new file mode 100644 index 0000000..d417d50 --- /dev/null +++ b/test/parsing/e_static.slt @@ -0,0 +1,4 @@ +static a = 2; +static f(x) => x; +static new context A; +static new T X; \ No newline at end of file diff --git a/test/parsing/e_ternary.slt b/test/parsing/e_ternary.slt new file mode 100644 index 0000000..51a6ed4 --- /dev/null +++ b/test/parsing/e_ternary.slt @@ -0,0 +1 @@ +2 == 2 ? 2 : 2; \ No newline at end of file diff --git a/test/parsing/e_unary.slt b/test/parsing/e_unary.slt new file mode 100644 index 0000000..9aeb04a --- /dev/null +++ b/test/parsing/e_unary.slt @@ -0,0 +1 @@ ++-*^50; \ No newline at end of file diff --git a/test/parsing/e_using.slt b/test/parsing/e_using.slt new file mode 100644 index 0000000..e2a7a4c --- /dev/null +++ b/test/parsing/e_using.slt @@ -0,0 +1,2 @@ +using slt; +using slt as AAA; \ No newline at end of file diff --git a/test/parsing/literals.slt b/test/parsing/literals.slt deleted file mode 100644 index 46e1805..0000000 --- a/test/parsing/literals.slt +++ /dev/null @@ -1,4 +0,0 @@ --128i8; -0b1000_1000; -0o777; -0xFF__FF__FF; \ No newline at end of file diff --git a/test/parsing/st_break.slt b/test/parsing/st_break.slt new file mode 100644 index 0000000..8cb76cf --- /dev/null +++ b/test/parsing/st_break.slt @@ -0,0 +1 @@ +break; \ No newline at end of file diff --git a/test/parsing/st_condition.slt b/test/parsing/st_condition.slt new file mode 100644 index 0000000..794c8c0 --- /dev/null +++ b/test/parsing/st_condition.slt @@ -0,0 +1,3 @@ +if (true) 2; else 3; +if (true) 2; else { 3; } +if (true) { 2; } else { 3; } \ No newline at end of file diff --git a/test/parsing/st_context.slt b/test/parsing/st_context.slt new file mode 100644 index 0000000..2bd16f4 --- /dev/null +++ b/test/parsing/st_context.slt @@ -0,0 +1,4 @@ +context {} +context A {} +context: B {} +context A: B {} \ No newline at end of file diff --git a/test/parsing/st_continue.slt b/test/parsing/st_continue.slt new file mode 100644 index 0000000..45127c0 --- /dev/null +++ b/test/parsing/st_continue.slt @@ -0,0 +1 @@ +continue; \ No newline at end of file diff --git a/test/parsing/st_empty.slt b/test/parsing/st_empty.slt new file mode 100644 index 0000000..1c8a0e7 --- /dev/null +++ b/test/parsing/st_empty.slt @@ -0,0 +1 @@ +; \ No newline at end of file diff --git a/test/parsing/st_expression.slt b/test/parsing/st_expression.slt new file mode 100644 index 0000000..e8f1808 --- /dev/null +++ b/test/parsing/st_expression.slt @@ -0,0 +1,4 @@ +{}; //dictionary +2; +1/1; +new context A; \ No newline at end of file diff --git a/test/parsing/st_foreach.slt b/test/parsing/st_foreach.slt new file mode 100644 index 0000000..2d859d4 --- /dev/null +++ b/test/parsing/st_foreach.slt @@ -0,0 +1,7 @@ +foreach (x in a) ; +foreach (x in a) { + ; +} +foreach (x in a) { + foreach (x in a) ; +} \ No newline at end of file diff --git a/test/parsing/st_intance.slt b/test/parsing/st_intance.slt new file mode 100644 index 0000000..7a2c131 --- /dev/null +++ b/test/parsing/st_intance.slt @@ -0,0 +1,9 @@ +new T {} +new T(args) {} +new T: A {} +new T(args): A {} + +new T Name {} +new T(args) Name {} +new T Name: A {} +new T(args) Name: A {} \ No newline at end of file diff --git a/test/parsing/st_return.slt b/test/parsing/st_return.slt new file mode 100644 index 0000000..0737c63 --- /dev/null +++ b/test/parsing/st_return.slt @@ -0,0 +1,6 @@ +return; +return 0xFF; +return context { + x = 2; +}; +return new T; \ No newline at end of file diff --git a/test/parsing/st_throw.slt b/test/parsing/st_throw.slt new file mode 100644 index 0000000..f598099 --- /dev/null +++ b/test/parsing/st_throw.slt @@ -0,0 +1,2 @@ +throw 2; +throw new System.Exception("234235"); \ No newline at end of file diff --git a/test/parsing/st_try.slt b/test/parsing/st_try.slt new file mode 100644 index 0000000..978d895 --- /dev/null +++ b/test/parsing/st_try.slt @@ -0,0 +1,6 @@ +try {;} catch (e) {;} finally {;} +try {;} catch (e) console.writeln(e); finally {;} +try {;} catch (e) console.writeln(e); +try {;} catch {;} finally {;} +try {;} catch {;} +try {;} \ No newline at end of file diff --git a/test/parsing/st_while.slt b/test/parsing/st_while.slt new file mode 100644 index 0000000..c07ac13 --- /dev/null +++ b/test/parsing/st_while.slt @@ -0,0 +1,4 @@ +while (true) ; +while (true) { + while (false) ; +} \ No newline at end of file From e5de2304cc3c1817ed50451619087d87c6e2e0d6 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 20 Jun 2024 16:40:34 +0300 Subject: [PATCH 61/69] abstract supporting, method.ToString --- SLThree/Exceptions/SpecificErrors.cs | 19 ++++++++++++++ SLThree/Expressions/FunctionDefinition.cs | 16 +++++++----- SLThree/Expressions/StaticExpression.cs | 3 +++ SLThree/Methods/GenericMethod.cs | 27 ++++++++++++++++++-- SLThree/Methods/Method.cs | 30 +++++++++++++++++++++-- SLThree/sys/slt.cs | 7 ++++++ 6 files changed, 92 insertions(+), 10 deletions(-) create mode 100644 SLThree/Exceptions/SpecificErrors.cs diff --git a/SLThree/Exceptions/SpecificErrors.cs b/SLThree/Exceptions/SpecificErrors.cs new file mode 100644 index 0000000..3d0d9a7 --- /dev/null +++ b/SLThree/Exceptions/SpecificErrors.cs @@ -0,0 +1,19 @@ +using System; + +namespace SLThree +{ + /// + /// Исключения во время работы программы + /// + [Serializable] + public class AbstractInvokation : RuntimeError + { + public AbstractInvokation() : base() { } + public AbstractInvokation(SourceContext context) : base(GetErrorText(), context) { } + + public static string GetErrorText() + { + return $"Trying to invoke abstract method"; + } + } +} diff --git a/SLThree/Expressions/FunctionDefinition.cs b/SLThree/Expressions/FunctionDefinition.cs index 242db2d..857b0b8 100644 --- a/SLThree/Expressions/FunctionDefinition.cs +++ b/SLThree/Expressions/FunctionDefinition.cs @@ -1,5 +1,6 @@ using SLThree.Extensions; using SLThree.Extensions.Cloning; +using SLThree.sys; using System; using System.Collections.Generic; using System.Linq; @@ -40,20 +41,22 @@ public FunctionDefinition(string[] modificators, BaseExpression name, NameExpres ReturnTypeHint = typehint; var many = Modificators.GroupBy(x => x).FirstOrDefault(x => x.Count() > 1); if (many != null) throw new SyntaxError($"Repeated modifier \"{many.First()}\"", context); + + var is_abstract = Modificators.Contains("abstract"); if (FunctionBody == null) { - if (Modificators.Contains("abstract")) + if (is_abstract) { - FunctionBody = new StatementList(new BaseStatement[] { new ThrowStatement(new StaticExpression(new RuntimeError("You cannot call an abstract method", null)), context) }, context); + FunctionBody = new StatementList(new BaseStatement[] { new ThrowStatement(new StaticExpression(new AbstractInvokation(SourceContext)), context) }, context); } else throw new LogicalError("Abstract method without abstract modifier", context); } - else if (Modificators.Contains("abstract") && !(FunctionBody.Statements.FirstOrDefault() is ThrowStatement)) throw new LogicalError("An abstract method shouldn't have a body", context); + else if (is_abstract && !slt.is_abstract(FunctionBody)) throw new LogicalError("An abstract method shouldn't have a body", context); if (Method == null) { if (GenericArguments.Length == 0) Method = new Method( - FunctionName == null ? "$method" : CreatorContext.GetLastName(FunctionName), + FunctionName == null ? Method.DefaultMethodName : CreatorContext.GetLastName(FunctionName), Arguments.Select(x => x.Name).ToArray(), FunctionBody, Arguments.Select(x => x.TypeHint).ToArray(), @@ -62,7 +65,7 @@ public FunctionDefinition(string[] modificators, BaseExpression name, NameExpres !Modificators.Contains("explicit"), Modificators.Contains("recursive")); else Method = new GenericMethod( - FunctionName == null ? "$method" : CreatorContext.GetLastName(FunctionName), + FunctionName == null ? Method.DefaultMethodName : CreatorContext.GetLastName(FunctionName), Arguments.Select(x => x.Name).ToArray(), FunctionBody, Arguments.Select(x => x.TypeHint).ToArray(), @@ -73,6 +76,7 @@ public FunctionDefinition(string[] modificators, BaseExpression name, NameExpres GenericArguments); } + Method.Abstract = is_abstract; not_native = !Modificators.Contains("native"); } @@ -130,7 +134,7 @@ public override object GetValue(ExecutionContext context) public override object Clone() { - return new FunctionDefinition(Modificators.CloneArray(), FunctionName.CloneCast(), GenericArguments.CloneArray(), Arguments.CloneArray(), FunctionBody.CloneCast(), ReturnTypeHint.CloneCast(), SourceContext.CloneCast()); + return new FunctionDefinition(Modificators.CloneArray(), FunctionName.CloneCast(), GenericArguments.CloneArray(), Arguments.CloneArray(), Modificators.Contains("abstract") ? null : FunctionBody.CloneCast(), ReturnTypeHint.CloneCast(), SourceContext.CloneCast()); } } } diff --git a/SLThree/Expressions/StaticExpression.cs b/SLThree/Expressions/StaticExpression.cs index bb2cfd7..16f0dae 100644 --- a/SLThree/Expressions/StaticExpression.cs +++ b/SLThree/Expressions/StaticExpression.cs @@ -23,6 +23,9 @@ public StaticExpression(BaseExpression right, SourceContext context) : base(cont private object obj; private bool artificial; + public bool IsArtificial => artificial; + public object Object => obj; + public override object GetValue(ExecutionContext context) { if (done) return obj; diff --git a/SLThree/Methods/GenericMethod.cs b/SLThree/Methods/GenericMethod.cs index 6117030..e9af16c 100644 --- a/SLThree/Methods/GenericMethod.cs +++ b/SLThree/Methods/GenericMethod.cs @@ -1,5 +1,6 @@ using SLThree.Extensions; using SLThree.Extensions.Cloning; +using SLThree.sys; using SLThree.Visitors; using System; using System.CodeDom; @@ -359,13 +360,35 @@ public Method MakeGenericMethod(Type[] args) } public readonly NameExpression[] Generics; - public override string ToString() => $"{DefinitionReturnType?.ToString() ?? "any"} {Name}<{Generics.JoinIntoString(", ")}>({DefinitionParamTypes.ConvertAll(x => x?.ToString() ?? "any").JoinIntoString(", ")})"; + public override string ToString() + { + var sb = new StringBuilder(); + var unnamed = Name == DefaultMethodName; + if (slt.is_abstract(Statements)) + sb.Append("abstract "); + else + { + if (Recursive) + sb.Append("recursive "); + if (!Implicit) + sb.Append("explicit "); + } + if (!unnamed) + sb.Append(Name); + sb.Append($"<{Generics.JoinIntoString(", ")}>"); + sb.Append($"({ParamTypes.ConvertAll(x => x?.ToString() ?? "any").JoinIntoString(", ")})"); + sb.Append($": {ReturnType?.ToString() ?? "any"}"); + return sb.ToString(); + } public List GenericsInfo; public override Method CloneWithNewName(string name) { - return new GenericMethod(name, ParamNames?.CloneArray(), Statements.CloneCast(), ParamTypes?.CloneArray(), ReturnType.CloneCast(), definitionplace, Implicit, Recursive, Generics.CloneArray()); + return new GenericMethod(name, ParamNames?.CloneArray(), Statements.CloneCast(), ParamTypes?.CloneArray(), ReturnType.CloneCast(), definitionplace, Implicit, Recursive, Generics.CloneArray()) + { + Abstract = Abstract + }; } } } diff --git a/SLThree/Methods/Method.cs b/SLThree/Methods/Method.cs index d24a4ca..7efdc3d 100644 --- a/SLThree/Methods/Method.cs +++ b/SLThree/Methods/Method.cs @@ -1,22 +1,27 @@ using SLThree.Extensions; using SLThree.Extensions.Cloning; +using SLThree.sys; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; +using System.Text; namespace SLThree { public class Method : ICloneable { + public const string DefaultMethodName = "$method"; + private ExecutionContext cached_context; public string Name; public readonly string[] ParamNames; public readonly StatementList Statements; public readonly bool Implicit = false; public readonly bool Recursive = false; + public bool Abstract = false; public bool Binded = false; public TypenameExpression[] ParamTypes; @@ -49,7 +54,25 @@ public Method(string name, string[] paramNames, StatementList statements, Typena internal void UpdateContextName() => contextName = $"<{Name}>methodcontext"; - public override string ToString() => $"{ReturnType?.ToString() ?? "any"} {Name}({ParamTypes.ConvertAll(x => x?.ToString() ?? "any").JoinIntoString(", ")})"; + public override string ToString() + { + var sb = new StringBuilder(); + var unnamed = Name == DefaultMethodName; + if (Abstract) + sb.Append("abstract "); + else + { + if (Recursive) + sb.Append("recursive "); + if (!Implicit) + sb.Append("explicit "); + } + if (!unnamed) + sb.Append(Name); + sb.Append($"({ParamTypes.ConvertAll(x => x?.ToString() ?? "any").JoinIntoString(", ")})"); + sb.Append($": {ReturnType?.ToString() ?? "any"}"); + return sb.ToString(); + } public virtual ExecutionContext GetExecutionContext(object[] arguments, ExecutionContext super_context = null) { @@ -233,7 +256,10 @@ public object InvokeWithContext(ExecutionContext from, object arg1, object arg2, public virtual Method CloneWithNewName(string name) { - return new Method(name, ParamNames?.CloneArray(), Statements.CloneCast(), ParamTypes?.CloneArray(), ReturnType.CloneCast(), definitionplace, Implicit, Recursive); + return new Method(name, ParamNames?.CloneArray(), Statements.CloneCast(), ParamTypes?.CloneArray(), ReturnType.CloneCast(), definitionplace, Implicit, Recursive) + { + Abstract = Abstract + }; } public virtual object Clone() diff --git a/SLThree/sys/slt.cs b/SLThree/sys/slt.cs index e398bc5..50a0a3a 100644 --- a/SLThree/sys/slt.cs +++ b/SLThree/sys/slt.cs @@ -25,6 +25,13 @@ public static class slt public static Method make_generic(GenericMethod method) => method.MakeGenericMethod(new Type[] { typeof(T1) }); public static Method make_generic(GenericMethod method) => method.MakeGenericMethod(new Type[] { typeof(T1), typeof(T2) }); public static Method make_generic(GenericMethod method) => method.MakeGenericMethod(new Type[] { typeof(T1), typeof(T2), typeof(T3) }); + internal static bool is_abstract(StatementList statement) + { + return statement.Statements.Length > 0 + && statement.Statements[0] is ThrowStatement @throw + && @throw.ThrowExpression is StaticExpression expression + && expression.IsArtificial && expression.Object is AbstractInvokation; + } public static readonly List registred; static slt() From 5f34a1445842bbbb5f1c12beface8415d08db85b Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 20 Jun 2024 16:42:51 +0300 Subject: [PATCH 62/69] syntax update if without else will no longer be available match right part is statement now --- SLThree/Parser.cs | 8 ++++++-- SLThree/SLThree.csproj | 2 +- SLThree/syntax.peg | 31 ++++++++++++++++--------------- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/SLThree/Parser.cs b/SLThree/Parser.cs index df4ee5f..663222b 100644 --- a/SLThree/Parser.cs +++ b/SLThree/Parser.cs @@ -173,9 +173,11 @@ public static void UncachebleCheck(object o, string suffix = " after static") if (Any(o, func => func.FunctionName != null, out var wrongmethod)) throw new LogicalError($"Unexpected named method{suffix}", wrongmethod.SourceContext); if (Any(o, context => context.Name != null, out var wrongcontext)) - throw new LogicalError($"Unexpected named context{suffix}", wrongassign.SourceContext); + throw new LogicalError($"Unexpected named context{suffix}", wrongcontext.SourceContext); if (Any(o, instance => instance.Name != null, out var wronginstance)) - throw new LogicalError($"Unexpected named instance{suffix}", wronginstance.SourceContext); + throw new LogicalError($"Unexpected named instantation{suffix}", wronginstance.SourceContext); + if (Any(o, @using => @using.Alias != null, out var wrongusing)) + throw new LogicalError($"Unexpected named using{suffix}", wrongusing.SourceContext); } private BaseExpression ReorderStatic(StaticExpression expression) { @@ -196,6 +198,8 @@ private BaseExpression ReorderStatic(StaticExpression expression) return new BinaryAssign(context.Name.CloneCast(), expression, context.SourceContext); if (expression.Right is CreatorInstance instance && instance.Name != null) return new BinaryAssign(instance.Name.CloneCast(), expression, instance.SourceContext); + if (expression.Right is UsingExpression @using && @using.Alias != null) + return new BinaryAssign(@using.Alias.CloneCast(), expression, @using.SourceContext); return ReorderStaticMethod(expression); } private BaseExpression ReorderStaticMethod(StaticExpression expression) diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 4f370dd..de83256 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-rc.46 + 0.8.0-rc.112 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index fe79a02..459e118 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -204,28 +204,29 @@ using_expression } condition_statement - = "if" _ "(" _ cond:expression _ ")" _ t:statement _ "else" _ f:block_statement { new ConditionExpression(cond, GetListStatement(t), GetListStatement(f), state) } + = expr:condition_expression _ ";" { expr } + / "if" _ "(" _ cond:expression _ ")" _ t:statement _ "else" _ f:statement { new ConditionExpression(cond, GetListStatement(t), GetListStatement(f), state) } + / condition_expression_1 / "if" _ "(" _ cond:expression _ ")" _ t:block_statement { new ConditionExpression(cond, GetListStatement(t), new StatementList(new BaseStatement[0], state), state) } / "if" _ "(" _ ")" _ block_statement? { Panic(new SyntaxError("Empty condition", state)) } condition_expression - = "if" _ "(" _ cond:expression _ ")" _ t:expression_as_statement _ "else" _ f:expression_as_statement { new ConditionExpression(cond, GetListStatement(t), GetListStatement(f), state) } - / "if" _ "(" _ cond:expression _ ")" _ t:expression_as_statement { new ConditionExpression(cond, GetListStatement(t), new StatementList(new BaseStatement[0], state), state) } + = condition_expression_1 / "if" _ "(" _ ")" _ statement? { Panic(new SyntaxError("Empty condition", state)) } +condition_expression_1 + = "if" _ "(" _ cond:expression _ ")" _ t:expression_as_statement _ "else" _ f:expression_as_statement { new ConditionExpression(cond, GetListStatement(t), GetListStatement(f), state) } + match_expression = "match" _ "(" _ expr:expression _ ")" _ "{" _ - matches:match_node<1,,";" _> + matches:match_node<1,,_> _ ";"? _ "}" { new MatchExpression(expr, matches, state) } match_node , BaseStatement>> = left:(>"(" _ ")" { null } / exprs:expression<1,,"," _> { exprs }) - _ "==>" _ right:( - - expr:expression { new ExpressionStatement(expr, state) } - / block_statement - ) { new ValueTuple, BaseStatement>(left, right) } + _ "==>" _ right:statement + { new ValueTuple, BaseStatement>(left, right) } withoutinvokation_primary -memoize = left:withoutinvokation_primary _ "." _ "?" _ "[" _ args:expression<1,,"," _> _ "]" { new IndexExpression(left, args.ToArray(), true, state) } @@ -478,8 +479,7 @@ using = t_name:typename { new CreatorUsing(t_name, state) } method_definition_expression - = abstract_method_expression - / method_definition_statement1 + = method_definition_statement1 / mods_name:method_mods_name? generics:method_generic_part? "(" _ args:arg_name<0,,"," _> _ ")" @@ -495,11 +495,12 @@ method_definition_expression { new FunctionDefinition(new string[0], null, GetOptional(generics)?.ToArray() ?? new NameExpression[0], new NameExpression[1] {arg}, GetListStatement(new ReturnStatement(value, state)), GetOptional(ret), state) } + / abstract_method_expression method_definition_statement - = abstract_method_statement - / method_definition_statement1 + = method_definition_statement1 / method_definition_statement2 / method_definition_statement3 + / abstract_method_statement abstract_method_statement = func:abstract_method_expression _ ";" { func } abstract_method_expression @@ -552,9 +553,9 @@ method_mods_name > / name:withoutinvokation_primary _ { new Tuple(new string[0], name) } method_modificator - = "recursive" + = "abstract" + / "recursive" / "explicit" - / "abstract" / "native" typename From 4356e2502065a3b24608e4a017a7705e5be0f69c Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 20 Jun 2024 16:51:28 +0300 Subject: [PATCH 63/69] examples update --- SLThree/SLThree.csproj | 2 +- examples/char_based_interface.slt | 38 ++++++++++++------------------- examples/get_system_types.slt | 9 +++++--- examples/recursive_fibonacci.slt | 2 +- test/parsing/get_system_types.slt | 3 --- 5 files changed, 23 insertions(+), 31 deletions(-) delete mode 100644 test/parsing/get_system_types.slt diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index de83256..5f1a5d2 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-rc.112 + 0.8.0-rc.113 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md diff --git a/examples/char_based_interface.slt b/examples/char_based_interface.slt index 3f2df76..6ac9601 100644 --- a/examples/char_based_interface.slt +++ b/examples/char_based_interface.slt @@ -2,39 +2,31 @@ out_help = () => { using console; console.writeln("0 - Выйти"); console.writeln("h - Вывести ещё раз"); - console.writeln("? - Вывести применённый оператор к a и b"); + console.writeln("+ - Вывести a + b"); + console.writeln("* - Вывести a * b"); + console.writeln("% - Вывести a % b"); console.writeln($"a - Заполнить a (Сейчас: {global.a})"); console.writeln($"b - Заполнить b (Сейчас: {global.b})"); }; read = str => { - using slt; using console; console.write(str); - try { - return slt.eval(console.readln()); - } - catch (err) return err.GetType().Name; + return console.readln().Trim() as i64; }; using console; -using slt; -(global.a, global.b) = (228, 666); +global.a = global.b = 2; out_help(); -while (true) -{ +while (true) { console.write(">>> "); input = console.readln().Trim(); - switch (input) - { - case "0": - break; - case "h": - out_help(); - case "a": - global.a = read("Введите a: "); - case "b": - global.b = read("Введите b: "); - } - if (input.Length == 1 && "+-/*".Contains(input)) - console.writeln($"Вывод: {slt.eval($"global.a {input} global.b")}"); + match (input) { + "0" ==> break; + "h" ==> out_help(); + "+" ==> console.writeln($"Вывод: {global.a + global.b}"); + "*" ==> console.writeln($"Вывод: {global.a * global.b}"); + "%" ==> console.writeln($"Вывод: {global.a % global.b}"); + "a" ==> global.a = read("Введите a: "); + "b" ==> global.b = read("Введите b: "); + }; } \ No newline at end of file diff --git a/examples/get_system_types.slt b/examples/get_system_types.slt index 99a3215..5bf8099 100644 --- a/examples/get_system_types.slt +++ b/examples/get_system_types.slt @@ -1,3 +1,6 @@ -using slt; -using linq; -sly.sys_types.Keys |> linq.jts("\n"); \ No newline at end of file +(using linq).jts( + linq.to_enumerable( + (using slt).sys_types + ), + "\n" +); \ No newline at end of file diff --git a/examples/recursive_fibonacci.slt b/examples/recursive_fibonacci.slt index a977e2b..1fd393f 100644 --- a/examples/recursive_fibonacci.slt +++ b/examples/recursive_fibonacci.slt @@ -1,3 +1,3 @@ -fib = (new context { fib = recursive (n) => (n < 2) ? n : this.fib(n - 2) + this.fib(n - 1); }.fib); +fib = (context { fib = recursive (n) => (n < 2) ? n : this.fib(n - 2) + this.fib(n - 1); }.fib); using linq; 1..20 |> linq.select(fib) |> linq.jts(); \ No newline at end of file diff --git a/test/parsing/get_system_types.slt b/test/parsing/get_system_types.slt deleted file mode 100644 index 30d5036..0000000 --- a/test/parsing/get_system_types.slt +++ /dev/null @@ -1,3 +0,0 @@ -using SLThree.UsingStatement; -using linq; -linq.jts(UsingStatement.SystemTypes.Keys, "\n"); \ No newline at end of file From c06d0d0d84a6f07595ba5d57bfd7f4e3935e8a3f Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Fri, 21 Jun 2024 00:16:20 +0300 Subject: [PATCH 64/69] AssertThrow --- TestSuite/Program.cs | 57 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/TestSuite/Program.cs b/TestSuite/Program.cs index bd8bba8..4672ca5 100644 --- a/TestSuite/Program.cs +++ b/TestSuite/Program.cs @@ -1,5 +1,6 @@ using SLThree; using SLThree.Extensions; +using SLThree.sys; using System; using System.Collections.Generic; using System.IO; @@ -11,6 +12,7 @@ public static class Program { public static List ErrorLog = new List(); + private static bool global_assert = true; private static bool current_assert = true; private static int current_assert_id = 1; public static void Log(object o) @@ -51,6 +53,53 @@ public static void Assert(ContextWrap context, BaseExpression expression) ErrorLog.Add($"FAILED {expression} as {expression.SourceContext} ===> {e}"); } } + public static void AssertThrow(ContextWrap context, BaseExpression sc, Type type, string val) + { + try + { + Console.ForegroundColor = ConsoleColor.White; + Console.Write(""); + Console.Write($"{current_assert_id++,6} "); + var expression = slt.parse_expr(val); + expression.GetValue(context.Context); + current_assert = false; + Console.ForegroundColor = ConsoleColor.Red; + Console.Write($" FAILED "); + Console.ForegroundColor = ConsoleColor.Red; + Console.Write($" [NO]"); + Console.ForegroundColor = ConsoleColor.Magenta; + Console.Write($" at {expression.SourceContext.ToStringWithoutFile()} "); + Console.ForegroundColor = ConsoleColor.Cyan; + Console.WriteLine($"{expression}"); + ErrorLog.Add($"FAILED {expression} as {expression.SourceContext} ===> {type} not thrown"); + } + catch (Exception e) + { + if (SLTHelpers.IsType(type, e.GetType())) + { + Console.ForegroundColor = ConsoleColor.Green; + Console.Write($"SUCCESS "); + Console.ForegroundColor = ConsoleColor.Green; + Console.Write($" [{type.Name}]"); + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine($" {val} "); + Console.ForegroundColor = ConsoleColor.White; + } + else + { + current_assert = false; + Console.ForegroundColor = ConsoleColor.Red; + Console.Write($" FAILED "); + Console.ForegroundColor = ConsoleColor.Red; + Console.Write($" [{e.GetType().Name}]"); + Console.ForegroundColor = ConsoleColor.Magenta; + Console.Write($" at {sc.SourceContext.ToStringWithoutFile()} "); + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine($"{val}"); + ErrorLog.Add($"FAILED {val} as {sc.SourceContext} ===> another exception thrown\n{e}"); + } + } + } public static bool ParseTest(string filename) { @@ -61,11 +110,13 @@ public static bool ParseTest(string filename) } catch (SLTException e) { + global_assert = false; ErrorLog.Add(e.ToString()); return false; } catch (Exception e) { + global_assert = false; ErrorLog.Add($"with {filename}: "); ErrorLog.Add(e.ToString()); return false; @@ -80,6 +131,7 @@ public static bool ExecTest(string filename) { var context = new ExecutionContext(); context.LocalVariables.SetValue("ASSERT", ((Action)Assert).Method); + context.LocalVariables.SetValue("ASSERT_THROW", ((Action)AssertThrow).Method); context.LocalVariables.SetValue("PATH", ((Func)GetPath).Method); context.LocalVariables.SetValue("LOG", ((Action)Log).Method); @@ -88,11 +140,13 @@ public static bool ExecTest(string filename) } catch (SLTException e) { + global_assert = false; ErrorLog.Add(e.ToString()); return false; } catch (Exception e) { + global_assert = false; ErrorLog.Add($"with {filename}: "); ErrorLog.Add(e.ToString()); return false; @@ -165,8 +219,7 @@ public static int Main(string[] args) ParsingTests(); ExecutingTests(); File.WriteAllLines("testsuite.log", ErrorLog.ToArray()); - if (ErrorLog.Count > 0) return 1; - else return 0; + return global_assert ? 0 : 1; } } } From 1be18559d294c557fba590fbdd36f7e797c6b351 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Fri, 21 Jun 2024 00:16:34 +0300 Subject: [PATCH 65/69] more tests --- SLThree/SLThree.csproj | 2 +- test/executing/0.8/context.slt | 29 ++ test/executing/0.8/funcdef.slt | 502 ++++++++++++++++++++++++++++++++ test/executing/0.8/instance.slt | 35 +++ test/executing/0.8/static.slt | 8 + test/executing/0.8/using.slt | 2 + 6 files changed, 577 insertions(+), 1 deletion(-) create mode 100644 test/executing/0.8/context.slt create mode 100644 test/executing/0.8/funcdef.slt create mode 100644 test/executing/0.8/instance.slt create mode 100644 test/executing/0.8/static.slt create mode 100644 test/executing/0.8/using.slt diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 5f1a5d2..1157a9d 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-rc.113 + 0.8.0-rc.123 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) README.md diff --git a/test/executing/0.8/context.slt b/test/executing/0.8/context.slt new file mode 100644 index 0000000..7b81cfb --- /dev/null +++ b/test/executing/0.8/context.slt @@ -0,0 +1,29 @@ +ISDNAME(context c) => c.unwrap().Name.StartsWith("@"); +EQNAME(context c, string name) => c.unwrap().Name == name; + +C() => new context; +ASSERT(self, ISDNAME(C()) as is); +C() => new context A; +ASSERT(self, EQNAME(C(), "A") as is); + +C() => context A { + f(x) => 5 * x; + g(x) => 4 * x; +}; +context B: C() { + sum(x) => this.f(x) - this.g(x); +}; +ASSERT(self, (B.sum(4) == 4) as is); + +context TBase { + constructor(x) { + this.A = 5 * x; + this.B = 4 * x; + abstract this.is_rem(x); + } +}; + +context X: TBase(25) { + is_rem(x) => this.A - this.B == x; +}; +ASSERT(self, (X.is_rem(25)) as is); \ No newline at end of file diff --git a/test/executing/0.8/funcdef.slt b/test/executing/0.8/funcdef.slt new file mode 100644 index 0000000..a95a0a8 --- /dev/null +++ b/test/executing/0.8/funcdef.slt @@ -0,0 +1,502 @@ +using SLThree.Method; +GET_GENERICS(method) => method is SLThree.GenericMethod ? method.Generics.Length : 0; +IS_RET(method, retname) => retname != null ? method.ReturnType?.ToString() == retname : method.ReturnType == null; +IS_ARG(method, arg) => arg != null ? method.ParamTypes[0]?.ToString() == arg : method.ParamTypes[0] == null; +HAS_ATTR(method) => method.Recursive || !method.Implicit; +NOT_ATTR(method) => !this.HAS_ATTR(method); + +M() => recursive explicit Name(args): Ret {}; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, (M().Statements.Statements.Length == 0) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => recursive explicit Name(args): Ret {}; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, (M().Statements.Statements.Length == 0) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => recursive explicit (args): Ret {}; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, (M().Statements.Statements.Length == 0) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => recursive explicit (args): Ret {}; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, (M().Statements.Statements.Length == 0) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => recursive explicit Name(args) {}; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, (M().Statements.Statements.Length == 0) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => recursive explicit Name(args) {}; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, (M().Statements.Statements.Length == 0) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => recursive explicit (args) {}; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, (M().Statements.Statements.Length == 0) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => recursive explicit (args) {}; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, (M().Statements.Statements.Length == 0) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => Name(args): Ret {}; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, (M().Statements.Statements.Length == 0) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => Name(args): Ret {}; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, (M().Statements.Statements.Length == 0) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => (args): Ret {}; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, (M().Statements.Statements.Length == 0) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => (args): Ret {}; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, (M().Statements.Statements.Length == 0) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => Name(args) {}; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, (M().Statements.Statements.Length == 0) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => Name(args) {}; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, (M().Statements.Statements.Length == 0) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => (args) {}; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, (M().Statements.Statements.Length == 0) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => (args) {}; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, (M().Statements.Statements.Length == 0) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => recursive explicit Name(args): Ret { 2; }; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => recursive explicit Name(args): Ret { 2; }; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => recursive explicit (args): Ret { 2; }; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => recursive explicit (args): Ret { 2; }; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => recursive explicit Name(args) { 2; }; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => recursive explicit Name(args) { 2; }; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => recursive explicit (args) { 2; }; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => recursive explicit (args) { 2; }; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => Name(args): Ret { 2; }; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => Name(args): Ret { 2; }; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => (args): Ret { 2; }; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => (args): Ret { 2; }; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => Name(args) { 2; }; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => Name(args) { 2; }; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => (args) { 2; }; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => (args) { 2; }; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => recursive explicit Name(args): Ret => 2; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => recursive explicit Name(args): Ret => 2; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => recursive explicit (args): Ret => 2; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => recursive explicit (args): Ret => 2; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => recursive explicit Name(args) => 2; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => recursive explicit Name(args) => 2; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => recursive explicit (args) => 2; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => recursive explicit (args) => 2; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, HAS_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => Name(args): Ret => 2; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => Name(args): Ret => 2; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => (args): Ret => 2; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => (args): Ret => 2; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => Name(args) => 2; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => Name(args) => 2; +ASSERT(self, (M().Name == "Name") as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => (args) => 2; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 1) as is); + +M() => (args) => 2; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => ArgT arg: Ret => { 2; }; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, IS_ARG(M(), "ArgT") as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => ArgT arg => { 2; }; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, IS_ARG(M(), "ArgT") as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => arg: Ret => { 2; }; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, IS_ARG(M(), null) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => arg => { 2; }; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, IS_ARG(M(), null) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ExpressionStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => ArgT arg: Ret => 2; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, IS_ARG(M(), "ArgT") as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => ArgT arg => 2; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, IS_ARG(M(), "ArgT") as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => arg: Ret => 2; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, IS_ARG(M(), null) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), "Ret") as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); + +M() => arg => 2; +ASSERT(self, (M().Name == Method.DefaultMethodName) as is); +ASSERT(self, (M().ParamNames.Length == 1) as is); +ASSERT(self, IS_ARG(M(), null) as is); +st = M().Statements.Statements; +ASSERT(self, (st.Length == 1 && st[0] is SLThree.ReturnStatement) as is); +ASSERT(self, NOT_ATTR(M()) as is); +ASSERT(self, IS_RET(M(), null) as is); +ASSERT(self, (GET_GENERICS(M()) == 0) as is); \ No newline at end of file diff --git a/test/executing/0.8/instance.slt b/test/executing/0.8/instance.slt new file mode 100644 index 0000000..4eb27de --- /dev/null +++ b/test/executing/0.8/instance.slt @@ -0,0 +1,35 @@ +I() => new any; +ASSERT(self, (I() is any) as is); +I() => new list(0o10i32); +ASSERT(self, (I().Capacity == 0o10i32) as is); +I() => new any: (new context); +ASSERT(self, (I() is any) as is); +I() => new list(0o10i32): (new context); +ASSERT(self, (I().Capacity == 0o10i32) as is); + +I() => new any { Capacity = 5i32; }; +ASSERT(self, (I() is any) as is); +I() => new list(0o10i32) { Capacity = 5i32; }; +ASSERT(self, (I().Capacity == 5i32) as is); +I() => new any: (new context) { Capacity = 5i32; }; +ASSERT(self, (I() is any) as is); +I() => new list(0o10i32): (new context) { Capacity = 5i32; }; +ASSERT(self, (I().Capacity == 5i32) as is); + +I() => new any Name; +ASSERT(self, (I() is any) as is); +I() => new list(0o10i32) Name; +ASSERT(self, (I().Capacity == 0o10i32) as is); +I() => new any Name: (new context); +ASSERT(self, (I() is any) as is); +I() => new list(0o10i32) Name: (new context); +ASSERT(self, (I().Capacity == 0o10i32) as is); + +I() => new any Name { Capacity = 5i32; }; +ASSERT(self, (I() is any) as is); +I() => new list(0o10i32) Name { Capacity = 5i32; }; +ASSERT(self, (I().Capacity == 5i32) as is); +I() => new any Name: (new context) { Capacity = 5i32; }; +ASSERT(self, (I() is any) as is); +I() => new list(0o10i32) Name: (new context) { Capacity = 5i32; }; +ASSERT(self, (I().Capacity == 5i32) as is); \ No newline at end of file diff --git a/test/executing/0.8/static.slt b/test/executing/0.8/static.slt new file mode 100644 index 0000000..cbd0235 --- /dev/null +++ b/test/executing/0.8/static.slt @@ -0,0 +1,8 @@ +ASSERT(self, ((static x = 5) as is is SLThree.BinaryAssign) as is); +ASSERT(self, ((static x(a) => 5) as is is SLThree.BinaryAssign) as is); +ASSERT(self, ((static new context x) as is is SLThree.BinaryAssign) as is); +ASSERT(self, ((static new any x) as is is SLThree.BinaryAssign) as is); + +ASSERT_THROW(self, null as is, @SLThree.LogicalError, "static f = f(x) => 2"); +ASSERT_THROW(self, null as is, @SLThree.LogicalError, "static f = new context f"); +ASSERT_THROW(self, null as is, @SLThree.LogicalError, "static f = new any f"); \ No newline at end of file diff --git a/test/executing/0.8/using.slt b/test/executing/0.8/using.slt new file mode 100644 index 0000000..3ccdff2 --- /dev/null +++ b/test/executing/0.8/using.slt @@ -0,0 +1,2 @@ +using linq as L; +ASSERT(self, (L is SLThree.ClassAccess) as is); \ No newline at end of file From 41e115d139242d06f7b304b13faa696bce9cbc00 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Fri, 21 Jun 2024 13:48:05 +0300 Subject: [PATCH 66/69] rename .css --- SLThree.HTMLCreator/{slthree.css => slthree.css.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename SLThree.HTMLCreator/{slthree.css => slthree.css.txt} (100%) diff --git a/SLThree.HTMLCreator/slthree.css b/SLThree.HTMLCreator/slthree.css.txt similarity index 100% rename from SLThree.HTMLCreator/slthree.css rename to SLThree.HTMLCreator/slthree.css.txt From 51b882418af686a0f2ba0ef5587a6e13ec53d43b Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Fri, 21 Jun 2024 13:52:25 +0300 Subject: [PATCH 67/69] turn of REPL versioning --- README.md | 4 +++- slt/docs/versions/3.0.0 | 4 ---- slt/slt.csproj | 4 +--- 3 files changed, 4 insertions(+), 8 deletions(-) delete mode 100644 slt/docs/versions/3.0.0 diff --git a/README.md b/README.md index 6f6b718..6274fb6 100644 --- a/README.md +++ b/README.md @@ -54,9 +54,11 @@ namespace TestSLThree ### LANG and REPL compatibility +Starting from language version 0.8.0, REPL no longer supports multiple versions at once and is built for each language update. + | REPL version | LANG version | |-----------------|-----------------| -| 2.0.0 | 0.7.0+ | +| 2.0.0 | 0.7.0 | | 1.* | 0.2.0 — 0.6.0 | ### Download diff --git a/slt/docs/versions/3.0.0 b/slt/docs/versions/3.0.0 deleted file mode 100644 index 92d27e9..0000000 --- a/slt/docs/versions/3.0.0 +++ /dev/null @@ -1,4 +0,0 @@ ------- SLThree REPL 3.0.0 ------ [~.~.~] -Supporing: - - From now on, REPL will not support multiple versions - of the language. \ No newline at end of file diff --git a/slt/slt.csproj b/slt/slt.csproj index 65a71a9..56dde44 100644 --- a/slt/slt.csproj +++ b/slt/slt.csproj @@ -6,7 +6,7 @@ net471;net6.0;net7.0;net8.0 disable disable - 3.0.0-alpha + 0.0.0-alpha ..\bin slthree.ico AnyCPU @@ -20,7 +20,6 @@ - @@ -34,7 +33,6 @@ - From 763c62fb29caecbe62983ca1ceae72034880fbbe Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Fri, 21 Jun 2024 13:52:36 +0300 Subject: [PATCH 68/69] nuget readme --- SLThree/SLThree.csproj | 6 ++--- SLThree/docs/nugetreadme.md | 50 +++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 SLThree/docs/nugetreadme.md diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 1157a9d..e631171 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,9 +12,9 @@ git language;scripts;script-lang True - 0.8.0-rc.123 + 0.8.0-rc.130 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) - README.md + nugetreadme.md 4 @@ -65,7 +65,7 @@ - + True \ diff --git a/SLThree/docs/nugetreadme.md b/SLThree/docs/nugetreadme.md new file mode 100644 index 0000000..02954ab --- /dev/null +++ b/SLThree/docs/nugetreadme.md @@ -0,0 +1,50 @@ +# SLThree + +A simple and easily embedded programming language for the .NET platform. Dynamic typing, lightweight reflection, this language is convenient for describing data and behavior. + +For more information about syntax: [slt-lang.github.io](https://slt-lang.github.io) + +### Embedding +Code example for C#: + +```CSharp +using System; +using SLThree; +using SLThree.Embedding; + +namespace TestSLThree +{ + public class Program + { + public class TC + { + public int x, y; + public Method sum; + public object Sum() => sum.Invoke(x, y); + } + + public class TC2 + { + public Func sum2; + } + + static void Main(string[] args) + { + //Context.ReturnedValue method + Console.WriteLine("return 2 + 2 * 2;".RunScript().ReturnedValue); + + //Uwrapping method + var tc = "x = 3; y = 5; sum = (a, b) => a + b;".RunScript().Unwrap(); + Console.WriteLine(tc.Sum()); + + //[Experimental] Compilation: + var tc2 = "sum2 = (new using jit).opt(sum2 = (i32 x, i32 y): i32 => x + y, self).CreateDelegate(@System.Func);".RunScript().Unwrap(); + Console.WriteLine(tc2.sum2(35, 65)); + } + } +} + +``` + +### Download +[![stable](https://img.shields.io/badge/stable-0.8.0-00cc00)](https://github.com/AIexandrKotov/SLThree/releases/tag/0.8.0) \ No newline at end of file From fd301cb57cc67bc6300284330d70d18760bf5200 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Fri, 21 Jun 2024 13:54:14 +0300 Subject: [PATCH 69/69] LANG 0.8.0 --- README.md | 2 +- SLThree/SLThree.csproj | 2 +- SLThree/docs/versions/0.8.0 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6274fb6..8424ee2 100644 --- a/README.md +++ b/README.md @@ -62,4 +62,4 @@ Starting from language version 0.8.0, REPL no longer supports multiple versions | 1.* | 0.2.0 — 0.6.0 | ### Download -[![stable](https://img.shields.io/badge/REPL_stable-2.0.0-00cc00)](https://github.com/AIexandrKotov/SLThree/releases/tag/0.7.0) [![stable](https://img.shields.io/badge/LANG_exp-0.7.0-ccaa00)](https://github.com/AIexandrKotov/SLThree/releases/tag/0.7.0) \ No newline at end of file +[![stable](https://img.shields.io/badge/stable-0.8.0-00cc00)](https://github.com/AIexandrKotov/SLThree/releases/tag/0.8.0) \ No newline at end of file diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index e631171..6b0ba89 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -12,7 +12,7 @@ git language;scripts;script-lang True - 0.8.0-rc.130 + 0.8.1 $([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/docs/versions/0.8.0")) nugetreadme.md diff --git a/SLThree/docs/versions/0.8.0 b/SLThree/docs/versions/0.8.0 index d51238d..038966b 100644 --- a/SLThree/docs/versions/0.8.0 +++ b/SLThree/docs/versions/0.8.0 @@ -1,4 +1,4 @@ ------- 0.8.0 Binding&Naming Update ------ [~.~.~] +------ 0.8.0 Binding&Naming Update ------ [21.06.24] Language: - New method definition syntax `[modifs][Name][](args) {...}`