From fffcfdfce4e9be76ea180456ed73efada1b784a4 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Mon, 30 Oct 2023 13:17:08 +0300 Subject: [PATCH 01/15] Create char_based_interface.slt --- examples/char_based_interface.slt | 50 +++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 examples/char_based_interface.slt diff --git a/examples/char_based_interface.slt b/examples/char_based_interface.slt new file mode 100644 index 0000000..0442206 --- /dev/null +++ b/examples/char_based_interface.slt @@ -0,0 +1,50 @@ +out_help = () => +{ + global.println("0 - Выйти"); + global.println("h - Вывести ещё раз"); + global.println("+ - Вывести a + b"); + global.println("* - Вывести a * b"); + global.println("% - Вывести a % b"); + global.println($"a - Заполнить a (Сейчас: {self.pred.a})"); + global.println($"b - Заполнить b (Сейчас: {self.pred.b})"); +}; +read = str => +{ + global.print(str); + return global.readln().Trim() as i64; +}; + +a = b = 2; +out_help(); +while (true) +{ + global.print(">>> "); + input = global.readln().Trim(); + switch (input) + { + case "0": + break; + case "h": + out_help(); + case "+": + { + global.println($"Вывод: {a + b}"); + } + case "*": + { + global.println($"Вывод: {a * b}"); + } + case "%": + { + global.println($"Вывод: {a % b}"); + } + case "a": + { + a = read("Введите a: "); + } + case "b": + { + b = read("Введите b: "); + } + } +} \ No newline at end of file From c280383bc9c1d75b96eaed40972507511273bf53 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Tue, 31 Oct 2023 20:10:09 +0300 Subject: [PATCH 02/15] fix #25 --- SLThree/Exceptions/SLTException.cs | 3 ++ SLThree/Lexems/LambdaLexem.cs | 2 ++ SLThree/Properties/AssemblyInfo.cs | 4 +-- SLThree/SourceContext.cs | 2 +- SLThree/syntax.peg | 55 +++++++++++++----------------- 5 files changed, 32 insertions(+), 34 deletions(-) diff --git a/SLThree/Exceptions/SLTException.cs b/SLThree/Exceptions/SLTException.cs index 0abcd0b..1b2ca55 100644 --- a/SLThree/Exceptions/SLTException.cs +++ b/SLThree/Exceptions/SLTException.cs @@ -41,6 +41,9 @@ public SyntaxError() : base() { } public SyntaxError(SourceContext context) : base(context) { } public SyntaxError(string message, SourceContext context) : base(message, context) { } public SyntaxError(string message, Exception inner, SourceContext context) : base(message, inner, context) { } + public SyntaxError(Cursor cursor) : base(new SourceContext(cursor)) { } + public SyntaxError(string message, Cursor cursor) : base(message, new SourceContext(cursor)) { } + public SyntaxError(string message, Exception inner, Cursor cursor) : base(message, inner, new SourceContext(cursor)) { } } /* /// diff --git a/SLThree/Lexems/LambdaLexem.cs b/SLThree/Lexems/LambdaLexem.cs index 811e552..d45e926 100644 --- a/SLThree/Lexems/LambdaLexem.cs +++ b/SLThree/Lexems/LambdaLexem.cs @@ -15,6 +15,8 @@ public LambdaLexem(InvokeLexem invokeLexem, StatementListStatement statements, I Left = invokeLexem; Right = statements; Modificators = modificators; + var many = Modificators.GroupBy(x => x).FirstOrDefault(x => x.Count() > 1); + if (many != null) throw new SyntaxError($"Repeated modifier \"{many.First()}\"", cursor); } public override string ToString() => $"{Left} => {Right}"; diff --git a/SLThree/Properties/AssemblyInfo.cs b/SLThree/Properties/AssemblyInfo.cs index d9f628a..52f2b52 100644 --- a/SLThree/Properties/AssemblyInfo.cs +++ b/SLThree/Properties/AssemblyInfo.cs @@ -43,8 +43,8 @@ public static class SLTVersion { public const string Major = "0"; //vh public const string Minor = "2"; //vh public const string Build = "0"; //vh - public const string Revision = "592"; //vh - public const long LastUpdate = 638340102431703149; //vh + public const string Revision = "630"; //vh + public const long LastUpdate = 638343687138288653; //vh public const string Version = Major + "." + Minor + "." + Build + "." + Revision; public const string VersionWithoutRevision = Major + "." + Minor + "." + Build; diff --git a/SLThree/SourceContext.cs b/SLThree/SourceContext.cs index 701da6f..f7b15f4 100644 --- a/SLThree/SourceContext.cs +++ b/SLThree/SourceContext.cs @@ -20,6 +20,6 @@ public SourceContext(Cursor cursor) Filename = cursor.FileName; } - public override string ToString() => $"{Line}:{Column}{(string.IsNullOrEmpty(Filename) ? "" : $"in {Filename}")}"; + public override string ToString() => $"{Line}:{Column}{(string.IsNullOrEmpty(Filename) ? "" : $" in {Filename}")}"; } } diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index 12402f8..1806d0e 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -78,40 +78,31 @@ binary_4 -memoize / left:binary_3 _ "*=" _ right:binary_4 { new ExpressionBinaryAssign(left, new ExpressionBinaryMultiply(left, right, state), state) } / left:binary_3 _ "/=" _ right:binary_4 { new ExpressionBinaryAssign(left, new ExpressionBinaryDivide(left, right, state), state) } / left:binary_3 _ "%=" _ right:binary_4 { new ExpressionBinaryAssign(left, new ExpressionBinaryMod(left, right, state), state) } - / mods:method_modificator* _ "(" _ args:names_arguments_list _ ")" _ "=>" _ "{" _ st:statement_list _ "}" { - new LambdaLexem(new InvokeLexem(null, args.ToArray(), state), st, mods, state) - } - / mods:method_modificator* _ "(" _ args:names_arguments_list _ ")" _ "=>" _ st:expr_statement _ { - new LambdaLexem( - new InvokeLexem(null, args.ToArray(), state), - new StatementListStatement( - new BaseStatement[1] { new ReturnStatement(st.Lexem, state) } - , state), mods, state) - } - / mods:method_modificator* _ a:name _ "=>" _ "{" _ st:statement_list _ "}" { - new LambdaLexem(new InvokeLexem(null, new BaseLexem[1] { a }, state), st, mods, state) - } - / mods:method_modificator* _ a:name _ "=>" _ st:expr_statement _ { - new LambdaLexem( - new InvokeLexem(null, new BaseLexem[1] { a }, state), - new StatementListStatement( - new BaseStatement[1] { new ReturnStatement(st.Lexem, state) } - , state), mods, state) - } - / mods:method_modificator* _ ("(" _ ")") _ "=>" _ "{" _ st:statement_list _ "}" { - new LambdaLexem(new InvokeLexem(null, new BaseLexem[0], state), st, mods, state) - } - / mods:method_modificator* _ ("(" _ ")") _ "=>" _ st:expr_statement _ { - new LambdaLexem( - new InvokeLexem(null, new BaseLexem[0], state), - new StatementListStatement( - new BaseStatement[1] { new ReturnStatement(st.Lexem, state) } - , state), mods, state) - } + / left:lambda_left _ "=>" _ right:lambda_right _ { new LambdaLexem(new InvokeLexem(null, left.Item2, state), right, left.Item1, state) } / left:binary_3 { left } +lambda_left , BaseLexem[]>> + = mods:method_modificator_list? _ "(" _ ")" { new ValueTuple, BaseLexem[]>(mods.Count == 0 ? new string[0] : mods[0], new BaseLexem[0]) } + / mods:method_modificator_list? _ "(" _ args:names_arguments_list _ ")" { new ValueTuple, BaseLexem[]>(mods.Count == 0 ? new string[0] : mods[0], args.ToArray()) } + / mods:method_modificator_list _required_ a:name { new ValueTuple, BaseLexem[]>(mods, new BaseLexem[1] { a } ) } + / a:name { new ValueTuple, BaseLexem[]>(new string[0], new BaseLexem[1] { a } ) } + +lambda_right + = st:expr_statement { new StatementListStatement(new BaseStatement[1] { new ReturnStatement(st.Lexem, state) }, state) } + / "{" _ st:statement_list _ "}" { st } + +method_modificator_list > + = m1:method_modificator m2p:other_modificators { m2p.AddAndRet(m1) } + / m1:method_modificator { new string[1] { m1 } } + +other_modificators > + = _required_ m2p:method_modificator+ { m2p } + method_modificator - = _ s:"implicit" _ { s } + = implicit_keyword + +implicit_keyword + = s:"implicit" { s } binary_3 -memoize = left:binary_3 _ "==" _ right:binary_2 { new ExpressionBinaryEquals(left, right, state) } @@ -261,6 +252,8 @@ available_name > comment = _ "//" [^\r\n]* +_required_ = [ \t\r\n]+ + _ = [ \t\r\n]* EOF = !. / c:. #ERROR{ "Unexpected '" + c + "'" } \ No newline at end of file From 5622344fcfa21640594b999992f1e442396691cb Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Tue, 31 Oct 2023 20:13:51 +0300 Subject: [PATCH 03/15] fix #15 --- SLThree/Wrapper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SLThree/Wrapper.cs b/SLThree/Wrapper.cs index bc6b1c1..aacf743 100644 --- a/SLThree/Wrapper.cs +++ b/SLThree/Wrapper.cs @@ -167,7 +167,7 @@ public static T Unwrap(ExecutionContext context) /// /// Это свойство будет пропущено при разворачивании /// - [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = false, AllowMultiple = false)] public sealed class WrapperSkipAttribute : Attribute { public WrapperSkipAttribute() { } From 17afcfe991b4685bad518ecdb7ac057eab667e60 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Tue, 31 Oct 2023 21:51:13 +0300 Subject: [PATCH 04/15] fix #20 fix #21 --- SLThree/Embedding/EmbeddingExtensions.cs | 8 +- SLThree/Properties/AssemblyInfo.cs | 4 +- SLThree/Wrapper.cs | 194 ++++++++++++++++++++--- 3 files changed, 185 insertions(+), 21 deletions(-) diff --git a/SLThree/Embedding/EmbeddingExtensions.cs b/SLThree/Embedding/EmbeddingExtensions.cs index 2b45e49..f03f522 100644 --- a/SLThree/Embedding/EmbeddingExtensions.cs +++ b/SLThree/Embedding/EmbeddingExtensions.cs @@ -20,6 +20,12 @@ public static ExecutionContext RunScript(this ExecutionContext context, string c { return Parser.This.RunScript(code, null, context); } - public static T Unwrap(this ExecutionContext context) where T : new() => Wrapper.Unwrap(context); + public static T Unwrap(this ExecutionContext context) where T : new() => UnwrapperForInstances.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) => UnwrapperForStaticClasses.Unwrap(type, context); + public static void UnwrapStaticClass(this Type type, ExecutionContext context) => UnwrapperForStaticClasses.Unwrap(type, context); + public static ExecutionContext WrapStaticClass(this Type type) => UnwrapperForStaticClasses.Wrap(type); } } diff --git a/SLThree/Properties/AssemblyInfo.cs b/SLThree/Properties/AssemblyInfo.cs index 52f2b52..0ea2b13 100644 --- a/SLThree/Properties/AssemblyInfo.cs +++ b/SLThree/Properties/AssemblyInfo.cs @@ -43,8 +43,8 @@ public static class SLTVersion { public const string Major = "0"; //vh public const string Minor = "2"; //vh public const string Build = "0"; //vh - public const string Revision = "630"; //vh - public const long LastUpdate = 638343687138288653; //vh + public const string Revision = "634"; //vh + public const long LastUpdate = 638343734238825581; //vh public const string Version = Major + "." + Minor + "." + Build + "." + Revision; public const string VersionWithoutRevision = Major + "." + Minor + "." + Build; diff --git a/SLThree/Wrapper.cs b/SLThree/Wrapper.cs index aacf743..937a1bc 100644 --- a/SLThree/Wrapper.cs +++ b/SLThree/Wrapper.cs @@ -5,16 +5,19 @@ using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; +using System.Runtime.Remoting.Contexts; using System.Security.Claims; using System.Text; using System.Threading.Tasks; namespace SLThree { - public static class Wrapper where T : new() + public abstract class Wrapper { - private static Dictionary Properties = new Dictionary(); - private static Dictionary Fields = new Dictionary(); + protected static readonly Dictionary Properties = new Dictionary(); + protected static readonly Dictionary Fields = new Dictionary(); + protected static readonly Dictionary StaticProperties = new Dictionary(); + protected static readonly Dictionary StaticFields = new Dictionary(); private static PropertyInfo InjectClassname = null; #region Type Setting static Wrapper() @@ -24,7 +27,6 @@ static Wrapper() foreach (var property in props) { if (Attribute.IsDefined(property, typeof(WrapperSkipAttribute))) continue; - else if (property.SetMethod == null) continue; //else if (Attribute.IsDefined(property, typeof(WrappingInjectClassname))) InjectClassname = property; else Properties[property.Name] = property; } @@ -34,16 +36,24 @@ static Wrapper() 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(WrappingInjectClassname))) InjectClassname = 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; + } } + protected internal Wrapper() { } private static Type generic_list = typeof(List).GetGenericTypeDefinition(); private static Type generic_dict = typeof(Dictionary).GetGenericTypeDefinition(); private static Type type_ituple = typeof(ITuple); - /// - /// - /// - /// Пераметр NET-типа - /// Параметр BQS-типа - /// private static bool HasRecast(Type type) { if (type.IsArray) return true; @@ -64,7 +74,7 @@ private static object[] TupleToArray(ITuple tuple) ret[i] = tuple[i]; return ret; } - private static object Cast(Type type_to_cast, object o) + protected static object UnwrapCast(Type type_to_cast, object o) { if (type_to_cast.IsArray && o is object[] obj_array) { @@ -73,7 +83,7 @@ private static object Cast(Type type_to_cast, object o) if (HasRecast(gga)) { for (var i = 0; i < obj_array.Length; i++) - ret.SetValue(Cast(gga, obj_array[i]), i); + ret.SetValue(UnwrapCast(gga, obj_array[i]), i); } else { @@ -89,7 +99,7 @@ private static object Cast(Type type_to_cast, object o) if (HasRecast(gga)) { for (var i = 0; i < obj_list.Count; i++) - ret.SetValue(Cast(gga, obj_list[i]), i); + ret.SetValue(UnwrapCast(gga, obj_list[i]), i); } else { @@ -108,7 +118,7 @@ private static object Cast(Type type_to_cast, object o) if (HasRecast(gga[0])) { for (var i = 0; i < obj_list.Count; i++) - ret.Add(Cast(gga[0], obj_list[i])); + ret.Add(UnwrapCast(gga[0], obj_list[i])); } else { @@ -124,7 +134,7 @@ private static object Cast(Type type_to_cast, object o) if (HasRecast(gga[0]) || HasRecast(gga[1])) { foreach (var x in obj_dict) - ret[Cast(gga[0], x.Key)] = Cast(gga[1], x.Value); + ret[UnwrapCast(gga[0], x.Key)] = UnwrapCast(gga[1], x.Value); } else { @@ -140,7 +150,7 @@ private static object Cast(Type type_to_cast, object o) 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) => Cast(gga[0], x)).ToArray()); + var ret = type_to_cast.GetConstructor(gga).Invoke(TupleToArray(tuple).Select((x, i) => UnwrapCast(gga[0], x)).ToArray()); return ret; } else @@ -151,14 +161,162 @@ private static object Cast(Type type_to_cast, object o) } return o; } + private 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.GetInterfaces().Contains(type_ituple)) + { + //todo supporting any-size tuples + } + return o; + } #endregion + public static ExecutionContext Wrap(T obj) + { + var ret = new ExecutionContext(); + 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 static ExecutionContext WrapStatic() + { + var ret = new ExecutionContext(); + 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; + } + public static void UnwrapStatic(ExecutionContext context) + { + foreach (var name in context.LocalVariables.GetAsDictionary()) + { + 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)); + } + } + } + + public sealed class UnwrapperForStaticClasses : Wrapper + { + private static Dictionary Unwrappers = new Dictionary(); + private new readonly Dictionary StaticProperties = new Dictionary(); + private new readonly Dictionary StaticFields = new Dictionary(); + private UnwrapperForStaticClasses(Type type) + { + if (!type.IsAbstract || !type.IsSealed) throw new ArgumentException($"Type {type.Name} is not static class!"); + 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(WrappingInjectClassname))) InjectClassname = 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; + } + } + + public static ExecutionContext Wrap(Type type) + { + var ret = new ExecutionContext(); + if (!Unwrappers.ContainsKey(type)) Unwrappers.Add(type, new UnwrapperForStaticClasses(type)); + var props = Unwrappers[type].StaticProperties; + var fields = Unwrappers[type].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 static void Unwrap(Type type, ExecutionContext context) + { + if (!Unwrappers.ContainsKey(type)) Unwrappers.Add(type, new UnwrapperForStaticClasses(type)); + var props = Unwrappers[type].StaticProperties; + var fields = Unwrappers[type].StaticFields; + foreach (var name in context.LocalVariables.GetAsDictionary()) + { + 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)); + } + } + } + + public abstract class UnwrapperForInstances : Wrapper where T: new() + { + private UnwrapperForInstances() { } public static T Unwrap(ExecutionContext context) { var ret = new T(); foreach (var name in context.LocalVariables.GetAsDictionary()) { - if (Properties.ContainsKey(name.Key)) Properties[name.Key].SetValue(ret, Cast(Properties[name.Key].PropertyType, name.Value)); - else if (Fields.ContainsKey(name.Key)) Fields[name.Key].SetValue(ret, Cast(Fields[name.Key].FieldType, name.Value)); + 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)); } return ret; } From bb5daa55492fae45d6acdf5023be3ca1cdaeddae Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Wed, 1 Nov 2023 00:21:49 +0300 Subject: [PATCH 05/15] fix #19 work with #11 --- SLThree/Exceptions/OperatorError.cs | 7 +-- SLThree/ExecutionContext.cs | 2 +- SLThree/Extensions/GenericExtensions.cs | 7 +++ SLThree/Extensions/SLTHelpers.cs | 9 ++++ SLThree/Lexems/ArrayInitializer.cs | 23 ++++++++ SLThree/Lexems/Expressions/MemberAccess.cs | 3 +- SLThree/Lexems/IndexLexem.cs | 62 ++++++++++++++++++++++ SLThree/Lexems/LambdaLexem.cs | 2 - SLThree/Properties/AssemblyInfo.cs | 4 +- SLThree/SLThree.csproj | 5 ++ SLThree/docs/versions/0.3.0 | 5 ++ SLThree/syntax.peg | 6 +++ 12 files changed, 126 insertions(+), 9 deletions(-) create mode 100644 SLThree/Lexems/ArrayInitializer.cs create mode 100644 SLThree/Lexems/IndexLexem.cs create mode 100644 SLThree/docs/versions/0.3.0 diff --git a/SLThree/Exceptions/OperatorError.cs b/SLThree/Exceptions/OperatorError.cs index e5922ed..8d21d7d 100644 --- a/SLThree/Exceptions/OperatorError.cs +++ b/SLThree/Exceptions/OperatorError.cs @@ -1,12 +1,13 @@ -using System; +using SLThree.Extensions; +using System; namespace SLThree { public class OperatorError : RuntimeError { public OperatorError(ExpressionUnary unary, Type left) - : base($"Operator {unary.Operator} not allow for {left?.Name ?? "null"}", unary.SourceContext) { } + : base($"Operator {unary.Operator} not allow for {left?.GetTypeString() ?? "null"}", unary.SourceContext) { } public OperatorError(ExpressionBinary binary, Type left, Type right) - : base($"Operator {binary.Operator} not allow for {left?.Name ?? "null"} and {right?.Name ?? "null"}", binary.SourceContext) { } + : base($"Operator {binary.Operator} not allow for {left?.GetTypeString() ?? "null"} and {right?.GetTypeString() ?? "null"}", binary.SourceContext) { } } } diff --git a/SLThree/ExecutionContext.cs b/SLThree/ExecutionContext.cs index c89d1cb..d9dec2a 100644 --- a/SLThree/ExecutionContext.cs +++ b/SLThree/ExecutionContext.cs @@ -12,7 +12,7 @@ public interface IExecutable object GetValue(ExecutionContext context); } - public bool ForbidImplicit = true; + public bool ForbidImplicit = false; public bool Returned; public bool Broken; diff --git a/SLThree/Extensions/GenericExtensions.cs b/SLThree/Extensions/GenericExtensions.cs index c3d7810..21ad5dd 100644 --- a/SLThree/Extensions/GenericExtensions.cs +++ b/SLThree/Extensions/GenericExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; @@ -39,6 +40,12 @@ public static string ReplaceAll(this string str, IDictionary rep public static T ToEnum(this string s) where T : Enum => (T)Enum.Parse(typeof(T), s); + public static IEnumerable Enumerate(this IEnumerable enumerable) + { + foreach (var x in enumerable) + yield return x; + } + public static TOut Cast(this TIn o) where TOut: TIn => (TOut)o; public static T Cast(this object o) => (T)o; } diff --git a/SLThree/Extensions/SLTHelpers.cs b/SLThree/Extensions/SLTHelpers.cs index e1e2589..aa6053c 100644 --- a/SLThree/Extensions/SLTHelpers.cs +++ b/SLThree/Extensions/SLTHelpers.cs @@ -28,6 +28,8 @@ public static object CastToMax(this object o) public static string GetTypeString(this Type t) { + if (t.IsGenericType) + return $"{t.FullName.Substring(0, t.FullName.IndexOf('`'))}<{t.GetGenericArguments().ConvertAll(x => x.GetTypeString()).JoinIntoString(", ")}>"; if (t == type_object) return "object"; if (t == type_byte) return "u8"; if (t == type_sbyte) return "i8"; @@ -45,6 +47,13 @@ public static string GetTypeString(this Type t) else return t.FullName; } + + public static bool IsList(this Type type) + { + return type.IsGenericType && type.GetGenericTypeDefinition() == type_list; + } + private static Type type_list = typeof(List<>); + public static string GetTypeString(this string t) { if (t == "System.Object") return "object"; diff --git a/SLThree/Lexems/ArrayInitializer.cs b/SLThree/Lexems/ArrayInitializer.cs new file mode 100644 index 0000000..00b3491 --- /dev/null +++ b/SLThree/Lexems/ArrayInitializer.cs @@ -0,0 +1,23 @@ +using Pegasus.Common; +using SLThree.Extensions; +using System.Linq; + +namespace SLThree +{ + public class ArrayInitializer : BaseLexem + { + public BaseLexem[] Lexems; + + public ArrayInitializer(BaseLexem[] lexems, Cursor cursor) : base(cursor) + { + Lexems = lexems; + } + + public override object GetValue(ExecutionContext context) + { + return Lexems.ConvertAll(x => x.GetValue(context)).ToList(); + } + + public override string ToString() => $"[{Lexems.JoinIntoString(", ")}]"; + } +} diff --git a/SLThree/Lexems/Expressions/MemberAccess.cs b/SLThree/Lexems/Expressions/MemberAccess.cs index eda3d5c..c1ef41d 100644 --- a/SLThree/Lexems/Expressions/MemberAccess.cs +++ b/SLThree/Lexems/Expressions/MemberAccess.cs @@ -16,6 +16,7 @@ public ClassAccess(Type name) { Name = name; } + public override string ToString() => $"access to {Name.GetTypeString()}"; } public override string Operator => "."; @@ -80,7 +81,7 @@ public override object GetValue(ExecutionContext context) if (prop != null) return prop.GetValue(left); nest_type = type.GetNestedType(nameLexem.Name); if (nest_type != null) return new ClassAccess(nest_type); - throw new RuntimeError($"Name {nameLexem.Name} not found in {type.Name.GetTypeString()}", SourceContext); + throw new RuntimeError($"Name \"{nameLexem.Name}\" not found in {type.GetTypeString()}", SourceContext); } else if (Right is InvokeLexem invokeLexem) { diff --git a/SLThree/Lexems/IndexLexem.cs b/SLThree/Lexems/IndexLexem.cs new file mode 100644 index 0000000..f82d04f --- /dev/null +++ b/SLThree/Lexems/IndexLexem.cs @@ -0,0 +1,62 @@ +using Pegasus.Common; +using SLThree.Extensions; +using System.Collections; +using System.Linq; +using System.Reflection; + +namespace SLThree +{ + public class IndexLexem : BaseLexem + { + public BaseLexem Lexem; + public BaseLexem[] Arguments; + + public IndexLexem(BaseLexem lexem, BaseLexem[] arguments, Cursor cursor) : base(cursor) + { + Lexem = lexem; + Arguments = arguments; + } + + private int Mode = 0; // 1 - array, 2 - list, 3 - tuple, 4 - any + private PropertyInfo PropertyInfo; + + public override object GetValue(ExecutionContext context) + { + var o = Lexem.GetValue(context); + + if (o == null) return null; + + if (Mode == 0) + { + var type = o.GetType(); + Mode = type.IsArray ? 1 : 0; + if (Mode == 0) + { + Mode = type.IsList() ? 1 : 0; + if (Mode == 0) + { + while (PropertyInfo == null && type != null) + { + PropertyInfo = type.GetProperties(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault(x => x.GetIndexParameters().Length == Arguments.Length); + if (PropertyInfo == null) type = type.BaseType; + } + if (PropertyInfo == null) return null; + Mode = 4; + } + } + } + + switch (Mode) + { + case 1: + { + return o.Cast()[context.ForbidImplicit ? Arguments[0].GetValue(context).Cast() : Arguments[0].GetValue(context).CastToType(typeof(int)).Cast()]; + } + case 4: return PropertyInfo.GetValue(o, Arguments.ConvertAll(x => x.GetValue(context))); + } + return null; + } + + public override string ToString() => $"{Lexem}[{Arguments.JoinIntoString(", ")}]"; + } +} diff --git a/SLThree/Lexems/LambdaLexem.cs b/SLThree/Lexems/LambdaLexem.cs index d45e926..377f110 100644 --- a/SLThree/Lexems/LambdaLexem.cs +++ b/SLThree/Lexems/LambdaLexem.cs @@ -36,7 +36,5 @@ public override object GetValue(ExecutionContext context) } return method; } - - public string Operator => "=>"; } } diff --git a/SLThree/Properties/AssemblyInfo.cs b/SLThree/Properties/AssemblyInfo.cs index 0ea2b13..17545d8 100644 --- a/SLThree/Properties/AssemblyInfo.cs +++ b/SLThree/Properties/AssemblyInfo.cs @@ -43,8 +43,8 @@ public static class SLTVersion { public const string Major = "0"; //vh public const string Minor = "2"; //vh public const string Build = "0"; //vh - public const string Revision = "634"; //vh - public const long LastUpdate = 638343734238825581; //vh + public const string Revision = "669"; //vh + public const long LastUpdate = 638343840422408233; //vh public const string Version = Major + "." + Minor + "." + Build + "." + Revision; public const string VersionWithoutRevision = Major + "." + Minor + "." + Build; diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index ec17448..4c38266 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -50,6 +50,7 @@ + @@ -73,6 +74,7 @@ + @@ -125,6 +127,9 @@ + + + diff --git a/SLThree/docs/versions/0.3.0 b/SLThree/docs/versions/0.3.0 new file mode 100644 index 0000000..d3e6c58 --- /dev/null +++ b/SLThree/docs/versions/0.3.0 @@ -0,0 +1,5 @@ +------ 0.3.0 ------ [~.~.~] +Language: + - Indexator and list initializers like in Python +Embedding: + - Wrapping classes in context, wrapping static members and classes \ No newline at end of file diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index 1806d0e..658f57d 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -152,11 +152,17 @@ primary -memoize / left:primary _ "." _ right:name { new MemberAccess(left, right, state) } / "new" _ right:invoke_lexem { new NewLexem(right as InvokeLexem, state) } / "new" _ right:primary { new NewLexem(right as MemberAccess, state) } + / left:primary _ "[" _ args:arguments_list _ "]" { new IndexLexem(left, args.ToArray(), state) } / "typeof" _ "(" _ left:primary _ ")" { new TypeofLexem(left, state) } / invoke_lexem + / list_creator / literal / name +list_creator + = "[" _ args:arguments_list _ "]" { new ArrayInitializer(args.ToArray(), state) } + / "[" _ "]" { new ArrayInitializer(new BaseLexem[0], state) } + invoke_lexem = left:identifier _ "(" _ args:arguments_list _ ")" { new InvokeLexem(left, args.ToArray(), state) } / left:identifier _ "(" _ ")" { new InvokeLexem(left, new BaseLexem[0], state) } From 7b8c63035d327ccbccb1ef64dbec8d639c84c372 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Wed, 1 Nov 2023 22:11:34 +0300 Subject: [PATCH 06/15] fix #16 --- SLThree/Extensions/SLTHelpers.cs | 5 +++ SLThree/Properties/AssemblyInfo.cs | 4 +- SLThree/SLThree.csproj | 4 +- SLThree/Statements/ForeachCycleStatement.cs | 50 +++++++++++++++++++++ SLThree/Statements/WhileCycleStatement.cs | 13 +++--- SLThree/syntax.peg | 9 +++- 6 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 SLThree/Statements/ForeachCycleStatement.cs diff --git a/SLThree/Extensions/SLTHelpers.cs b/SLThree/Extensions/SLTHelpers.cs index aa6053c..54aaa12 100644 --- a/SLThree/Extensions/SLTHelpers.cs +++ b/SLThree/Extensions/SLTHelpers.cs @@ -52,7 +52,12 @@ public static bool IsList(this Type type) { return type.IsGenericType && type.GetGenericTypeDefinition() == type_list; } + public static bool IsDictionary(this Type type) + { + return type.IsGenericType && type.GetGenericTypeDefinition() == type_dict; + } private static Type type_list = typeof(List<>); + private static Type type_dict = typeof(Dictionary<,>); public static string GetTypeString(this string t) { diff --git a/SLThree/Properties/AssemblyInfo.cs b/SLThree/Properties/AssemblyInfo.cs index 17545d8..d3f97c2 100644 --- a/SLThree/Properties/AssemblyInfo.cs +++ b/SLThree/Properties/AssemblyInfo.cs @@ -43,8 +43,8 @@ public static class SLTVersion { public const string Major = "0"; //vh public const string Minor = "2"; //vh public const string Build = "0"; //vh - public const string Revision = "669"; //vh - public const long LastUpdate = 638343840422408233; //vh + public const string Revision = "675"; //vh + public const long LastUpdate = 638344624525570340; //vh public const string Version = Major + "." + Minor + "." + Build + "." + Revision; public const string VersionWithoutRevision = Major + "." + Minor + "." + Build; diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 4c38266..6ba4600 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -105,6 +105,7 @@ + @@ -116,9 +117,6 @@ - - - diff --git a/SLThree/Statements/ForeachCycleStatement.cs b/SLThree/Statements/ForeachCycleStatement.cs new file mode 100644 index 0000000..824cacd --- /dev/null +++ b/SLThree/Statements/ForeachCycleStatement.cs @@ -0,0 +1,50 @@ +using Pegasus.Common; +using SLThree.Extensions; +using System.Collections; +using System.Linq; + +namespace SLThree +{ + public class ForeachCycleStatement : BaseStatement + { + public NameLexem Name { get; set; } + public BaseLexem Iterator { get; set; } + public StatementListStatement CycleBody { get; set; } + + public ForeachCycleStatement(NameLexem name, BaseLexem iterator, StatementListStatement cycleBody, Cursor cursor) : base(cursor) + { + Name = name; + Iterator = iterator; + CycleBody = cycleBody; + } + + private ExecutionContext last_context; + private int variable_index; + public override object GetValue(ExecutionContext context) + { + var iterator = Iterator.GetValue(context).Cast(); + var enumerator = iterator.GetEnumerator(); + if (context != last_context) + { + last_context = context; + variable_index = context.LocalVariables.SetValue(Name.Name, null); + } + var ret = default(object); + context.StartCycle(); + while (enumerator.MoveNext()) + { + context.LocalVariables.SetValue(variable_index, enumerator.Current); + for (var i = 0; i < CycleBody.Statements.Count; i++) + { + ret = CycleBody.Statements[i].GetValue(context); + if (context.Returned || context.Broken) break; + if (context.Continued) continue; + } + } + context.EndCycle(); + return ret; + } + + public override string ToString() => $"foreach ({Name} in {Iterator}) {{{CycleBody}}}"; + } +} diff --git a/SLThree/Statements/WhileCycleStatement.cs b/SLThree/Statements/WhileCycleStatement.cs index f8ee000..dfee04c 100644 --- a/SLThree/Statements/WhileCycleStatement.cs +++ b/SLThree/Statements/WhileCycleStatement.cs @@ -11,9 +11,9 @@ namespace SLThree public class WhileCycleStatement : BaseStatement { public BaseLexem Condition { get; set; } - public BaseStatement CycleBody { get; set; } + public StatementListStatement CycleBody { get; set; } - public WhileCycleStatement(BaseLexem condition, BaseStatement cycleBody, Cursor cursor) : base(cursor) + public WhileCycleStatement(BaseLexem condition, StatementListStatement cycleBody, Cursor cursor) : base(cursor) { Condition = condition; CycleBody = cycleBody; @@ -27,9 +27,12 @@ public override object GetValue(ExecutionContext context) context.StartCycle(); while (Condition.GetValue(context).Cast()) { - ret = CycleBody.GetValue(context); - if (context.Returned || context.Broken) return ret; - if (context.Continued) continue; + for (var i = 0; i < CycleBody.Statements.Count; i++) + { + ret = CycleBody.Statements[i].GetValue(context); + if (context.Returned || context.Broken) break; + if (context.Continued) continue; + } } context.EndCycle(); return ret; diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index 658f57d..6d8963c 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -14,6 +14,7 @@ statement_list statement_ws = _ st:statement _ ";" { st } / _ st:switch_statement _ { st } + / _ st:foreach_statement _ { st } / _ st:while_statement _ { st } / _ st:condition_statement _ { st } / _ st:block_statement _ { st } @@ -26,6 +27,7 @@ statement / _ st:using_statement _ { st } / _ st:condition_statement _ { st } / _ st:switch_statement _ { st } + / _ st:foreach_statement _ { st } / _ st:while_statement _ { st } / _ st:block_statement _ { st } / _ st:expr_statement _ { st } @@ -55,11 +57,14 @@ case_node / _ "case" _ lex:lexem _ ":" _ st:statement _ ";" _ { new SwitchStatement.Node(lex, st, false) } / _ "case" _ lex:lexem _ ":" _ { new SwitchStatement.Node(lex, null, true) } -block_statement +block_statement = "{" _ st:statement_list _ "}" { st } while_statement - = "while" _ "(" cond:lexem ")" _ body:block_statement { new WhileCycleStatement(cond, body, state) } + = "while" _ "(" _ cond:lexem _ ")" _ body:block_statement { new WhileCycleStatement(cond, body, state) } + +foreach_statement + = "foreach" _ "(" _ n:name _ "in" _ iter:lexem _ ")" _ body:block_statement { new ForeachCycleStatement(n, iter, body, state) } condition_statement = "if" _ "(" cond:lexem ")" _ t:block_statement _ "else" _ f:block_statement { new ConditionStatement(cond, t, f, state) } From 453ae4694e781e96b7c0659f0adb1955aa92ff90 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 2 Nov 2023 00:00:08 +0300 Subject: [PATCH 07/15] fix #18 --- SLThree/ExecutionContext.cs | 7 +- .../Lexems/Expressions/ExpressionBinaryAdd.cs | 2 +- .../Expressions/ExpressionBinaryDivide.cs | 2 +- .../Expressions/ExpressionBinaryEquals.cs | 4 +- .../ExpressionBinaryGreaterThan.cs | 4 +- .../ExpressionBinaryGreaterThanEquals.cs | 4 +- .../Expressions/ExpressionBinaryLessThan.cs | 4 +- .../ExpressionBinaryLessThanEquals.cs | 4 +- .../Lexems/Expressions/ExpressionBinaryMod.cs | 2 +- .../Expressions/ExpressionBinaryMultiply.cs | 2 +- .../Lexems/Expressions/ExpressionBinaryRem.cs | 2 +- .../Expressions/ExpressionBinaryUnequals.cs | 4 +- .../Lexems/Expressions/ExpressionUnaryAdd.cs | 2 +- .../Expressions/ExpressionUnaryBitNot.cs | 2 +- .../Lexems/Expressions/ExpressionUnaryNot.cs | 2 +- .../Lexems/Expressions/ExpressionUnaryRem.cs | 2 +- SLThree/Lexems/Expressions/MemberAccess.cs | 7 ++ SLThree/Lexems/IndexLexem.cs | 2 +- SLThree/Lexems/InvokeLexem.cs | 11 ++- SLThree/Lexems/LambdaLexem.cs | 2 +- SLThree/Lexems/Literals/LinqLiteral.cs | 13 ++++ SLThree/Linq/Linq.cs | 76 +++++++++++++++++++ SLThree/Method.cs | 4 +- SLThree/Properties/AssemblyInfo.cs | 4 +- SLThree/SLThree.csproj | 2 + SLThree/docs/versions/0.3.0 | 2 + SLThree/syntax.peg | 1 + 27 files changed, 141 insertions(+), 32 deletions(-) create mode 100644 SLThree/Lexems/Literals/LinqLiteral.cs create mode 100644 SLThree/Linq/Linq.cs diff --git a/SLThree/ExecutionContext.cs b/SLThree/ExecutionContext.cs index d9dec2a..9ac7a67 100644 --- a/SLThree/ExecutionContext.cs +++ b/SLThree/ExecutionContext.cs @@ -12,7 +12,10 @@ public interface IExecutable object GetValue(ExecutionContext context); } - public bool ForbidImplicit = false; + /// + /// Запрещает implicit в контексте + /// + public bool fimp = false; public bool Returned; public bool Broken; @@ -20,7 +23,7 @@ public interface IExecutable public object ReturnedValue; - public static ContextWrap global = new ContextWrap(new ExecutionContext()); + public static ContextWrap global = new ContextWrap(new ExecutionContext() { fimp = true }); private static bool and(bool a, bool b) => a && b; private static bool or(bool a, bool b) => a || b; diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryAdd.cs b/SLThree/Lexems/Expressions/ExpressionBinaryAdd.cs index 3184e38..6d40f7f 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryAdd.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryAdd.cs @@ -13,7 +13,7 @@ public override object GetValue(ExecutionContext context) { object left; object right; - if (context.ForbidImplicit) + if (context.fimp) { left = Left.GetValue(context); right = Right.GetValue(context); diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryDivide.cs b/SLThree/Lexems/Expressions/ExpressionBinaryDivide.cs index c8ebb14..1f8b2ca 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryDivide.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryDivide.cs @@ -13,7 +13,7 @@ public override object GetValue(ExecutionContext context) { object left; object right; - if (context.ForbidImplicit) + if (context.fimp) { left = Left.GetValue(context); right = Right.GetValue(context); diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryEquals.cs b/SLThree/Lexems/Expressions/ExpressionBinaryEquals.cs index a9fafb9..85c7777 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryEquals.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryEquals.cs @@ -13,7 +13,7 @@ public override object GetValue(ExecutionContext context) { object left; object right; - if (context.ForbidImplicit) + if (context.fimp) { left = Left.GetValue(context); right = Right.GetValue(context); @@ -39,7 +39,7 @@ public override object GetValue(ExecutionContext context) if (right is double d2) return u1 == d2; if (right is ulong u2) return u1 == u2; } - if (!context.ForbidImplicit) + if (!context.fimp) return (left as IComparable).CompareTo(right) == 0; throw new OperatorError(this, left?.GetType(), right?.GetType()); } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryGreaterThan.cs b/SLThree/Lexems/Expressions/ExpressionBinaryGreaterThan.cs index 8fc7eb3..e7bf59a 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryGreaterThan.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryGreaterThan.cs @@ -13,7 +13,7 @@ public override object GetValue(ExecutionContext context) { object left; object right; - if (context.ForbidImplicit) + if (context.fimp) { left = Left.GetValue(context); right = Right.GetValue(context); @@ -39,7 +39,7 @@ public override object GetValue(ExecutionContext context) if (right is double d2) return u1 > d2; if (right is ulong u2) return u1 > u2; } - if (!context.ForbidImplicit) + if (!context.fimp) return (left as IComparable).CompareTo(right) > 0; throw new OperatorError(this, left?.GetType(), right?.GetType()); } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryGreaterThanEquals.cs b/SLThree/Lexems/Expressions/ExpressionBinaryGreaterThanEquals.cs index 33fd2a8..61db100 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryGreaterThanEquals.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryGreaterThanEquals.cs @@ -13,7 +13,7 @@ public override object GetValue(ExecutionContext context) { object left; object right; - if (context.ForbidImplicit) + if (context.fimp) { left = Left.GetValue(context); right = Right.GetValue(context); @@ -39,7 +39,7 @@ public override object GetValue(ExecutionContext context) if (right is double d2) return u1 >= d2; if (right is ulong u2) return u1 >= u2; } - if (!context.ForbidImplicit) + if (!context.fimp) return (left as IComparable).CompareTo(right) >= 0; throw new OperatorError(this, left?.GetType(), right?.GetType()); } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryLessThan.cs b/SLThree/Lexems/Expressions/ExpressionBinaryLessThan.cs index 0b8ec92..2e290c4 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryLessThan.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryLessThan.cs @@ -13,7 +13,7 @@ public override object GetValue(ExecutionContext context) { object left; object right; - if (context.ForbidImplicit) + if (context.fimp) { left = Left.GetValue(context); right = Right.GetValue(context); @@ -39,7 +39,7 @@ public override object GetValue(ExecutionContext context) if (right is double d2) return u1 < d2; if (right is ulong u2) return u1 < u2; } - if (!context.ForbidImplicit) + if (!context.fimp) return (left as IComparable).CompareTo(right) < 0; throw new OperatorError(this, left?.GetType(), right?.GetType()); } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryLessThanEquals.cs b/SLThree/Lexems/Expressions/ExpressionBinaryLessThanEquals.cs index e4de528..0ce1c95 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryLessThanEquals.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryLessThanEquals.cs @@ -13,7 +13,7 @@ public override object GetValue(ExecutionContext context) { object left; object right; - if (context.ForbidImplicit) + if (context.fimp) { left = Left.GetValue(context); right = Right.GetValue(context); @@ -39,7 +39,7 @@ public override object GetValue(ExecutionContext context) if (right is double d2) return u1 <= d2; if (right is ulong u2) return u1 <= u2; } - if (!context.ForbidImplicit) + if (!context.fimp) return (left as IComparable).CompareTo(right) <= 0; throw new OperatorError(this, left?.GetType(), right?.GetType()); } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryMod.cs b/SLThree/Lexems/Expressions/ExpressionBinaryMod.cs index cbe6cb7..1a1e6eb 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryMod.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryMod.cs @@ -12,7 +12,7 @@ public override object GetValue(ExecutionContext context) { object left; object right; - if (context.ForbidImplicit) + if (context.fimp) { left = Left.GetValue(context); right = Right.GetValue(context); diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryMultiply.cs b/SLThree/Lexems/Expressions/ExpressionBinaryMultiply.cs index 486a973..632fcc6 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryMultiply.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryMultiply.cs @@ -13,7 +13,7 @@ public override object GetValue(ExecutionContext context) { object left; object right; - if (context.ForbidImplicit) + if (context.fimp) { left = Left.GetValue(context); right = Right.GetValue(context); diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryRem.cs b/SLThree/Lexems/Expressions/ExpressionBinaryRem.cs index df7a165..2ab2b87 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryRem.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryRem.cs @@ -18,7 +18,7 @@ public override object GetValue(ExecutionContext context) { object left; object right; - if (context.ForbidImplicit) + if (context.fimp) { left = Left.GetValue(context); right = Right.GetValue(context); diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryUnequals.cs b/SLThree/Lexems/Expressions/ExpressionBinaryUnequals.cs index 439fb07..9397112 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryUnequals.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryUnequals.cs @@ -13,7 +13,7 @@ public override object GetValue(ExecutionContext context) { object left; object right; - if (context.ForbidImplicit) + if (context.fimp) { left = Left.GetValue(context); right = Right.GetValue(context); @@ -39,7 +39,7 @@ public override object GetValue(ExecutionContext context) if (right is double d2) return u1 != d2; if (right is ulong u2) return u1 != u2; } - if (!context.ForbidImplicit) + if (!context.fimp) return (left as IComparable).CompareTo(right) != 0; throw new OperatorError(this, left?.GetType(), right?.GetType()); } diff --git a/SLThree/Lexems/Expressions/ExpressionUnaryAdd.cs b/SLThree/Lexems/Expressions/ExpressionUnaryAdd.cs index bb11dbe..f7edc72 100644 --- a/SLThree/Lexems/Expressions/ExpressionUnaryAdd.cs +++ b/SLThree/Lexems/Expressions/ExpressionUnaryAdd.cs @@ -11,7 +11,7 @@ public ExpressionUnaryAdd() : base() { } public override object GetValue(ExecutionContext context) { object left; - if (context.ForbidImplicit) + if (context.fimp) { left = Left.GetValue(context); } diff --git a/SLThree/Lexems/Expressions/ExpressionUnaryBitNot.cs b/SLThree/Lexems/Expressions/ExpressionUnaryBitNot.cs index d2227f2..8598a1a 100644 --- a/SLThree/Lexems/Expressions/ExpressionUnaryBitNot.cs +++ b/SLThree/Lexems/Expressions/ExpressionUnaryBitNot.cs @@ -11,7 +11,7 @@ public ExpressionUnaryBitNot() : base() { } public override object GetValue(ExecutionContext context) { object left; - if (context.ForbidImplicit) + if (context.fimp) { left = Left.GetValue(context); } diff --git a/SLThree/Lexems/Expressions/ExpressionUnaryNot.cs b/SLThree/Lexems/Expressions/ExpressionUnaryNot.cs index 291ed82..ce7cfad 100644 --- a/SLThree/Lexems/Expressions/ExpressionUnaryNot.cs +++ b/SLThree/Lexems/Expressions/ExpressionUnaryNot.cs @@ -11,7 +11,7 @@ public ExpressionUnaryNot() : base() { } public override object GetValue(ExecutionContext context) { object left; - if (context.ForbidImplicit) + if (context.fimp) { left = Left.GetValue(context); } diff --git a/SLThree/Lexems/Expressions/ExpressionUnaryRem.cs b/SLThree/Lexems/Expressions/ExpressionUnaryRem.cs index a8fe4d2..d1af362 100644 --- a/SLThree/Lexems/Expressions/ExpressionUnaryRem.cs +++ b/SLThree/Lexems/Expressions/ExpressionUnaryRem.cs @@ -11,7 +11,7 @@ public ExpressionUnaryRem() : base() { } public override object GetValue(ExecutionContext context) { object left; - if (context.ForbidImplicit) + if (context.fimp) { left = Left.GetValue(context); } diff --git a/SLThree/Lexems/Expressions/MemberAccess.cs b/SLThree/Lexems/Expressions/MemberAccess.cs index c1ef41d..5b143ab 100644 --- a/SLThree/Lexems/Expressions/MemberAccess.cs +++ b/SLThree/Lexems/Expressions/MemberAccess.cs @@ -43,6 +43,8 @@ public object Create(ExecutionContext context) private bool counted_contextwrapcache; private string variable_name; + + private bool counted_contextwrapcache2; public override object GetValue(ExecutionContext context) { var left = Left.GetValue(context); @@ -51,6 +53,10 @@ public override object GetValue(ExecutionContext context) { return (left as ExecutionContext.ContextWrap).pred.LocalVariables.GetValue(variable_name).Item1; } + else if (counted_contextwrapcache2) + { + return (Right as InvokeLexem).GetValue((left as ExecutionContext.ContextWrap).pred, (Right as InvokeLexem).Arguments.Select(x => x.GetValue(context)).ToArray()); + } if (left != null) { @@ -64,6 +70,7 @@ public override object GetValue(ExecutionContext context) } else if (Right is InvokeLexem invokeLexem) { + counted_contextwrapcache2 = true; return invokeLexem.GetValue(pred.pred, invokeLexem.Arguments.Select(x => x.GetValue(context)).ToArray()); } } diff --git a/SLThree/Lexems/IndexLexem.cs b/SLThree/Lexems/IndexLexem.cs index f82d04f..820a838 100644 --- a/SLThree/Lexems/IndexLexem.cs +++ b/SLThree/Lexems/IndexLexem.cs @@ -50,7 +50,7 @@ public override object GetValue(ExecutionContext context) { case 1: { - return o.Cast()[context.ForbidImplicit ? Arguments[0].GetValue(context).Cast() : Arguments[0].GetValue(context).CastToType(typeof(int)).Cast()]; + return o.Cast()[context.fimp ? Arguments[0].GetValue(context).Cast() : Arguments[0].GetValue(context).CastToType(typeof(int)).Cast()]; } case 4: return PropertyInfo.GetValue(o, Arguments.ConvertAll(x => x.GetValue(context))); } diff --git a/SLThree/Lexems/InvokeLexem.cs b/SLThree/Lexems/InvokeLexem.cs index 7aa9b60..d014b57 100644 --- a/SLThree/Lexems/InvokeLexem.cs +++ b/SLThree/Lexems/InvokeLexem.cs @@ -60,15 +60,20 @@ public override object GetValue(ExecutionContext context) return GetValue(context, Arguments.ConvertAll(x => x.GetValue(context))); } + private bool cached_1; + private MethodInfo founded; public object GetValue(ExecutionContext context, object obj) { var key = Name.ToString().Replace(" ", ""); + if (cached_1) return founded.Invoke(null, Arguments.ConvertAll(x => x.GetValue(context))); + if (obj is MemberAccess.ClassAccess ca) { - return ca.Name.GetMethods(BindingFlags.Public | BindingFlags.Static) - .FirstOrDefault(x => x.Name == key && x.GetParameters().Length == Arguments.Length) - .Invoke(null, Arguments.ConvertAll(x => x.GetValue(context))); + founded = ca.Name.GetMethods(BindingFlags.Public | BindingFlags.Static) + .FirstOrDefault(x => x.Name == key && x.GetParameters().Length == Arguments.Length); + cached_1 = true; + return founded.Invoke(null, Arguments.ConvertAll(x => x.GetValue(context))); } else if (obj != null) { diff --git a/SLThree/Lexems/LambdaLexem.cs b/SLThree/Lexems/LambdaLexem.cs index 377f110..5b4f796 100644 --- a/SLThree/Lexems/LambdaLexem.cs +++ b/SLThree/Lexems/LambdaLexem.cs @@ -31,7 +31,7 @@ public override object GetValue(ExecutionContext context) Name = "anon_method", ParamNames = Left.Arguments.Select(x => (x as NameLexem).Name).ToArray(), Statements = Right, - IsImplicit = Modificators.Contains("implicit") + imp = Modificators.Contains("implicit") }; } return method; diff --git a/SLThree/Lexems/Literals/LinqLiteral.cs b/SLThree/Lexems/Literals/LinqLiteral.cs new file mode 100644 index 0000000..58c96df --- /dev/null +++ b/SLThree/Lexems/Literals/LinqLiteral.cs @@ -0,0 +1,13 @@ +using Pegasus.Common; + +namespace SLThree +{ + public class LinqLiteral : BaseLexem + { + public LinqLiteral(Cursor cursor) : base(cursor) { } + + public override string ToString() => "linq"; + + public override object GetValue(ExecutionContext context) => Linq.Linq.LinqAccess; + } +} diff --git a/SLThree/Linq/Linq.cs b/SLThree/Linq/Linq.cs new file mode 100644 index 0000000..0febcc4 --- /dev/null +++ b/SLThree/Linq/Linq.cs @@ -0,0 +1,76 @@ +using SLThree.Extensions; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Remoting.Messaging; +using System.Text; +using System.Threading.Tasks; + +namespace SLThree.Linq +{ + public static class Linq + { + internal static MemberAccess.ClassAccess LinqAccess = new MemberAccess.ClassAccess(typeof(Linq)); +#pragma warning disable IDE1006 // Стили именования + public static IEnumerable range(long end) + { + for (var i = 0; i < end; i += 1) + yield return i; + } + public static IEnumerable range(long start, long end) + { + for (var i = start; i < end; i += 1) + yield return i; + } + public static IEnumerable range(long start, long end, long step) + { + for (var i = start; i < end; i += step) + yield return i; + } + + public static object max(IEnumerable objects, Method method, ExecutionContext context) + { + return objects.Max(x => method.GetValue(context, new object[] { x })); + } + public static object max(IEnumerable objects, Method method) + { + return objects.Max(x => method.GetValue(new object[] { x })); + } + public static object max(IEnumerable objects) => objects.Max(); + + public static object min(IEnumerable objects, Method method, ExecutionContext context) + { + return objects.Min(x => method.GetValue(context, new object[] { x })); + } + public static object min(IEnumerable objects, Method method) + { + return objects.Min(x => method.GetValue(new object[] { x })); + } + public static object min(IEnumerable objects) => objects.Min(); + + public static IEnumerable map(IEnumerable objects, Method method, ExecutionContext context) + { + return objects.Select(x => method.GetValue(context, new object[] { x })); + } + public static IEnumerable map(IEnumerable objects, Method method) + { + return objects.Select(x => method.GetValue(new object[] { x })); + } + + public static IEnumerable filter(IEnumerable objects, Method method, ExecutionContext context) + { + return objects.Where(x => method.GetValue(context, new object[] { x }).Cast()); + } + public static IEnumerable filter(IEnumerable objects, Method method) + { + return objects.Where(x => method.GetValue(new object[] { x }).Cast()); + } + + public static List tolist(IEnumerable objects) => objects.ToList(); + public static object[] toarray(IEnumerable objects) => objects.ToArray(); + + public static string jts(IEnumerable objects, string str) => objects.JoinIntoString(str); + public static string jts(IEnumerable objects) => objects.JoinIntoString(" "); +#pragma warning restore IDE1006 // Стили именования + } +} diff --git a/SLThree/Method.cs b/SLThree/Method.cs index b5f46fe..600695b 100644 --- a/SLThree/Method.cs +++ b/SLThree/Method.cs @@ -14,7 +14,7 @@ public class Method public string[] ParamNames; public StatementListStatement Statements; - public bool IsImplicit = false; + public bool imp = false; public override string ToString() => $"_ {Name}({ParamNames.ConvertAll(x => "_").JoinIntoString(", ")})"; @@ -33,7 +33,7 @@ public ExecutionContext GetExecutionContext(object[] arguments, ExecutionContext } ret.PreviousContext = context; ret.LocalVariables.FillArguments(this, arguments); - ret.ForbidImplicit = !IsImplicit; + ret.fimp = !imp; return ret; } diff --git a/SLThree/Properties/AssemblyInfo.cs b/SLThree/Properties/AssemblyInfo.cs index d3f97c2..822b084 100644 --- a/SLThree/Properties/AssemblyInfo.cs +++ b/SLThree/Properties/AssemblyInfo.cs @@ -43,8 +43,8 @@ public static class SLTVersion { public const string Major = "0"; //vh public const string Minor = "2"; //vh public const string Build = "0"; //vh - public const string Revision = "675"; //vh - public const long LastUpdate = 638344624525570340; //vh + public const string Revision = "692"; //vh + public const long LastUpdate = 638344689891003685; //vh public const string Version = Major + "." + Minor + "." + Build + "." + Revision; public const string VersionWithoutRevision = Major + "." + Minor + "." + Build; diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 6ba4600..2602b9a 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -84,6 +84,7 @@ + @@ -94,6 +95,7 @@ + diff --git a/SLThree/docs/versions/0.3.0 b/SLThree/docs/versions/0.3.0 index d3e6c58..91f4c2e 100644 --- a/SLThree/docs/versions/0.3.0 +++ b/SLThree/docs/versions/0.3.0 @@ -1,5 +1,7 @@ ------ 0.3.0 ------ [~.~.~] Language: + - Foreach cycle + - linq context (linq.range, linq.max etc.) - Indexator and list initializers like in Python Embedding: - Wrapping classes in context, wrapping static members and classes \ No newline at end of file diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index 6d8963c..754c71e 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -199,6 +199,7 @@ literal / u64:([0-9]+ ("u64")) { new ULongLiteral(ulong.Parse(u64.Replace("u64", ""), CultureInfo.InvariantCulture), state) } / i64:([0-9]+ ("i64")?) { new LongLiteral(long.Parse(i64.Replace("i64", ""), CultureInfo.InvariantCulture), state) } / b:("true"/"false") { new BoolLiteral(bool.Parse(b), state) } + / "linq" { new LinqLiteral(state) } / "global" { new GlobalLiteral(state) } / "null" { new NullLiteral(state) } / "self" { new SelfLiteral(state) } From 3517e0eedafe11998cec08130d05b406d75ac0e7 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 2 Nov 2023 12:56:40 +0300 Subject: [PATCH 08/15] fix #12 fix #23 --- SLThree/Exceptions/OperatorError.cs | 2 + SLThree/ExecutionContext.cs | 9 +--- .../Lexems/Expressions/ExpressionBinaryAnd.cs | 18 +++++++ .../Expressions/ExpressionBinaryBitAnd.cs | 37 ++++++++++++++ .../Expressions/ExpressionBinaryBitOr.cs | 37 ++++++++++++++ .../Expressions/ExpressionBinaryBitXor.cs | 37 ++++++++++++++ .../Lexems/Expressions/ExpressionBinaryOr.cs | 18 +++++++ .../Lexems/Expressions/ExpressionTernary.cs | 31 ++++++++++++ SLThree/Lexems/Expressions/MemberAccess.cs | 9 +++- SLThree/Properties/AssemblyInfo.cs | 4 +- SLThree/SLThree.csproj | 6 +++ SLThree/docs/versions/0.3.0 | 2 + SLThree/syntax.peg | 48 ++++++++++++++----- 13 files changed, 236 insertions(+), 22 deletions(-) create mode 100644 SLThree/Lexems/Expressions/ExpressionBinaryAnd.cs create mode 100644 SLThree/Lexems/Expressions/ExpressionBinaryBitAnd.cs create mode 100644 SLThree/Lexems/Expressions/ExpressionBinaryBitOr.cs create mode 100644 SLThree/Lexems/Expressions/ExpressionBinaryBitXor.cs create mode 100644 SLThree/Lexems/Expressions/ExpressionBinaryOr.cs create mode 100644 SLThree/Lexems/Expressions/ExpressionTernary.cs diff --git a/SLThree/Exceptions/OperatorError.cs b/SLThree/Exceptions/OperatorError.cs index 8d21d7d..336d22a 100644 --- a/SLThree/Exceptions/OperatorError.cs +++ b/SLThree/Exceptions/OperatorError.cs @@ -9,5 +9,7 @@ public OperatorError(ExpressionUnary unary, Type left) : base($"Operator {unary.Operator} not allow for {left?.GetTypeString() ?? "null"}", unary.SourceContext) { } public OperatorError(ExpressionBinary binary, Type left, Type right) : base($"Operator {binary.Operator} not allow for {left?.GetTypeString() ?? "null"} and {right?.GetTypeString() ?? "null"}", binary.SourceContext) { } + public OperatorError(string op, Type cond, SourceContext context) + : base($"Operator {op} not allow for {cond?.GetTypeString() ?? "null"}", context) { } } } diff --git a/SLThree/ExecutionContext.cs b/SLThree/ExecutionContext.cs index 9ac7a67..134e4b5 100644 --- a/SLThree/ExecutionContext.cs +++ b/SLThree/ExecutionContext.cs @@ -25,14 +25,9 @@ public interface IExecutable public static ContextWrap global = new ContextWrap(new ExecutionContext() { fimp = true }); - private static bool and(bool a, bool b) => a && b; - private static bool or(bool a, bool b) => a || b; - private static bool xor(bool a, bool b) => a ^ b; static ExecutionContext() { - global.pred.LocalVariables.SetValue("and", Method.Create(and)); - global.pred.LocalVariables.SetValue("or", Method.Create(or)); - global.pred.LocalVariables.SetValue("xor", Method.Create(xor)); + } public class ContextWrap @@ -45,7 +40,7 @@ public ContextWrap(ExecutionContext pred) } internal ExecutionContext PreviousContext; public ContextWrap pred => new ContextWrap(PreviousContext); - public ContextWrap direct => new ContextWrap(this); + public ContextWrap wrap => new ContextWrap(this); private int cycles = 0; diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryAnd.cs b/SLThree/Lexems/Expressions/ExpressionBinaryAnd.cs new file mode 100644 index 0000000..40a2e20 --- /dev/null +++ b/SLThree/Lexems/Expressions/ExpressionBinaryAnd.cs @@ -0,0 +1,18 @@ +using Pegasus.Common; + +namespace SLThree +{ + public class ExpressionBinaryAnd : ExpressionBinary + { + public override string Operator => "&&"; + public ExpressionBinaryAnd(BaseLexem left, BaseLexem right, Cursor cursor) : base(left, right, cursor) { } + public ExpressionBinaryAnd() : base() { } + public override object GetValue(ExecutionContext context) + { + object left = Left.GetValue(context); + object right = Right.GetValue(context); + if (left is bool b1 && right is bool b2) return b1 && b2; + throw new OperatorError(this, left?.GetType(), right?.GetType()); + } + } +} diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryBitAnd.cs b/SLThree/Lexems/Expressions/ExpressionBinaryBitAnd.cs new file mode 100644 index 0000000..89b46e5 --- /dev/null +++ b/SLThree/Lexems/Expressions/ExpressionBinaryBitAnd.cs @@ -0,0 +1,37 @@ +using Pegasus.Common; +using SLThree.Extensions; + +namespace SLThree +{ + public class ExpressionBinaryBitAnd : ExpressionBinary + { + public override string Operator => "&"; + public ExpressionBinaryBitAnd(BaseLexem left, BaseLexem right, Cursor cursor) : base(left, right, cursor) { } + public ExpressionBinaryBitAnd() : base() { } + public override object GetValue(ExecutionContext context) + { + object left; + object right; + if (context.fimp) + { + left = Left.GetValue(context); + right = Right.GetValue(context); + } + else + { + left = Left.GetValue(context).CastToMax(); + right = Right.GetValue(context).CastToMax(); + } + if (left is bool b1 && right is bool b2) return b1 & b2; + else if (left is long i1) + { + if (right is long i2) return i1 & i2; + } + else if (left is ulong u1) + { + if (right is ulong u2) return u1 & u2; + } + throw new OperatorError(this, left?.GetType(), right?.GetType()); + } + } +} diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryBitOr.cs b/SLThree/Lexems/Expressions/ExpressionBinaryBitOr.cs new file mode 100644 index 0000000..fa35153 --- /dev/null +++ b/SLThree/Lexems/Expressions/ExpressionBinaryBitOr.cs @@ -0,0 +1,37 @@ +using Pegasus.Common; +using SLThree.Extensions; + +namespace SLThree +{ + public class ExpressionBinaryBitOr : ExpressionBinary + { + public override string Operator => "|"; + public ExpressionBinaryBitOr(BaseLexem left, BaseLexem right, Cursor cursor) : base(left, right, cursor) { } + public ExpressionBinaryBitOr() : base() { } + public override object GetValue(ExecutionContext context) + { + object left; + object right; + if (context.fimp) + { + left = Left.GetValue(context); + right = Right.GetValue(context); + } + else + { + left = Left.GetValue(context).CastToMax(); + right = Right.GetValue(context).CastToMax(); + } + if (left is bool b1 && right is bool b2) return b1 | b2; + else if (left is long i1) + { + if (right is long i2) return i1 | i2; + } + else if (left is ulong u1) + { + if (right is ulong u2) return u1 | u2; + } + throw new OperatorError(this, left?.GetType(), right?.GetType()); + } + } +} diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryBitXor.cs b/SLThree/Lexems/Expressions/ExpressionBinaryBitXor.cs new file mode 100644 index 0000000..fc4cf57 --- /dev/null +++ b/SLThree/Lexems/Expressions/ExpressionBinaryBitXor.cs @@ -0,0 +1,37 @@ +using Pegasus.Common; +using SLThree.Extensions; + +namespace SLThree +{ + public class ExpressionBinaryBitXor : ExpressionBinary + { + public override string Operator => "^"; + public ExpressionBinaryBitXor(BaseLexem left, BaseLexem right, Cursor cursor) : base(left, right, cursor) { } + public ExpressionBinaryBitXor() : base() { } + public override object GetValue(ExecutionContext context) + { + object left; + object right; + if (context.fimp) + { + left = Left.GetValue(context); + right = Right.GetValue(context); + } + else + { + left = Left.GetValue(context).CastToMax(); + right = Right.GetValue(context).CastToMax(); + } + if (left is bool b1 && right is bool b2) return b1 ^ b2; + else if (left is long i1) + { + if (right is long i2) return i1 ^ i2; + } + else if (left is ulong u1) + { + if (right is ulong u2) return u1 ^ u2; + } + throw new OperatorError(this, left?.GetType(), right?.GetType()); + } + } +} diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryOr.cs b/SLThree/Lexems/Expressions/ExpressionBinaryOr.cs new file mode 100644 index 0000000..8282302 --- /dev/null +++ b/SLThree/Lexems/Expressions/ExpressionBinaryOr.cs @@ -0,0 +1,18 @@ +using Pegasus.Common; + +namespace SLThree +{ + public class ExpressionBinaryOr: ExpressionBinary + { + public override string Operator => "||"; + public ExpressionBinaryOr(BaseLexem left, BaseLexem right, Cursor cursor) : base(left, right, cursor) { } + public ExpressionBinaryOr() : base() { } + public override object GetValue(ExecutionContext context) + { + object left = Left.GetValue(context); + object right = Right.GetValue(context); + if (left is bool b1 && right is bool b2) return b1 || b2; + throw new OperatorError(this, left?.GetType(), right?.GetType()); + } + } +} diff --git a/SLThree/Lexems/Expressions/ExpressionTernary.cs b/SLThree/Lexems/Expressions/ExpressionTernary.cs new file mode 100644 index 0000000..ebfab87 --- /dev/null +++ b/SLThree/Lexems/Expressions/ExpressionTernary.cs @@ -0,0 +1,31 @@ +using Pegasus.Common; + +namespace SLThree +{ + public class ExpressionTernary : BaseLexem + { + public string Operator => "?:"; + + public BaseLexem Condition; + public BaseLexem Left; + public BaseLexem Right; + + public ExpressionTernary(BaseLexem cond, BaseLexem left, BaseLexem right, Cursor cursor) : base(cursor) + { + Condition = cond; + Left = left; + Right = right; + } + public ExpressionTernary() : base(default) { } + public override object GetValue(ExecutionContext context) + { + object cond = Condition.GetValue(context); + object left = Left.GetValue(context); + object right = Right.GetValue(context); + if (cond is bool b1) return b1 ? left : right; + throw new OperatorError(Operator, cond?.GetType(), SourceContext); + } + + public override string ToString() => $"{Condition} ? {Left} : {Right}"; + } +} diff --git a/SLThree/Lexems/Expressions/MemberAccess.cs b/SLThree/Lexems/Expressions/MemberAccess.cs index 5b143ab..98b180a 100644 --- a/SLThree/Lexems/Expressions/MemberAccess.cs +++ b/SLThree/Lexems/Expressions/MemberAccess.cs @@ -45,6 +45,7 @@ public object Create(ExecutionContext context) private string variable_name; private bool counted_contextwrapcache2; + private bool is_unwrap; public override object GetValue(ExecutionContext context) { var left = Left.GetValue(context); @@ -55,7 +56,8 @@ public override object GetValue(ExecutionContext context) } else if (counted_contextwrapcache2) { - return (Right as InvokeLexem).GetValue((left as ExecutionContext.ContextWrap).pred, (Right as InvokeLexem).Arguments.Select(x => x.GetValue(context)).ToArray()); + if (is_unwrap) return (left as ExecutionContext.ContextWrap).pred; + else return (Right as InvokeLexem).GetValue((left as ExecutionContext.ContextWrap).pred, (Right as InvokeLexem).Arguments.Select(x => x.GetValue(context)).ToArray()); } if (left != null) @@ -71,6 +73,11 @@ public override object GetValue(ExecutionContext context) else if (Right is InvokeLexem invokeLexem) { counted_contextwrapcache2 = true; + if (invokeLexem.Name?.Cast()?.Name == "unwrap" && invokeLexem.Arguments.Length == 0) + { + is_unwrap = true; + return pred.pred; + } return invokeLexem.GetValue(pred.pred, invokeLexem.Arguments.Select(x => x.GetValue(context)).ToArray()); } } diff --git a/SLThree/Properties/AssemblyInfo.cs b/SLThree/Properties/AssemblyInfo.cs index 822b084..7f31404 100644 --- a/SLThree/Properties/AssemblyInfo.cs +++ b/SLThree/Properties/AssemblyInfo.cs @@ -43,8 +43,8 @@ public static class SLTVersion { public const string Major = "0"; //vh public const string Minor = "2"; //vh public const string Build = "0"; //vh - public const string Revision = "692"; //vh - public const long LastUpdate = 638344689891003685; //vh + public const string Revision = "710"; //vh + public const long LastUpdate = 638345151568919183; //vh public const string Version = Major + "." + Minor + "." + Build + "." + Revision; public const string VersionWithoutRevision = Major + "." + Minor + "." + Build; diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 2602b9a..93c2d43 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -52,7 +52,13 @@ + + + + + + diff --git a/SLThree/docs/versions/0.3.0 b/SLThree/docs/versions/0.3.0 index 91f4c2e..ce043bd 100644 --- a/SLThree/docs/versions/0.3.0 +++ b/SLThree/docs/versions/0.3.0 @@ -3,5 +3,7 @@ Language: - Foreach cycle - linq context (linq.range, linq.max etc.) - Indexator and list initializers like in Python + - Logical operators (&&, ||) and binary bit operators (&, |, ^) + - Ternary operator Embedding: - Wrapping classes in context, wrapping static members and classes \ No newline at end of file diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index 754c71e..f8157b5 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -74,17 +74,43 @@ expr_statement = value:lexem { new ExpressionStatement(value, state) } lexem - = binary_4 + = binary_9 + +binary_9 -memoize + = left:binary_7 _ "=" _ right:binary_9 { new ExpressionBinaryAssign(left, right, state) } + / left:binary_7 _ "+=" _ right:binary_9 { new ExpressionBinaryAssign(left, new ExpressionBinaryAdd(left, right, state), state) } + / left:binary_7 _ "-=" _ right:binary_9 { new ExpressionBinaryAssign(left, new ExpressionBinaryRem(left, right, state), state) } + / left:binary_7 _ "*=" _ right:binary_9 { new ExpressionBinaryAssign(left, new ExpressionBinaryMultiply(left, right, state), state) } + / left:binary_7 _ "/=" _ right:binary_9 { new ExpressionBinaryAssign(left, new ExpressionBinaryDivide(left, right, state), state) } + / left:binary_7 _ "%=" _ right:binary_9 { new ExpressionBinaryAssign(left, new ExpressionBinaryMod(left, right, state), state) } + / left:binary_7 _ "&=" _ right:binary_9 { new ExpressionBinaryAssign(left, new ExpressionBinaryBitAnd(left, right, state), state) } + / left:binary_7 _ "|=" _ right:binary_9 { new ExpressionBinaryAssign(left, new ExpressionBinaryBitOr(left, right, state), state) } + / left:binary_7 _ "^=" _ right:binary_9 { new ExpressionBinaryAssign(left, new ExpressionBinaryBitXor(left, right, state), state) } + / left:lambda_left _ "=>" _ right:lambda_right _ { new LambdaLexem(new InvokeLexem(null, left.Item2, state), right, left.Item1, state) } + / left:ternary_0 { left } + +ternary_0 -memoize + = cond:ternary_0 _ "?" _ t:lexem _ ":" _ f:lexem { new ExpressionTernary(cond, t, f, state) } + / binary_7 + +binary_7 -memoize + = left:binary_7 _ "||" right:binary_6 { new ExpressionBinaryOr(left, right, state) } + / binary_6 + +binary_6 -memoize + = left:binary_6 _ "&&" right:binary_5 { new ExpressionBinaryAnd(left, right, state) } + / binary_5 + +binary_5 -memoize + = left:binary_5 _ "&" right:binary_4 { new ExpressionBinaryBitAnd(left, right, state) } + / left:binary_5 _ "^" right:binary_4 { new ExpressionBinaryBitXor(left, right, state) } + / left:binary_5 _ "|" right:binary_4 { new ExpressionBinaryBitOr(left, right, state) } + / binary_4 binary_4 -memoize - = left:binary_3 _ "=" _ right:binary_4 { new ExpressionBinaryAssign(left, right, state) } - / left:binary_3 _ "+=" _ right:binary_4 { new ExpressionBinaryAssign(left, new ExpressionBinaryAdd(left, right, state), state) } - / left:binary_3 _ "-=" _ right:binary_4 { new ExpressionBinaryAssign(left, new ExpressionBinaryRem(left, right, state), state) } - / left:binary_3 _ "*=" _ right:binary_4 { new ExpressionBinaryAssign(left, new ExpressionBinaryMultiply(left, right, state), state) } - / left:binary_3 _ "/=" _ right:binary_4 { new ExpressionBinaryAssign(left, new ExpressionBinaryDivide(left, right, state), state) } - / left:binary_3 _ "%=" _ right:binary_4 { new ExpressionBinaryAssign(left, new ExpressionBinaryMod(left, right, state), state) } - / left:lambda_left _ "=>" _ right:lambda_right _ { new LambdaLexem(new InvokeLexem(null, left.Item2, state), right, left.Item1, state) } - / left:binary_3 { left } + = left:binary_4 _ "==" _ right:binary_3 { new ExpressionBinaryEquals(left, right, state) } + / left:binary_4 _ "!=" _ right:binary_3 { new ExpressionBinaryUnequals(left, right, state) } + / binary_3 lambda_left , BaseLexem[]>> = mods:method_modificator_list? _ "(" _ ")" { new ValueTuple, BaseLexem[]>(mods.Count == 0 ? new string[0] : mods[0], new BaseLexem[0]) } @@ -110,9 +136,7 @@ implicit_keyword = s:"implicit" { s } binary_3 -memoize - = left:binary_3 _ "==" _ right:binary_2 { new ExpressionBinaryEquals(left, right, state) } - / left:binary_3 _ "as" _ right:as_expr_right { new CastLexem(left, right, state) } - / left:binary_3 _ "!=" _ right:binary_2 { new ExpressionBinaryUnequals(left, right, state) } + = left:binary_3 _ "as" _ right:as_expr_right { new CastLexem(left, right, state) } / left:binary_3 _ ">=" _ right:binary_2 { new ExpressionBinaryGreaterThanEquals(left, right, state) } / left:binary_3 _ "<=" _ right:binary_2 { new ExpressionBinaryLessThanEquals(left, right, state) } / left:binary_3 _ ">" _ right:binary_2 { new ExpressionBinaryGreaterThan(left, right, state) } From 271c26ce02745f0d7c298c1ebfedb383db200be0 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 2 Nov 2023 21:06:35 +0300 Subject: [PATCH 09/15] one more optimization binaries don't throws errors now --- SLThree/ExecutionContext.cs | 6 ++++ SLThree/Extensions/GenericExtensions.cs | 2 ++ SLThree/Lexems/BaseLexem.cs | 1 + .../Lexems/Expressions/ExpressionBinaryAdd.cs | 7 ++-- .../Expressions/ExpressionBinaryAssign.cs | 3 +- .../Expressions/ExpressionBinaryDivide.cs | 7 ++-- .../Expressions/ExpressionBinaryEquals.cs | 7 ++-- .../ExpressionBinaryGreaterThan.cs | 7 ++-- .../ExpressionBinaryGreaterThanEquals.cs | 7 ++-- .../Expressions/ExpressionBinaryLessThan.cs | 7 ++-- .../ExpressionBinaryLessThanEquals.cs | 7 ++-- .../Lexems/Expressions/ExpressionBinaryMod.cs | 7 ++-- .../Expressions/ExpressionBinaryMultiply.cs | 7 ++-- .../Lexems/Expressions/ExpressionBinaryOr.cs | 3 +- .../Lexems/Expressions/ExpressionBinaryRem.cs | 7 ++-- .../Expressions/ExpressionBinaryUnequals.cs | 7 ++-- .../Lexems/Expressions/ExpressionTernary.cs | 9 +++--- .../Lexems/Expressions/ExpressionUnaryAdd.cs | 3 +- .../Expressions/ExpressionUnaryBitNot.cs | 3 +- .../Lexems/Expressions/ExpressionUnaryNot.cs | 3 +- .../Lexems/Expressions/ExpressionUnaryRem.cs | 3 +- SLThree/Lexems/Expressions/MemberAccess.cs | 2 +- SLThree/Lexems/InvokeLexem.cs | 13 ++++---- SLThree/Lexems/Literals/Literal.cs | 2 +- SLThree/Properties/AssemblyInfo.cs | 4 +-- SLThree/Statements/ConditionStatement.cs | 32 +++++++++++++------ SLThree/Statements/ForeachCycleStatement.cs | 10 +++--- SLThree/Statements/StatementListStatement.cs | 6 ++-- SLThree/Statements/WhileCycleStatement.cs | 12 ++++--- SLThree/docs/versions/0.3.0 | 4 ++- SLThree/syntax.peg | 10 +++--- 31 files changed, 128 insertions(+), 80 deletions(-) diff --git a/SLThree/ExecutionContext.cs b/SLThree/ExecutionContext.cs index 134e4b5..02d40b3 100644 --- a/SLThree/ExecutionContext.cs +++ b/SLThree/ExecutionContext.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; @@ -23,6 +25,8 @@ public interface IExecutable public object ReturnedValue; + public List Errors = new List(); + public static ContextWrap global = new ContextWrap(new ExecutionContext() { fimp = true }); static ExecutionContext() @@ -44,6 +48,7 @@ public ContextWrap(ExecutionContext pred) private int cycles = 0; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void StartCycle() { cycles += 1; @@ -52,6 +57,7 @@ public void StartCycle() public bool InCycle() => cycles > 1; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void EndCycle() { cycles -= 1; diff --git a/SLThree/Extensions/GenericExtensions.cs b/SLThree/Extensions/GenericExtensions.cs index 21ad5dd..c759719 100644 --- a/SLThree/Extensions/GenericExtensions.cs +++ b/SLThree/Extensions/GenericExtensions.cs @@ -2,6 +2,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; @@ -21,6 +22,7 @@ public static string JoinIntoString(this IEnumerable e, string delim) return sb.ToString(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TOut[] ConvertAll(this TIn[] array, Converter func) => Array.ConvertAll(array, func); diff --git a/SLThree/Lexems/BaseLexem.cs b/SLThree/Lexems/BaseLexem.cs index 4cb4a27..3b745d6 100644 --- a/SLThree/Lexems/BaseLexem.cs +++ b/SLThree/Lexems/BaseLexem.cs @@ -1,5 +1,6 @@ using Pegasus.Common; using System.Diagnostics; +using System.Runtime.CompilerServices; namespace SLThree { diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryAdd.cs b/SLThree/Lexems/Expressions/ExpressionBinaryAdd.cs index 6d40f7f..76151b1 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryAdd.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryAdd.cs @@ -25,8 +25,8 @@ public override object GetValue(ExecutionContext context) } if (left is long i1) { - if (right is double d2) return i1 + d2; if (right is long i2) return i1 + i2; + if (right is double d2) return i1 + d2; } else if (left is double d1) { @@ -36,10 +36,11 @@ public override object GetValue(ExecutionContext context) } else if (left is ulong u1) { - if (right is double d2) return u1 + d2; if (right is ulong u2) return u1 + u2; + if (right is double d2) return u1 + d2; } - throw new OperatorError(this, left?.GetType(), right?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType(), right?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryAssign.cs b/SLThree/Lexems/Expressions/ExpressionBinaryAssign.cs index 653b770..bd680e7 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryAssign.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryAssign.cs @@ -33,7 +33,8 @@ public override object GetValue(ExecutionContext context) return right; } } - throw new OperatorError(this, Left?.GetType(), right?.GetType()); + context.Errors.Add(new OperatorError(this, Left?.GetType(), right?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryDivide.cs b/SLThree/Lexems/Expressions/ExpressionBinaryDivide.cs index 1f8b2ca..b226dad 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryDivide.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryDivide.cs @@ -25,8 +25,8 @@ public override object GetValue(ExecutionContext context) } if (left is long i1) { - if (right is double d2) return i1 / d2; if (right is long i2) return i1 / i2; + if (right is double d2) return i1 / d2; } else if (left is double d1) { @@ -36,10 +36,11 @@ public override object GetValue(ExecutionContext context) } else if (left is ulong u1) { - if (right is double d2) return u1 / d2; if (right is ulong u2) return u1 / u2; + if (right is double d2) return u1 / d2; } - throw new OperatorError(this, left?.GetType(), right?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType(), right?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryEquals.cs b/SLThree/Lexems/Expressions/ExpressionBinaryEquals.cs index 85c7777..fcaaf6d 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryEquals.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryEquals.cs @@ -25,8 +25,8 @@ public override object GetValue(ExecutionContext context) } if (left is long i1) { - if (right is double d2) return i1 == d2; if (right is long i2) return i1 == i2; + if (right is double d2) return i1 == d2; } else if (left is double d1) { @@ -36,12 +36,13 @@ public override object GetValue(ExecutionContext context) } else if (left is ulong u1) { - if (right is double d2) return u1 == d2; if (right is ulong u2) return u1 == u2; + if (right is double d2) return u1 == d2; } if (!context.fimp) return (left as IComparable).CompareTo(right) == 0; - throw new OperatorError(this, left?.GetType(), right?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType(), right?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryGreaterThan.cs b/SLThree/Lexems/Expressions/ExpressionBinaryGreaterThan.cs index e7bf59a..9a84334 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryGreaterThan.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryGreaterThan.cs @@ -25,8 +25,8 @@ public override object GetValue(ExecutionContext context) } if (left is long i1) { - if (right is double d2) return i1 > d2; if (right is long i2) return i1 > i2; + if (right is double d2) return i1 > d2; } else if (left is double d1) { @@ -36,12 +36,13 @@ public override object GetValue(ExecutionContext context) } else if (left is ulong u1) { - if (right is double d2) return u1 > d2; if (right is ulong u2) return u1 > u2; + if (right is double d2) return u1 > d2; } if (!context.fimp) return (left as IComparable).CompareTo(right) > 0; - throw new OperatorError(this, left?.GetType(), right?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType(), right?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryGreaterThanEquals.cs b/SLThree/Lexems/Expressions/ExpressionBinaryGreaterThanEquals.cs index 61db100..24fdaf8 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryGreaterThanEquals.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryGreaterThanEquals.cs @@ -25,8 +25,8 @@ public override object GetValue(ExecutionContext context) } if (left is long i1) { - if (right is double d2) return i1 >= d2; if (right is long i2) return i1 >= i2; + if (right is double d2) return i1 >= d2; } else if (left is double d1) { @@ -36,12 +36,13 @@ public override object GetValue(ExecutionContext context) } else if (left is ulong u1) { - if (right is double d2) return u1 >= d2; if (right is ulong u2) return u1 >= u2; + if (right is double d2) return u1 >= d2; } if (!context.fimp) return (left as IComparable).CompareTo(right) >= 0; - throw new OperatorError(this, left?.GetType(), right?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType(), right?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryLessThan.cs b/SLThree/Lexems/Expressions/ExpressionBinaryLessThan.cs index 2e290c4..22fc436 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryLessThan.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryLessThan.cs @@ -25,8 +25,8 @@ public override object GetValue(ExecutionContext context) } if (left is long i1) { - if (right is double d2) return i1 < d2; if (right is long i2) return i1 < i2; + if (right is double d2) return i1 < d2; } else if (left is double d1) { @@ -36,12 +36,13 @@ public override object GetValue(ExecutionContext context) } else if (left is ulong u1) { - if (right is double d2) return u1 < d2; if (right is ulong u2) return u1 < u2; + if (right is double d2) return u1 < d2; } if (!context.fimp) return (left as IComparable).CompareTo(right) < 0; - throw new OperatorError(this, left?.GetType(), right?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType(), right?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryLessThanEquals.cs b/SLThree/Lexems/Expressions/ExpressionBinaryLessThanEquals.cs index 0ce1c95..6c0930e 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryLessThanEquals.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryLessThanEquals.cs @@ -25,8 +25,8 @@ public override object GetValue(ExecutionContext context) } if (left is long i1) { - if (right is double d2) return i1 <= d2; if (right is long i2) return i1 <= i2; + if (right is double d2) return i1 <= d2; } else if (left is double d1) { @@ -36,12 +36,13 @@ public override object GetValue(ExecutionContext context) } else if (left is ulong u1) { - if (right is double d2) return u1 <= d2; if (right is ulong u2) return u1 <= u2; + if (right is double d2) return u1 <= d2; } if (!context.fimp) return (left as IComparable).CompareTo(right) <= 0; - throw new OperatorError(this, left?.GetType(), right?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType(), right?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryMod.cs b/SLThree/Lexems/Expressions/ExpressionBinaryMod.cs index 1a1e6eb..f4f12e3 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryMod.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryMod.cs @@ -24,8 +24,8 @@ public override object GetValue(ExecutionContext context) } if (left is long i1) { - if (right is double d2) return i1 % d2; if (right is long i2) return i1 % i2; + if (right is double d2) return i1 % d2; } else if (left is double d1) { @@ -35,10 +35,11 @@ public override object GetValue(ExecutionContext context) } else if (left is ulong u1) { - if (right is double d2) return u1 % d2; if (right is ulong u2) return u1 % u2; + if (right is double d2) return u1 % d2; } - throw new OperatorError(this, left?.GetType(), right?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType(), right?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryMultiply.cs b/SLThree/Lexems/Expressions/ExpressionBinaryMultiply.cs index 632fcc6..1690592 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryMultiply.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryMultiply.cs @@ -25,8 +25,8 @@ public override object GetValue(ExecutionContext context) } if (left is long i1) { - if (right is double d2) return i1 * d2; if (right is long i2) return i1 * i2; + if (right is double d2) return i1 * d2; } else if (left is double d1) { @@ -36,10 +36,11 @@ public override object GetValue(ExecutionContext context) } else if (left is ulong u1) { - if (right is double d2) return u1 * d2; if (right is ulong u2) return u1 * u2; + if (right is double d2) return u1 * d2; } - throw new OperatorError(this, left?.GetType(), right?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType(), right?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryOr.cs b/SLThree/Lexems/Expressions/ExpressionBinaryOr.cs index 8282302..04bea9b 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryOr.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryOr.cs @@ -12,7 +12,8 @@ public override object GetValue(ExecutionContext context) object left = Left.GetValue(context); object right = Right.GetValue(context); if (left is bool b1 && right is bool b2) return b1 || b2; - throw new OperatorError(this, left?.GetType(), right?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType(), right?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryRem.cs b/SLThree/Lexems/Expressions/ExpressionBinaryRem.cs index 2ab2b87..13e79ff 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryRem.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryRem.cs @@ -30,8 +30,8 @@ public override object GetValue(ExecutionContext context) } if (left is long i1) { - if (right is double d2) return i1 - d2; if (right is long i2) return i1 - i2; + if (right is double d2) return i1 - d2; } else if (left is double d1) { @@ -41,10 +41,11 @@ public override object GetValue(ExecutionContext context) } else if (left is ulong u1) { - if (right is double d2) return u1 - d2; if (right is ulong u2) return u1 - u2; + if (right is double d2) return u1 - d2; } - throw new OperatorError(this, left?.GetType(), right?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType(), right?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryUnequals.cs b/SLThree/Lexems/Expressions/ExpressionBinaryUnequals.cs index 9397112..03d5931 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryUnequals.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryUnequals.cs @@ -25,8 +25,8 @@ public override object GetValue(ExecutionContext context) } if (left is long i1) { - if (right is double d2) return i1 != d2; if (right is long i2) return i1 != i2; + if (right is double d2) return i1 != d2; } else if (left is double d1) { @@ -36,12 +36,13 @@ public override object GetValue(ExecutionContext context) } else if (left is ulong u1) { - if (right is double d2) return u1 != d2; if (right is ulong u2) return u1 != u2; + if (right is double d2) return u1 != d2; } if (!context.fimp) return (left as IComparable).CompareTo(right) != 0; - throw new OperatorError(this, left?.GetType(), right?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType(), right?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/ExpressionTernary.cs b/SLThree/Lexems/Expressions/ExpressionTernary.cs index ebfab87..4444d2f 100644 --- a/SLThree/Lexems/Expressions/ExpressionTernary.cs +++ b/SLThree/Lexems/Expressions/ExpressionTernary.cs @@ -19,11 +19,10 @@ public ExpressionTernary(BaseLexem cond, BaseLexem left, BaseLexem right, Cursor public ExpressionTernary() : base(default) { } public override object GetValue(ExecutionContext context) { - object cond = Condition.GetValue(context); - object left = Left.GetValue(context); - object right = Right.GetValue(context); - if (cond is bool b1) return b1 ? left : right; - throw new OperatorError(Operator, cond?.GetType(), SourceContext); + var cond = Condition.GetValue(context); + var left = Left.GetValue(context); + var right = Right.GetValue(context); + return (bool)cond ? left : right; } public override string ToString() => $"{Condition} ? {Left} : {Right}"; diff --git a/SLThree/Lexems/Expressions/ExpressionUnaryAdd.cs b/SLThree/Lexems/Expressions/ExpressionUnaryAdd.cs index f7edc72..5d9da2c 100644 --- a/SLThree/Lexems/Expressions/ExpressionUnaryAdd.cs +++ b/SLThree/Lexems/Expressions/ExpressionUnaryAdd.cs @@ -25,7 +25,8 @@ public override object GetValue(ExecutionContext context) case ulong v: return +v; case double v: return +v; } - throw new OperatorError(this, left?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/ExpressionUnaryBitNot.cs b/SLThree/Lexems/Expressions/ExpressionUnaryBitNot.cs index 8598a1a..ab92954 100644 --- a/SLThree/Lexems/Expressions/ExpressionUnaryBitNot.cs +++ b/SLThree/Lexems/Expressions/ExpressionUnaryBitNot.cs @@ -24,7 +24,8 @@ public override object GetValue(ExecutionContext context) case long v: return ~v; case ulong v: return ~v; } - throw new OperatorError(this, left?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/ExpressionUnaryNot.cs b/SLThree/Lexems/Expressions/ExpressionUnaryNot.cs index ce7cfad..0165add 100644 --- a/SLThree/Lexems/Expressions/ExpressionUnaryNot.cs +++ b/SLThree/Lexems/Expressions/ExpressionUnaryNot.cs @@ -23,7 +23,8 @@ public override object GetValue(ExecutionContext context) { case bool b: return !b; } - throw new OperatorError(this, left?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/ExpressionUnaryRem.cs b/SLThree/Lexems/Expressions/ExpressionUnaryRem.cs index d1af362..2999122 100644 --- a/SLThree/Lexems/Expressions/ExpressionUnaryRem.cs +++ b/SLThree/Lexems/Expressions/ExpressionUnaryRem.cs @@ -24,7 +24,8 @@ public override object GetValue(ExecutionContext context) case long v: return -v; case double v: return -v; } - throw new OperatorError(this, left?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/MemberAccess.cs b/SLThree/Lexems/Expressions/MemberAccess.cs index 98b180a..fc079af 100644 --- a/SLThree/Lexems/Expressions/MemberAccess.cs +++ b/SLThree/Lexems/Expressions/MemberAccess.cs @@ -57,7 +57,7 @@ public override object GetValue(ExecutionContext context) else if (counted_contextwrapcache2) { if (is_unwrap) return (left as ExecutionContext.ContextWrap).pred; - else return (Right as InvokeLexem).GetValue((left as ExecutionContext.ContextWrap).pred, (Right as InvokeLexem).Arguments.Select(x => x.GetValue(context)).ToArray()); + else return (Right as InvokeLexem).GetValue((left as ExecutionContext.ContextWrap).pred, (Right as InvokeLexem).Arguments.ConvertAll(x => x.GetValue(context))); } if (left != null) diff --git a/SLThree/Lexems/InvokeLexem.cs b/SLThree/Lexems/InvokeLexem.cs index d014b57..46051aa 100644 --- a/SLThree/Lexems/InvokeLexem.cs +++ b/SLThree/Lexems/InvokeLexem.cs @@ -29,21 +29,22 @@ public object GetValue(ExecutionContext context, object[] args) get_name = Name.ToString().Replace(" ", ""); get_counted_name = true; } + var o = context.LocalVariables.GetValue(get_name).Item1; if (o == null) throw new RuntimeError($"Method {get_name}(_) not found", SourceContext); - if (o is BaseLexem bl) return bl.GetValue(context); + if (o is Method method) + { + if (method.ParamNames.Length != args.Length) throw new RuntimeError("Call with wrong arguments count", SourceContext); + return method.GetValue(context, args); + } else if (o is MethodInfo mi) { if (!mi.IsStatic) return mi.Invoke(args[0], args.Skip(1).ToArray()); else return mi.Invoke(null, args); } - else if (o is Method method) - { - if (method.ParamNames.Length != args.Length) throw new RuntimeError("Call with wrong arguments count", SourceContext); - return method.GetValue(context, args); - } + else if (o is BaseLexem bl) return bl.GetValue(context); else { var type = o.GetType(); diff --git a/SLThree/Lexems/Literals/Literal.cs b/SLThree/Lexems/Literals/Literal.cs index da12d64..6af4ea5 100644 --- a/SLThree/Lexems/Literals/Literal.cs +++ b/SLThree/Lexems/Literals/Literal.cs @@ -5,7 +5,7 @@ namespace SLThree { public partial class Literal : BaseLexem { - public T Value; + public object Value; public Literal() : this(default, default) { } public Literal(T value, Cursor cursor) : base(cursor) { diff --git a/SLThree/Properties/AssemblyInfo.cs b/SLThree/Properties/AssemblyInfo.cs index 7f31404..b5c9d29 100644 --- a/SLThree/Properties/AssemblyInfo.cs +++ b/SLThree/Properties/AssemblyInfo.cs @@ -43,8 +43,8 @@ public static class SLTVersion { public const string Major = "0"; //vh public const string Minor = "2"; //vh public const string Build = "0"; //vh - public const string Revision = "710"; //vh - public const long LastUpdate = 638345151568919183; //vh + public const string Revision = "762"; //vh + public const long LastUpdate = 638345449084390873; //vh public const string Version = Major + "." + Minor + "." + Build + "." + Revision; public const string VersionWithoutRevision = Major + "." + Minor + "." + Build; diff --git a/SLThree/Statements/ConditionStatement.cs b/SLThree/Statements/ConditionStatement.cs index 8462cca..5c65380 100644 --- a/SLThree/Statements/ConditionStatement.cs +++ b/SLThree/Statements/ConditionStatement.cs @@ -2,6 +2,7 @@ using SLThree.Extensions; using System; using System.Collections.Generic; +using System.Diagnostics.PerformanceData; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -11,21 +12,34 @@ namespace SLThree public class ConditionStatement : BaseStatement { public BaseLexem Condition { get; set; } - public BaseStatement TrueBlock { get; set; } - public BaseStatement FalseBlock { get; set; } + public BaseStatement[] Body { get; set; } - public ConditionStatement(BaseLexem condition, BaseStatement trueBlock, BaseStatement falseBlock, Cursor cursor) : base(cursor) + public ConditionStatement(BaseLexem condition, StatementListStatement trueBlock, StatementListStatement falseBlock, Cursor cursor) : base(cursor) { Condition = condition; - TrueBlock = trueBlock; - FalseBlock = falseBlock; + count = trueBlock.Statements.Count + falseBlock.Statements.Count; + Body = new BaseStatement[count]; + trueBlock.Statements.CopyTo(Body, 0); + falsestart = trueBlock.Statements.Count; + falseBlock.Statements.CopyTo(Body, falsestart); } + private int count; + private int falsestart; - public override string ToString() => $"if ({Condition}) {{{TrueBlock}}}{(FalseBlock)}"; + public override string ToString() => $"if ({Condition}) {{{Body}}}"; public override object GetValue(ExecutionContext context) - => Condition.GetValue(context).Cast() - ? TrueBlock.GetValue(context) - : FalseBlock.GetValue(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; + } } } diff --git a/SLThree/Statements/ForeachCycleStatement.cs b/SLThree/Statements/ForeachCycleStatement.cs index 824cacd..a6e8ae7 100644 --- a/SLThree/Statements/ForeachCycleStatement.cs +++ b/SLThree/Statements/ForeachCycleStatement.cs @@ -9,17 +9,19 @@ public class ForeachCycleStatement : BaseStatement { public NameLexem Name { get; set; } public BaseLexem Iterator { get; set; } - public StatementListStatement CycleBody { get; set; } + public BaseStatement[] CycleBody { get; set; } public ForeachCycleStatement(NameLexem name, BaseLexem iterator, StatementListStatement cycleBody, Cursor cursor) : base(cursor) { Name = name; Iterator = iterator; - CycleBody = cycleBody; + CycleBody = cycleBody.Statements.ToArray(); + count = CycleBody.Length; } private ExecutionContext last_context; private int variable_index; + private int count; public override object GetValue(ExecutionContext context) { var iterator = Iterator.GetValue(context).Cast(); @@ -34,9 +36,9 @@ public override object GetValue(ExecutionContext context) while (enumerator.MoveNext()) { context.LocalVariables.SetValue(variable_index, enumerator.Current); - for (var i = 0; i < CycleBody.Statements.Count; i++) + for (var i = 0; i < count; i++) { - ret = CycleBody.Statements[i].GetValue(context); + ret = CycleBody[i].GetValue(context); if (context.Returned || context.Broken) break; if (context.Continued) continue; } diff --git a/SLThree/Statements/StatementListStatement.cs b/SLThree/Statements/StatementListStatement.cs index a3d6b22..09d502b 100644 --- a/SLThree/Statements/StatementListStatement.cs +++ b/SLThree/Statements/StatementListStatement.cs @@ -12,10 +12,12 @@ namespace SLThree public class StatementListStatement : BaseStatement { public IList Statements; + private int count; public StatementListStatement(IList statements, Cursor cursor) : base(cursor) { Statements = statements; + count = statements.Count; } public override string ToString() => $"{Statements.Count} statements"; @@ -23,10 +25,10 @@ public StatementListStatement(IList statements, Cursor cursor) : public override object GetValue(ExecutionContext context) { var ret = default(object); - for (var i = 0; i < Statements.Count; i++) + for (var i = 0; i < count; i++) { ret = Statements[i].GetValue(context); - if (context.Returned || (context.InCycle() && (context.Broken || context.Continued))) break; + if (context.Returned || context.Broken || context.Continued) break; } return ret; } diff --git a/SLThree/Statements/WhileCycleStatement.cs b/SLThree/Statements/WhileCycleStatement.cs index dfee04c..2cabf4e 100644 --- a/SLThree/Statements/WhileCycleStatement.cs +++ b/SLThree/Statements/WhileCycleStatement.cs @@ -11,25 +11,27 @@ namespace SLThree public class WhileCycleStatement : BaseStatement { public BaseLexem Condition { get; set; } - public StatementListStatement CycleBody { get; set; } + public BaseStatement[] CycleBody { get; set; } public WhileCycleStatement(BaseLexem condition, StatementListStatement cycleBody, Cursor cursor) : base(cursor) { Condition = condition; - CycleBody = cycleBody; + CycleBody = cycleBody.Statements.ToArray(); + count = CycleBody.Length; } public override string ToString() => $"while ({Condition}) {{{CycleBody}}}"; + private int count; public override object GetValue(ExecutionContext context) { var ret = default(object); context.StartCycle(); - while (Condition.GetValue(context).Cast()) + while ((bool)Condition.GetValue(context)) { - for (var i = 0; i < CycleBody.Statements.Count; i++) + for (var i = 0; i < count; i++) { - ret = CycleBody.Statements[i].GetValue(context); + ret = CycleBody[i].GetValue(context); if (context.Returned || context.Broken) break; if (context.Continued) continue; } diff --git a/SLThree/docs/versions/0.3.0 b/SLThree/docs/versions/0.3.0 index ce043bd..ca9d0b5 100644 --- a/SLThree/docs/versions/0.3.0 +++ b/SLThree/docs/versions/0.3.0 @@ -6,4 +6,6 @@ Language: - Logical operators (&&, ||) and binary bit operators (&, |, ^) - Ternary operator Embedding: - - Wrapping classes in context, wrapping static members and classes \ No newline at end of file + - Wrapping classes in context, wrapping static members and classes +Optimization: + - >40% (collatz_conjecture 14 s => 8 s) \ No newline at end of file diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index f8157b5..9cdb2c3 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -94,17 +94,17 @@ ternary_0 -memoize / binary_7 binary_7 -memoize - = left:binary_7 _ "||" right:binary_6 { new ExpressionBinaryOr(left, right, state) } + = left:binary_7 _ "||" _ right:binary_6 { new ExpressionBinaryOr(left, right, state) } / binary_6 binary_6 -memoize - = left:binary_6 _ "&&" right:binary_5 { new ExpressionBinaryAnd(left, right, state) } + = left:binary_6 _ "&&" _ right:binary_5 { new ExpressionBinaryAnd(left, right, state) } / binary_5 binary_5 -memoize - = left:binary_5 _ "&" right:binary_4 { new ExpressionBinaryBitAnd(left, right, state) } - / left:binary_5 _ "^" right:binary_4 { new ExpressionBinaryBitXor(left, right, state) } - / left:binary_5 _ "|" right:binary_4 { new ExpressionBinaryBitOr(left, right, state) } + = left:binary_5 _ "&" _ right:binary_4 { new ExpressionBinaryBitAnd(left, right, state) } + / left:binary_5 _ "^" _ right:binary_4 { new ExpressionBinaryBitXor(left, right, state) } + / left:binary_5 _ "|" _ right:binary_4 { new ExpressionBinaryBitOr(left, right, state) } / binary_4 binary_4 -memoize From 9b4be8839e1f7852c13526a140e1f21df848d58d Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 2 Nov 2023 21:10:01 +0300 Subject: [PATCH 10/15] fix #28 --- SLThree/Properties/AssemblyInfo.cs | 4 ++-- SLThree/syntax.peg | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/SLThree/Properties/AssemblyInfo.cs b/SLThree/Properties/AssemblyInfo.cs index b5c9d29..315ac1a 100644 --- a/SLThree/Properties/AssemblyInfo.cs +++ b/SLThree/Properties/AssemblyInfo.cs @@ -43,8 +43,8 @@ public static class SLTVersion { public const string Major = "0"; //vh public const string Minor = "2"; //vh public const string Build = "0"; //vh - public const string Revision = "762"; //vh - public const long LastUpdate = 638345449084390873; //vh + public const string Revision = "764"; //vh + public const long LastUpdate = 638345453362770753; //vh public const string Version = Major + "." + Minor + "." + Build + "." + Revision; public const string VersionWithoutRevision = Major + "." + Minor + "." + Build; diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index 9cdb2c3..5af3b3b 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -33,8 +33,8 @@ statement / _ st:expr_statement _ { st } using_statement - = "using" _ ex: as_expr_right _ "as" _ n:name { new UsingStatement(ex, n.Name, state) } - / "using" _ ex: as_expr_right { new UsingStatement(ex, state) } + = "using" _required_ ex: as_expr_right _required_ "as" _required_ n:name { new UsingStatement(ex, n.Name, state) } + / "using" _required_ ex: as_expr_right { new UsingStatement(ex, state) } return_statement = "return" _ lex:lexem { new ReturnStatement(lex, state) } @@ -136,7 +136,7 @@ implicit_keyword = s:"implicit" { s } binary_3 -memoize - = left:binary_3 _ "as" _ right:as_expr_right { new CastLexem(left, right, state) } + = left:binary_3 _ "as" _required_ right:as_expr_right { new CastLexem(left, right, state) } / left:binary_3 _ ">=" _ right:binary_2 { new ExpressionBinaryGreaterThanEquals(left, right, state) } / left:binary_3 _ "<=" _ right:binary_2 { new ExpressionBinaryLessThanEquals(left, right, state) } / left:binary_3 _ ">" _ right:binary_2 { new ExpressionBinaryGreaterThan(left, right, state) } From 445008fda8cd5e9465ff3d4f3a53856a4286066f Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 2 Nov 2023 22:07:56 +0300 Subject: [PATCH 11/15] fix #11 + assign by indexator --- .../{ArrayInitializer.cs => CreatorArray.cs} | 4 +- SLThree/Lexems/CreatorDictionary.cs | 40 ++++++++++++ SLThree/Lexems/CreatorTuple.cs | 47 ++++++++++++++ .../Expressions/ExpressionBinaryAssign.cs | 15 +++-- SLThree/Lexems/IndexLexem.cs | 61 ++++++++++++++++--- SLThree/Properties/AssemblyInfo.cs | 4 +- SLThree/SLThree.csproj | 4 +- SLThree/syntax.peg | 20 +++++- 8 files changed, 173 insertions(+), 22 deletions(-) rename SLThree/Lexems/{ArrayInitializer.cs => CreatorArray.cs} (77%) create mode 100644 SLThree/Lexems/CreatorDictionary.cs create mode 100644 SLThree/Lexems/CreatorTuple.cs diff --git a/SLThree/Lexems/ArrayInitializer.cs b/SLThree/Lexems/CreatorArray.cs similarity index 77% rename from SLThree/Lexems/ArrayInitializer.cs rename to SLThree/Lexems/CreatorArray.cs index 00b3491..2d0a721 100644 --- a/SLThree/Lexems/ArrayInitializer.cs +++ b/SLThree/Lexems/CreatorArray.cs @@ -4,11 +4,11 @@ namespace SLThree { - public class ArrayInitializer : BaseLexem + public class CreatorArray : BaseLexem { public BaseLexem[] Lexems; - public ArrayInitializer(BaseLexem[] lexems, Cursor cursor) : base(cursor) + public CreatorArray(BaseLexem[] lexems, Cursor cursor) : base(cursor) { Lexems = lexems; } diff --git a/SLThree/Lexems/CreatorDictionary.cs b/SLThree/Lexems/CreatorDictionary.cs new file mode 100644 index 0000000..2413d9a --- /dev/null +++ b/SLThree/Lexems/CreatorDictionary.cs @@ -0,0 +1,40 @@ +using Pegasus.Common; +using SLThree.Extensions; +using System.Collections.Generic; +using System.Linq; + +namespace SLThree +{ + public class CreatorDictionary : BaseLexem + { + public class Entry : BaseLexem + { + public BaseLexem Key; + public BaseLexem Value; + public Entry(BaseLexem key, BaseLexem value, Cursor cursor) : base(cursor) + { + Key = key; + Value = value; + } + public override object GetValue(ExecutionContext context) + { + return new KeyValuePair(Key.GetValue(context), Value.GetValue(context)); + } + public override string ToString() => $"{Key}: {Value}"; + } + + public Entry[] Entries; + + public CreatorDictionary(Entry[] entries, Cursor cursor) : base(cursor) + { + Entries = entries; + } + + public override object GetValue(ExecutionContext context) + { + return Entries.Select(x => (KeyValuePair)x.GetValue(context)).ToDictionary(x => x.Key, x => x.Value); + } + + public override string ToString() => $"{{{Entries.JoinIntoString(", ")}}}"; + } +} diff --git a/SLThree/Lexems/CreatorTuple.cs b/SLThree/Lexems/CreatorTuple.cs new file mode 100644 index 0000000..6e7fd9d --- /dev/null +++ b/SLThree/Lexems/CreatorTuple.cs @@ -0,0 +1,47 @@ +using Pegasus.Common; +using SLThree.Extensions; +using System; +using System.Linq; +using System.Runtime.CompilerServices; + +namespace SLThree +{ + public class CreatorTuple : BaseLexem + { + public BaseLexem[] Lexems; + + public CreatorTuple(BaseLexem[] lexems, Cursor cursor) : base(cursor) + { + Lexems = lexems; + } + + public override object GetValue(ExecutionContext context) + { + return Create(Lexems.ConvertAll(x => x.GetValue(context))); + } + + public static ITuple Create(object[] objs, int index = 0) + { + switch (objs.Length - index) + { + case 0: throw new ArgumentException("Zero length array in objs"); + case 1: return new Tuple(objs[index]); + case 2: return new Tuple(objs[index], objs[index + 1]); + case 3: return new Tuple(objs[index + 0], objs[index + 1], objs[index + 2]); + case 4: return new Tuple(objs[index + 0], objs[index + 1], objs[index + 2], objs[index + 3]); + case 5: return new Tuple(objs[index + 0], objs[index + 1], objs[index + 2], objs[index + 3], objs[index + 4]); + case 6: return new Tuple(objs[index + 0], objs[index + 1], objs[index + 2], objs[index + 3], objs[index + 4], objs[index + 5]); + case 7: return new Tuple(objs[index + 0], objs[index + 1], objs[index + 2], objs[index + 3], objs[index + 4], objs[index + 5], objs[index + 6]); + default: return new Tuple(objs[index + 0], objs[index + 1], objs[index + 2], objs[index + 3], objs[index + 4], objs[index + 5], objs[index + 6], Create(objs, index + 7)); + } + } + public static object[] ToArray(ITuple tuple) + { + var ret = new object[tuple.Length]; + for (var i = 0; i < tuple.Length; i++) + ret[i] = tuple[i]; + return ret; + } + public override string ToString() => $"({Lexems.JoinIntoString(", ")})"; + } +} diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryAssign.cs b/SLThree/Lexems/Expressions/ExpressionBinaryAssign.cs index bd680e7..1f97a6c 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryAssign.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryAssign.cs @@ -20,16 +20,21 @@ public override object GetValue(ExecutionContext context) } else { - if (Left is MemberAccess memberAccess) + if (Left is NameLexem nl) + { + variable_index = context.LocalVariables.SetValue(nl.Name, right); + is_namelexem = true; + counted_invoked = context; + return right; + } + else if (Left is MemberAccess memberAccess) { memberAccess.SetValue(context, right); return right; } - else if (Left is NameLexem nl) + else if (Left is IndexLexem indexLexem) { - variable_index = context.LocalVariables.SetValue(nl.Name, right); - is_namelexem = true; - counted_invoked = context; + indexLexem.SetValue(context, right); return right; } } diff --git a/SLThree/Lexems/IndexLexem.cs b/SLThree/Lexems/IndexLexem.cs index 820a838..898838b 100644 --- a/SLThree/Lexems/IndexLexem.cs +++ b/SLThree/Lexems/IndexLexem.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Linq; using System.Reflection; +using System.Runtime.CompilerServices; namespace SLThree { @@ -20,19 +21,16 @@ public IndexLexem(BaseLexem lexem, BaseLexem[] arguments, Cursor cursor) : base( private int Mode = 0; // 1 - array, 2 - list, 3 - tuple, 4 - any private PropertyInfo PropertyInfo; - public override object GetValue(ExecutionContext context) + private void CalcMode(object o) { - var o = Lexem.GetValue(context); - - if (o == null) return null; - + var type = o.GetType(); + Mode = type.IsArray ? 1 : 0; if (Mode == 0) { - var type = o.GetType(); - Mode = type.IsArray ? 1 : 0; + Mode = type.IsList() ? 1 : 0; if (Mode == 0) { - Mode = type.IsList() ? 1 : 0; + Mode = type.GetInterfaces().Any(x => x == typeof(ITuple)) ? 3 : 0; if (Mode == 0) { while (PropertyInfo == null && type != null) @@ -40,11 +38,26 @@ public override object GetValue(ExecutionContext context) PropertyInfo = type.GetProperties(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault(x => x.GetIndexParameters().Length == Arguments.Length); if (PropertyInfo == null) type = type.BaseType; } - if (PropertyInfo == null) return null; - Mode = 4; + if (PropertyInfo == null) + { + Mode = int.MaxValue; + } + else Mode = 4; } } } + } + + public override object GetValue(ExecutionContext context) + { + var o = Lexem.GetValue(context); + + if (o == null) return null; + + if (Mode == 0) + { + CalcMode(o); + } switch (Mode) { @@ -52,10 +65,38 @@ public override object GetValue(ExecutionContext context) { return o.Cast()[context.fimp ? Arguments[0].GetValue(context).Cast() : Arguments[0].GetValue(context).CastToType(typeof(int)).Cast()]; } + case 3: + { + return o.Cast()[context.fimp ? Arguments[0].GetValue(context).Cast() : Arguments[0].GetValue(context).CastToType(typeof(int)).Cast()]; + } case 4: return PropertyInfo.GetValue(o, Arguments.ConvertAll(x => x.GetValue(context))); } return null; } + + public object SetValue(ExecutionContext context, object value) + { + var o = Lexem.GetValue(context); + + if (o == null) return null; + + if (Mode == 0) + { + CalcMode(o); + } + + switch (Mode) + { + case 1: + { + return o.Cast()[context.fimp ? Arguments[0].GetValue(context).Cast() : Arguments[0].GetValue(context).CastToType(typeof(int)).Cast()] = value; + } + case 4: + PropertyInfo.SetValue(o, value, Arguments.ConvertAll(x => x.GetValue(context))); + break; + } + return value; + } public override string ToString() => $"{Lexem}[{Arguments.JoinIntoString(", ")}]"; } diff --git a/SLThree/Properties/AssemblyInfo.cs b/SLThree/Properties/AssemblyInfo.cs index 315ac1a..6935a6f 100644 --- a/SLThree/Properties/AssemblyInfo.cs +++ b/SLThree/Properties/AssemblyInfo.cs @@ -43,8 +43,8 @@ public static class SLTVersion { public const string Major = "0"; //vh public const string Minor = "2"; //vh public const string Build = "0"; //vh - public const string Revision = "764"; //vh - public const long LastUpdate = 638345453362770753; //vh + public const string Revision = "778"; //vh + public const long LastUpdate = 638345483712300651; //vh public const string Version = Major + "." + Minor + "." + Build + "." + Revision; public const string VersionWithoutRevision = Major + "." + Minor + "." + Build; diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 93c2d43..3147c9e 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -50,8 +50,9 @@ - + + @@ -101,6 +102,7 @@ + diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index 5af3b3b..1b48949 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -184,13 +184,29 @@ primary -memoize / left:primary _ "[" _ args:arguments_list _ "]" { new IndexLexem(left, args.ToArray(), state) } / "typeof" _ "(" _ left:primary _ ")" { new TypeofLexem(left, state) } / invoke_lexem + / tuple_creator + / dictionary_creator / list_creator / literal / name +dictionary_creator + = "{" _ etrs:dictionary_entries _ "}" { new CreatorDictionary(etrs.ToArray(), state) } + +dictionary_entries > + = first:dictionary_entry _ oth:other_entry* { oth.AddAndRet(first) } + +other_entry = ("," _ a:dictionary_entry _ ) { a } + +dictionary_entry + = left:primary _ ":" _ right:lexem { new CreatorDictionary.Entry(left, right, state) } + +tuple_creator + = "(" _ args:arguments_list _ ")" { new CreatorTuple(args.ToArray(), state) } + list_creator - = "[" _ args:arguments_list _ "]" { new ArrayInitializer(args.ToArray(), state) } - / "[" _ "]" { new ArrayInitializer(new BaseLexem[0], state) } + = "[" _ args:arguments_list _ "]" { new CreatorArray(args.ToArray(), state) } + / "[" _ "]" { new CreatorArray(new BaseLexem[0], state) } invoke_lexem = left:identifier _ "(" _ args:arguments_list _ ")" { new InvokeLexem(left, args.ToArray(), state) } From 67e0ac68618ca9f338be20cb989c2ca6f640be6e Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Thu, 2 Nov 2023 22:48:41 +0300 Subject: [PATCH 12/15] fix #27 --- .../Lexems/Expressions/ExpressionBinaryAnd.cs | 3 +- .../Expressions/ExpressionBinaryBitAnd.cs | 3 +- .../Expressions/ExpressionBinaryBitOr.cs | 3 +- .../Expressions/ExpressionBinaryBitXor.cs | 3 +- SLThree/LocalVariablesContainer.cs | 11 ++-- SLThree/Properties/AssemblyInfo.cs | 4 +- SLThree/syntax.peg | 59 +++++++++++++------ 7 files changed, 58 insertions(+), 28 deletions(-) diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryAnd.cs b/SLThree/Lexems/Expressions/ExpressionBinaryAnd.cs index 40a2e20..6770f3e 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryAnd.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryAnd.cs @@ -12,7 +12,8 @@ public override object GetValue(ExecutionContext context) object left = Left.GetValue(context); object right = Right.GetValue(context); if (left is bool b1 && right is bool b2) return b1 && b2; - throw new OperatorError(this, left?.GetType(), right?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType(), right?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryBitAnd.cs b/SLThree/Lexems/Expressions/ExpressionBinaryBitAnd.cs index 89b46e5..0b5974a 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryBitAnd.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryBitAnd.cs @@ -31,7 +31,8 @@ public override object GetValue(ExecutionContext context) { if (right is ulong u2) return u1 & u2; } - throw new OperatorError(this, left?.GetType(), right?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType(), right?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryBitOr.cs b/SLThree/Lexems/Expressions/ExpressionBinaryBitOr.cs index fa35153..76b7e65 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryBitOr.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryBitOr.cs @@ -31,7 +31,8 @@ public override object GetValue(ExecutionContext context) { if (right is ulong u2) return u1 | u2; } - throw new OperatorError(this, left?.GetType(), right?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType(), right?.GetType())); + return null; } } } diff --git a/SLThree/Lexems/Expressions/ExpressionBinaryBitXor.cs b/SLThree/Lexems/Expressions/ExpressionBinaryBitXor.cs index fc4cf57..5a047ea 100644 --- a/SLThree/Lexems/Expressions/ExpressionBinaryBitXor.cs +++ b/SLThree/Lexems/Expressions/ExpressionBinaryBitXor.cs @@ -31,7 +31,8 @@ public override object GetValue(ExecutionContext context) { if (right is ulong u2) return u1 ^ u2; } - throw new OperatorError(this, left?.GetType(), right?.GetType()); + context.Errors.Add(new OperatorError(this, left?.GetType(), right?.GetType())); + return null; } } } diff --git a/SLThree/LocalVariablesContainer.cs b/SLThree/LocalVariablesContainer.cs index 93d7845..bab6cc7 100644 --- a/SLThree/LocalVariablesContainer.cs +++ b/SLThree/LocalVariablesContainer.cs @@ -11,6 +11,7 @@ public LocalVariablesContainer() } + internal int current = 0; internal object[] Variables = new object[8]; public Dictionary NamedIdenificators = new Dictionary(); @@ -33,6 +34,7 @@ private void Expand() public void FillArguments(Method method, object[] args) { if (Variables.Length <= args.Length) Variables = new object[8 + args.Length + Variables.Length]; + if (current <= args.Length) current = args.Length; args.CopyTo(Variables, 0); for (var i = 0; i < args.Length; i++) NamedIdenificators[method.ParamNames[i]] = i; @@ -48,11 +50,10 @@ public int SetValue(string name, object value) } else { - if (NamedIdenificators.Count >= Variables.Length) Expand(); - var count = NamedIdenificators.Count; - Variables[count] = value; - NamedIdenificators[name] = count; - return count; + if (current >= Variables.Length) Expand(); + Variables[current] = value; + NamedIdenificators[name] = current; + return current++; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/SLThree/Properties/AssemblyInfo.cs b/SLThree/Properties/AssemblyInfo.cs index 6935a6f..939a9b0 100644 --- a/SLThree/Properties/AssemblyInfo.cs +++ b/SLThree/Properties/AssemblyInfo.cs @@ -43,8 +43,8 @@ public static class SLTVersion { public const string Major = "0"; //vh public const string Minor = "2"; //vh public const string Build = "0"; //vh - public const string Revision = "778"; //vh - public const long LastUpdate = 638345483712300651; //vh + public const string Revision = "797"; //vh + public const long LastUpdate = 638345509453743994; //vh public const string Version = Major + "." + Minor + "." + Build + "." + Revision; public const string VersionWithoutRevision = Major + "." + Minor + "." + Build; diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index 1b48949..5ed6887 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -158,8 +158,8 @@ binary_0 = _ left:binary_min _ { left } binary_min - = "(" _ bin:binary_4 _ ")" { bin } - / _ u:unary _ { u } + //= "(" _ bin:binary_9 _ ")" { bin } + = _ u:unary _ { u } unary = "+" _ left:binary_min { new ExpressionUnaryAdd(left, state) } @@ -177,18 +177,21 @@ as_expr_right -memoize / right:name { right } primary -memoize - = left:primary _ "." _ right:invoke_lexem { new MemberAccess(left, right, state) } + = "(" _ left:lexem _ ")" _ "." _ right:invoke_lexem { new MemberAccess(left, right, state) } + / left:primary _ "." _ right:invoke_lexem { new MemberAccess(left, right, state) } / left:primary _ "." _ right:name { new MemberAccess(left, right, state) } / "new" _ right:invoke_lexem { new NewLexem(right as InvokeLexem, state) } / "new" _ right:primary { new NewLexem(right as MemberAccess, state) } / left:primary _ "[" _ args:arguments_list _ "]" { new IndexLexem(left, args.ToArray(), state) } / "typeof" _ "(" _ left:primary _ ")" { new TypeofLexem(left, state) } / invoke_lexem + / "(" _ x:lexem _ ")" { x } / tuple_creator / dictionary_creator / list_creator - / literal + / special / name + / literal dictionary_creator = "{" _ etrs:dictionary_entries _ "}" { new CreatorDictionary(etrs.ToArray(), state) } @@ -226,23 +229,45 @@ other_arg_name = ("," _ a:arg_name _ ) { a } arg_name = name -literal - = f32:([0-9]+ ("." [0-9]+)? ("f32")) { new FloatLiteral(float.Parse(f32.Replace("f32", ""), CultureInfo.InvariantCulture), state) } - / f64:([0-9]+ ("." [0-9]+) ("f64")?) { new DoubleLiteral(double.Parse(f64.Replace("f64", ""), CultureInfo.InvariantCulture), state) } - / f64:([0-9]+ ("f64")) { new DoubleLiteral(double.Parse(f64.Replace("f64", ""), CultureInfo.InvariantCulture), state) } - / i8:([0-9]+ ("i8")) { new SByteLiteral(sbyte.Parse(i8.Replace("i8", ""), CultureInfo.InvariantCulture), state) } - / u8:([0-9]+ ("u8")) { new ByteLiteral(byte.Parse(u8.Replace("u8", ""), CultureInfo.InvariantCulture), state) } - / i16:([0-9]+ ("i16")) { new ShortLiteral(short.Parse(i16.Replace("i16", ""), CultureInfo.InvariantCulture), state) } - / u16:([0-9]+ ("u16")) { new UShortLiteral(ushort.Parse(u16.Replace("u16", ""), CultureInfo.InvariantCulture), state) } - / i32:([0-9]+ ("i32")) { new IntLiteral(int.Parse(i32.Replace("i32", ""), CultureInfo.InvariantCulture), state) } - / u32:([0-9]+ ("u32")) { new UIntLiteral(uint.Parse(u32.Replace("u32", ""), CultureInfo.InvariantCulture), state) } - / u64:([0-9]+ ("u64")) { new ULongLiteral(ulong.Parse(u64.Replace("u64", ""), CultureInfo.InvariantCulture), state) } - / i64:([0-9]+ ("i64")?) { new LongLiteral(long.Parse(i64.Replace("i64", ""), CultureInfo.InvariantCulture), state) } - / b:("true"/"false") { new BoolLiteral(bool.Parse(b), state) } +special + = b:("true"/"false") { new BoolLiteral(bool.Parse(b), state) } / "linq" { new LinqLiteral(state) } / "global" { new GlobalLiteral(state) } / "null" { new NullLiteral(state) } / "self" { new SelfLiteral(state) } + +literal + = f32:([0-9_]+ ("." [0-9_]+)? ("f32")) { new FloatLiteral(float.Parse(f32.Replace("f32", "").Replace("_", ""), CultureInfo.InvariantCulture), state) } + / f64:([0-9_]+ ("." [0-9_]+) ("f64")?) { new DoubleLiteral(double.Parse(f64.Replace("f64", "").Replace("_", ""), CultureInfo.InvariantCulture), state) } + / f64:([0-9_]+ ("f64")) { new DoubleLiteral(double.Parse(f64.Replace("f64", "").Replace("_", ""), CultureInfo.InvariantCulture), state) } + + / "0b" i8:([01_]+ ("i8")) { new SByteLiteral (Convert.ToSByte (i8.Replace("i8", "").Replace("_", ""), 2), state) } + / "0b" u8:([01_]+ ("u8")) { new ByteLiteral (Convert.ToByte (u8.Replace("u8", "").Replace("_", ""), 2), state) } + / "0b" i16:([01_]+ ("i16")) { new ShortLiteral (Convert.ToInt16 (i16.Replace("i16", "").Replace("_", ""), 2), state) } + / "0b" u16:([01_]+ ("u16")) { new UShortLiteral (Convert.ToUInt16 (u16.Replace("u16", "").Replace("_", ""), 2), state) } + / "0b" i32:([01_]+ ("i32")) { new IntLiteral (Convert.ToInt32 (i32.Replace("i32", "").Replace("_", ""), 2), state) } + / "0b" u32:([01_]+ ("u32")) { new UIntLiteral (Convert.ToUInt32 (u32.Replace("u32", "").Replace("_", ""), 2), state) } + / "0b" u64:([01_]+ ("u64")) { new ULongLiteral (Convert.ToUInt64 (u64.Replace("u64", "").Replace("_", ""), 2), state) } + / "0b" i64:([01_]+ ("i64")?) { new LongLiteral (Convert.ToInt64 (i64.Replace("i64", "").Replace("_", ""), 2), state) } + + / "0x" i8:([0-9A-F_]+ ("i8")) { new SByteLiteral (Convert.ToSByte (i8.Replace("i8", "").Replace("_", ""), 16), state) } + / "0x" u8:([0-9A-F_]+ ("u8")) { new ByteLiteral (Convert.ToByte (u8.Replace("u8", "").Replace("_", ""), 16), state) } + / "0x" i16:([0-9A-F_]+ ("i16")) { new ShortLiteral (Convert.ToInt16 (i16.Replace("i16", "").Replace("_", ""), 16), state) } + / "0x" u16:([0-9A-F_]+ ("u16")) { new UShortLiteral (Convert.ToUInt16 (u16.Replace("u16", "").Replace("_", ""), 16), state) } + / "0x" i32:([0-9A-F_]+ ("i32")) { new IntLiteral (Convert.ToInt32 (i32.Replace("i32", "").Replace("_", ""), 16), state) } + / "0x" u32:([0-9A-F_]+ ("u32")) { new UIntLiteral (Convert.ToUInt32 (u32.Replace("u32", "").Replace("_", ""), 16), state) } + / "0x" u64:([0-9A-F_]+ ("u64")) { new ULongLiteral (Convert.ToUInt64 (u64.Replace("u64", "").Replace("_", ""), 16), state) } + / "0x" i64:([0-9A-F_]+ ("i64")?) { new LongLiteral (Convert.ToInt64 (i64.Replace("i64", "").Replace("_", ""), 16), state) } + + / i8:([0-9_]+ ("i8")) { new SByteLiteral (sbyte.Parse (i8.Replace("i8", "").Replace("_", ""), CultureInfo.InvariantCulture), state) } + / u8:([0-9_]+ ("u8")) { new ByteLiteral (byte.Parse (u8.Replace("u8", "").Replace("_", ""), CultureInfo.InvariantCulture), state) } + / i16:([0-9_]+ ("i16")) { new ShortLiteral (short.Parse (i16.Replace("i16", "").Replace("_", ""), CultureInfo.InvariantCulture), state) } + / u16:([0-9_]+ ("u16")) { new UShortLiteral (ushort.Parse (u16.Replace("u16", "").Replace("_", ""), CultureInfo.InvariantCulture), state) } + / i32:([0-9_]+ ("i32")) { new IntLiteral (int.Parse (i32.Replace("i32", "").Replace("_", ""), CultureInfo.InvariantCulture), state) } + / u32:([0-9_]+ ("u32")) { new UIntLiteral (uint.Parse (u32.Replace("u32", "").Replace("_", ""), CultureInfo.InvariantCulture), state) } + / u64:([0-9_]+ ("u64")) { new ULongLiteral (ulong.Parse (u64.Replace("u64", "").Replace("_", ""), CultureInfo.InvariantCulture), state) } + / i64:([0-9_]+ ("i64")?) { new LongLiteral (long.Parse (i64.Replace("i64", "").Replace("_", ""), CultureInfo.InvariantCulture), state) } + / interpolated_string / string_literal / char_literal From 8dacd148f332abfa8f88f1b33b4dbc590bced1da Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Mon, 6 Nov 2023 16:08:55 +0300 Subject: [PATCH 13/15] fix #22 --- SLThree/Embedding/EmbeddingExtensions.cs | 6 +++ SLThree/Properties/AssemblyInfo.cs | 4 +- SLThree/Wrapper.cs | 55 ++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/SLThree/Embedding/EmbeddingExtensions.cs b/SLThree/Embedding/EmbeddingExtensions.cs index f03f522..b896056 100644 --- a/SLThree/Embedding/EmbeddingExtensions.cs +++ b/SLThree/Embedding/EmbeddingExtensions.cs @@ -20,6 +20,7 @@ public static ExecutionContext RunScript(this ExecutionContext context, string c { return Parser.This.RunScript(code, null, context); } + public static T Unwrap(this ExecutionContext context) where T : new() => UnwrapperForInstances.Unwrap(context); public static void UnwrapStatic(this ExecutionContext context) => Wrapper.UnwrapStatic(context); public static ExecutionContext Wrap(this T obj) => Wrapper.Wrap(obj); @@ -27,5 +28,10 @@ public static ExecutionContext RunScript(this ExecutionContext context, string c public static void UnwrapStaticClass(this ExecutionContext context, Type type) => UnwrapperForStaticClasses.Unwrap(type, context); public static void UnwrapStaticClass(this Type type, ExecutionContext context) => UnwrapperForStaticClasses.Unwrap(type, context); public static ExecutionContext WrapStaticClass(this Type type) => UnwrapperForStaticClasses.Wrap(type); + + public static T SafeUnwrap(this ExecutionContext context) where T : new() => UnwrapperForInstances.SafeUnwrap(context); + public static void SafeUnwrapStatic(this ExecutionContext context) => Wrapper.SafeUnwrapStatic(context); + public static void SafeUnwrapStaticClass(this ExecutionContext context, Type type) => UnwrapperForStaticClasses.SafeUnwrap(type, context); + public static void SafeUnwrapStaticClass(this Type type, ExecutionContext context) => UnwrapperForStaticClasses.SafeUnwrap(type, context); } } diff --git a/SLThree/Properties/AssemblyInfo.cs b/SLThree/Properties/AssemblyInfo.cs index 939a9b0..e1c9914 100644 --- a/SLThree/Properties/AssemblyInfo.cs +++ b/SLThree/Properties/AssemblyInfo.cs @@ -43,8 +43,8 @@ public static class SLTVersion { public const string Major = "0"; //vh public const string Minor = "2"; //vh public const string Build = "0"; //vh - public const string Revision = "797"; //vh - public const long LastUpdate = 638345509453743994; //vh + public const string Revision = "798"; //vh + public const long LastUpdate = 638348728666782572; //vh public const string Version = Major + "." + Minor + "." + Build + "." + Revision; public const string VersionWithoutRevision = Major + "." + Minor + "." + Build; diff --git a/SLThree/Wrapper.cs b/SLThree/Wrapper.cs index 937a1bc..f9212f3 100644 --- a/SLThree/Wrapper.cs +++ b/SLThree/Wrapper.cs @@ -245,6 +245,22 @@ public static ExecutionContext WrapStatic() ret.LocalVariables.SetValue(x.Key, WrapCast(x.Value.GetValue(null))); return ret; } + public static void SafeUnwrapStatic(ExecutionContext context) + { + foreach (var name in context.LocalVariables.GetAsDictionary()) + { + try + { + 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)); + } + catch (Exception e) + { + context.Errors.Add(e); + } + } + } public static void UnwrapStatic(ExecutionContext context) { foreach (var name in context.LocalVariables.GetAsDictionary()) @@ -304,6 +320,26 @@ public static void Unwrap(Type type, ExecutionContext context) else if (fields.ContainsKey(name.Key)) fields[name.Key].SetValue(null, UnwrapCast(fields[name.Key].FieldType, name.Value)); } } + + public static void SafeUnwrap(Type type, ExecutionContext context) + { + if (!Unwrappers.ContainsKey(type)) Unwrappers.Add(type, new UnwrapperForStaticClasses(type)); + var props = Unwrappers[type].StaticProperties; + var fields = Unwrappers[type].StaticFields; + foreach (var name in context.LocalVariables.GetAsDictionary()) + { + try + { + 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)); + } + catch (Exception e) + { + context.Errors.Add(e); + } + } + } } public abstract class UnwrapperForInstances : Wrapper where T: new() @@ -320,6 +356,25 @@ public static T Unwrap(ExecutionContext context) } return ret; } + + public static T SafeUnwrap(ExecutionContext context) + { + var ret = new T(); + foreach (var name in context.LocalVariables.GetAsDictionary()) + { + try + { + 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)); + } + catch (Exception e) + { + context.Errors.Add(e); + } + } + return ret; + } } /// From c921b63b59aa8f5b43fa180afc919e1b6979ac67 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Mon, 6 Nov 2023 17:12:11 +0300 Subject: [PATCH 14/15] fix #29 --- SLThree/ExecutionContext.cs | 1 + SLThree/Lexems/Literals/Literal.cs | 2 +- SLThree/Properties/AssemblyInfo.cs | 4 ++-- SLThree/SLThree.csproj | 4 ++-- ...{ForeachCycleStatement.cs => ForeachLoopStatement.cs} | 9 ++++----- .../{WhileCycleStatement.cs => WhileLoopStatement.cs} | 4 ++-- SLThree/syntax.peg | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) rename SLThree/Statements/{ForeachCycleStatement.cs => ForeachLoopStatement.cs} (82%) rename SLThree/Statements/{WhileCycleStatement.cs => WhileLoopStatement.cs} (86%) diff --git a/SLThree/ExecutionContext.cs b/SLThree/ExecutionContext.cs index 02d40b3..42e711c 100644 --- a/SLThree/ExecutionContext.cs +++ b/SLThree/ExecutionContext.cs @@ -68,6 +68,7 @@ public void EndCycle() public void Return(object o) { Returned = true; ReturnedValue = o; } public void Break() { Broken = true; } public void Continue() { Continued = true; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void PrepareToInvoke() { Returned = Broken = Continued = false; } public void DefaultEnvironment() { diff --git a/SLThree/Lexems/Literals/Literal.cs b/SLThree/Lexems/Literals/Literal.cs index 6af4ea5..fa3131d 100644 --- a/SLThree/Lexems/Literals/Literal.cs +++ b/SLThree/Lexems/Literals/Literal.cs @@ -3,7 +3,7 @@ namespace SLThree { - public partial class Literal : BaseLexem + public class Literal : BaseLexem { public object Value; public Literal() : this(default, default) { } diff --git a/SLThree/Properties/AssemblyInfo.cs b/SLThree/Properties/AssemblyInfo.cs index e1c9914..c6e1605 100644 --- a/SLThree/Properties/AssemblyInfo.cs +++ b/SLThree/Properties/AssemblyInfo.cs @@ -43,8 +43,8 @@ public static class SLTVersion { public const string Major = "0"; //vh public const string Minor = "2"; //vh public const string Build = "0"; //vh - public const string Revision = "798"; //vh - public const long LastUpdate = 638348728666782572; //vh + public const string Revision = "842"; //vh + public const long LastUpdate = 638348766608802346; //vh public const string Version = Major + "." + Minor + "." + Build + "." + Revision; public const string VersionWithoutRevision = Major + "." + Minor + "." + Build; diff --git a/SLThree/SLThree.csproj b/SLThree/SLThree.csproj index 3147c9e..d95dba1 100644 --- a/SLThree/SLThree.csproj +++ b/SLThree/SLThree.csproj @@ -115,7 +115,7 @@ - + @@ -124,7 +124,7 @@ - + diff --git a/SLThree/Statements/ForeachCycleStatement.cs b/SLThree/Statements/ForeachLoopStatement.cs similarity index 82% rename from SLThree/Statements/ForeachCycleStatement.cs rename to SLThree/Statements/ForeachLoopStatement.cs index a6e8ae7..fe4e1ff 100644 --- a/SLThree/Statements/ForeachCycleStatement.cs +++ b/SLThree/Statements/ForeachLoopStatement.cs @@ -5,13 +5,13 @@ namespace SLThree { - public class ForeachCycleStatement : BaseStatement + public class ForeachLoopStatement : BaseStatement { public NameLexem Name { get; set; } public BaseLexem Iterator { get; set; } public BaseStatement[] CycleBody { get; set; } - public ForeachCycleStatement(NameLexem name, BaseLexem iterator, StatementListStatement cycleBody, Cursor cursor) : base(cursor) + public ForeachLoopStatement(NameLexem name, BaseLexem iterator, StatementListStatement cycleBody, Cursor cursor) : base(cursor) { Name = name; Iterator = iterator; @@ -25,7 +25,6 @@ public ForeachCycleStatement(NameLexem name, BaseLexem iterator, StatementListSt public override object GetValue(ExecutionContext context) { var iterator = Iterator.GetValue(context).Cast(); - var enumerator = iterator.GetEnumerator(); if (context != last_context) { last_context = context; @@ -33,9 +32,9 @@ public override object GetValue(ExecutionContext context) } var ret = default(object); context.StartCycle(); - while (enumerator.MoveNext()) + foreach (var x in iterator) { - context.LocalVariables.SetValue(variable_index, enumerator.Current); + context.LocalVariables.SetValue(variable_index, x); for (var i = 0; i < count; i++) { ret = CycleBody[i].GetValue(context); diff --git a/SLThree/Statements/WhileCycleStatement.cs b/SLThree/Statements/WhileLoopStatement.cs similarity index 86% rename from SLThree/Statements/WhileCycleStatement.cs rename to SLThree/Statements/WhileLoopStatement.cs index 2cabf4e..c0d3732 100644 --- a/SLThree/Statements/WhileCycleStatement.cs +++ b/SLThree/Statements/WhileLoopStatement.cs @@ -8,12 +8,12 @@ namespace SLThree { - public class WhileCycleStatement : BaseStatement + public class WhileLoopStatement : BaseStatement { public BaseLexem Condition { get; set; } public BaseStatement[] CycleBody { get; set; } - public WhileCycleStatement(BaseLexem condition, StatementListStatement cycleBody, Cursor cursor) : base(cursor) + public WhileLoopStatement(BaseLexem condition, StatementListStatement cycleBody, Cursor cursor) : base(cursor) { Condition = condition; CycleBody = cycleBody.Statements.ToArray(); diff --git a/SLThree/syntax.peg b/SLThree/syntax.peg index 5ed6887..5e0f03d 100644 --- a/SLThree/syntax.peg +++ b/SLThree/syntax.peg @@ -61,10 +61,10 @@ block_statement = "{" _ st:statement_list _ "}" { st } while_statement - = "while" _ "(" _ cond:lexem _ ")" _ body:block_statement { new WhileCycleStatement(cond, body, state) } + = "while" _ "(" _ cond:lexem _ ")" _ body:block_statement { new WhileLoopStatement(cond, body, state) } foreach_statement - = "foreach" _ "(" _ n:name _ "in" _ iter:lexem _ ")" _ body:block_statement { new ForeachCycleStatement(n, iter, body, state) } + = "foreach" _ "(" _ n:name _ "in" _ iter:lexem _ ")" _ body:block_statement { new ForeachLoopStatement(n, iter, body, state) } condition_statement = "if" _ "(" cond:lexem ")" _ t:block_statement _ "else" _ f:block_statement { new ConditionStatement(cond, t, f, state) } From ac69fc1433638ccdd9a657865f7d89d0acbbcda3 Mon Sep 17 00:00:00 2001 From: Kotov <44296606+AIexandrKotov@users.noreply.github.com> Date: Mon, 6 Nov 2023 17:42:44 +0300 Subject: [PATCH 15/15] 0.3.0 --- README.md | 9 ++++----- SLThree/Properties/AssemblyInfo.cs | 8 ++++---- SLThree/docs/specification | 13 +++++++++---- SLThree/docs/versions/0.3.0 | 7 +++++-- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 8d2c784..1c4dce0 100644 --- a/README.md +++ b/README.md @@ -31,10 +31,9 @@ end. ### LANG and REPL compatibility -| LANG version | REPL version | -|--------------|--------------| -| 0.2.0 | 1.0.0+ | -| 0.1.0-0.1.1 | Unsupported | +| REPL version | LANG version | +|-----------------|-----------------| +| 1.0.0 | 0.2.0+ | ### Download -[![stable](https://img.shields.io/badge/REPL_stable-1.0.0-00cc00)](https://github.com/AIexandrKotov/SLThree/releases/tag/0.2.0) [![stable](https://img.shields.io/badge/LANG_exp-0.2.0-ccaa00)](https://github.com/AIexandrKotov/SLThree/releases/tag/0.2.0) \ No newline at end of file +[![stable](https://img.shields.io/badge/REPL_stable-1.0.0-00cc00)](https://github.com/AIexandrKotov/SLThree/releases/tag/0.2.0) [![stable](https://img.shields.io/badge/LANG_exp-0.3.0-ccaa00)](https://github.com/AIexandrKotov/SLThree/releases/tag/0.3.0) \ No newline at end of file diff --git a/SLThree/Properties/AssemblyInfo.cs b/SLThree/Properties/AssemblyInfo.cs index c6e1605..5565a91 100644 --- a/SLThree/Properties/AssemblyInfo.cs +++ b/SLThree/Properties/AssemblyInfo.cs @@ -41,10 +41,10 @@ public static class SLTVersion { public const string Major = "0"; //vh - public const string Minor = "2"; //vh + public const string Minor = "3"; //vh public const string Build = "0"; //vh - public const string Revision = "842"; //vh - public const long LastUpdate = 638348766608802346; //vh + public const string Revision = "845"; //vh + public const long LastUpdate = 638348783847449980; //vh public const string Version = Major + "." + Minor + "." + Build + "." + Revision; public const string VersionWithoutRevision = Major + "." + Minor + "." + Build; @@ -78,7 +78,7 @@ static SLTVersion() } } - public static string Edition { get; } = "Unwrap the wrap"; + public static string Edition { get; } = "Third time is lucky"; public static string GetTitle() { diff --git a/SLThree/docs/specification b/SLThree/docs/specification index 27778d8..5e9e327 100644 --- a/SLThree/docs/specification +++ b/SLThree/docs/specification @@ -1,17 +1,22 @@ --=== SLT SPECIFICATION ===-- Nums (default 64 bit), chars, strings (+interpolated) and bools like in C# Suffixes for nums determine type like in Rust (1u32 = uint, 1f32 = float) -Operators (priority like in C#): - Binary: + - * / % == != > >= < <= = += -= *= /= %= => as +Operators (priority like in C#, exclude bit operators): + Ternary: ?: + Binary: + - * / % == != > >= < <= = += -= *= /= %= => as, &&, ||, &, |, ^ Unary: + - ! ~ - Primary: x.y, x(), new x() + Primary: x.y, x(), new x(), x[y] Statements like in C#: - if and while - return, break, continue Almost like in C#: + - foreach ( in ) - using ; // not namespace - switch (supports non-const in case and break not needed) - [implicit] - implicit supports more types (slower) SLThree features: - getting lexems ( as is) and call it ---=== END SPECIFICATON ===-- \ No newline at end of file + - list, tuple and dictionary initializers +--=== END SPECIFICATON ===-- +For more information: + https://github.com/AIexandrKotov/SLThree/wiki/Language \ No newline at end of file diff --git a/SLThree/docs/versions/0.3.0 b/SLThree/docs/versions/0.3.0 index ca9d0b5..636899a 100644 --- a/SLThree/docs/versions/0.3.0 +++ b/SLThree/docs/versions/0.3.0 @@ -1,11 +1,14 @@ ------- 0.3.0 ------ [~.~.~] +------ 0.3.0 Third time is lucky ------ [06.11.23] Language: - Foreach cycle - linq context (linq.range, linq.max etc.) - - Indexator and list initializers like in Python + - list, tuples and dictionary initializers + - Indexators - Logical operators (&&, ||) and binary bit operators (&, |, ^) - Ternary operator + - Hexadecimal and binary literals, suppoting _ in nums Embedding: - Wrapping classes in context, wrapping static members and classes + - Safe unwrapping Optimization: - >40% (collatz_conjecture 14 s => 8 s) \ No newline at end of file