From 9f373dc806dd7dbc20be40f4edbdb53bede4f4ac Mon Sep 17 00:00:00 2001 From: "Tobias Burdow [Kaleidox]" Date: Sun, 24 Apr 2022 16:37:56 +0200 Subject: [PATCH 1/3] intN --- kscr-core/Std/Numeric.cs | 233 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 216 insertions(+), 17 deletions(-) diff --git a/kscr-core/Std/Numeric.cs b/kscr-core/Std/Numeric.cs index 3317efa..8e4fa93 100644 --- a/kscr-core/Std/Numeric.cs +++ b/kscr-core/Std/Numeric.cs @@ -1,6 +1,9 @@ using System; using System.Collections.Concurrent; +using System.Collections.Generic; using System.Globalization; +using System.Linq; +using System.Numerics; using System.Text.RegularExpressions; using KScr.Core.Exception; using KScr.Core.Model; @@ -10,10 +13,7 @@ namespace KScr.Core.Std; public enum NumericMode { - Byte, - Short, Int, - Long, Float, Double } @@ -22,9 +22,19 @@ public sealed class Numeric : NativeObj { public static readonly Regex NumberRegex = new(@"([\d]+(i|l|f|d|s|b)?)([.,]([\d]+)(f|d))?"); - public static Numeric Zero; + public static readonly Numeric Zero = new(0) + { + Mutable = false, + Bytes = BitConverter.GetBytes((byte)0), + Mode = NumericMode.Int + }; - public static Numeric One; + public static readonly Numeric One = new(1) + { + Mutable = false, + Bytes = BitConverter.GetBytes((byte)1), + Mode = NumericMode.Int + }; private static readonly ConcurrentDictionary Cache = new(); @@ -38,12 +48,15 @@ internal Numeric(RuntimeBase vm, bool constant = false) : base(vm) _objId = vm.NextObjId(); } - public NumericMode Mode { get; internal set; } = NumericMode.Short; - public byte[] Bytes { get; internal set; } = BitConverter.GetBytes((short)0); - public byte ByteValue => GetAs(); - public short ShortValue => GetAs(); - public int IntValue => GetAs(); - public long LongValue => GetAs(); + public bool Mutable + { + get => !_constant && _mutable; + private set => _mutable = value; + } + + public NumericMode Mode { get; private set; } = NumericMode.Int; + public byte[] Bytes { get; private set; } = BitConverter.GetBytes((short)0); + public IntN IntNValue => GetAs(); public float FloatValue => GetAs(); public double DoubleValue => GetAs(); public string StringValue => GetAs(); @@ -86,10 +99,7 @@ public override Stack InvokeNative(RuntimeBase vm, Stack stack, string member, p delta = (Constant(vm, 0.001).Value as Numeric)!; stack[StackOutput.Default] = Mode switch { - NumericMode.Byte => ByteValue == other.ByteValue, - NumericMode.Short => ShortValue == other.ShortValue, NumericMode.Int => IntValue == other.IntValue, - NumericMode.Long => LongValue == other.LongValue, NumericMode.Float => Math.Abs(FloatValue - other.FloatValue) < delta.FloatValue, NumericMode.Double => Math.Abs(DoubleValue - other.DoubleValue) < delta.DoubleValue, _ => throw new ArgumentOutOfRangeException() @@ -110,10 +120,7 @@ public override string GetKey() { return Mode switch { - NumericMode.Byte => CreateKey(LongValue), - NumericMode.Short => CreateKey(LongValue), NumericMode.Int => CreateKey(LongValue), - NumericMode.Long => CreateKey(LongValue), NumericMode.Float => CreateKey(FloatValue), NumericMode.Double => CreateKey(DoubleValue), _ => throw new ArgumentOutOfRangeException() @@ -728,4 +735,196 @@ public IObjectRef Tan(RuntimeBase vm) throw new ArgumentOutOfRangeException(); } } +} + +public sealed class IntN : IObject +{ + public static readonly char[] digits = new[] { + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9' + }; + public static readonly char[] chars = new[] { + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z', + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + 'x', + 'y', + 'z' + }; + + private static readonly Dictionary _clsInsts = new(); + private readonly IClassInstance _clsInst; + + public readonly int N; + public readonly byte[] Bytes; + + private byte[] Bits + { + get + { + byte[] bits = new byte[N]; + for (int i = 0; i < N; i++) + bits[i] = (byte)((Bytes[i / 8] & (1 << i % 8 - 1)) != 0 ? 1 : 0); + bits = bits.Reverse().ToArray(); + return bits; + } + } + + public byte ByteValue + { + get => Bytes[0]; + set => Set(new[] { value }); + } + + public short ShortValue + { + get => BitConverter.ToInt16(Bytes); + set => Set(BitConverter.GetBytes(value)); + } + + public int IntValue + { + get => BitConverter.ToInt32(Bytes); + set => Set(BitConverter.GetBytes(value)); + } + + public long LongValue + { + get => BitConverter.ToInt64(Bytes); + set => Set(BitConverter.GetBytes(value)); + } + + public BigInteger BitIntValue + { + get => new(Bytes); + set => Set(value.ToByteArray()); + } + + public string StringValue(byte radix) + { // todo: inspect + string str = string.Empty; + if (radix == 1) + str = string.Join("", Bits.Select(x => x.ToString())); + else + { + (int div, int mod) divmod(int x, int y) => (x / y, x % y); + void add(int[] output, int[] input) + { + int carry = 0; + for (int i = 0; i < input.Length; i++) + (carry, output[i]) = divmod(output[i] + input[i] + carry, radix); + for (int i = 0; carry > 0; i++) + (carry, output[i]) = divmod(output[i] + carry, radix); + } + + int[] res = new int[(int)Math.Ceiling(str.Length * Math.Log(2) / Math.Log(10))], + s = StringValue(1).Substring(2).Select(x => (int)x).ToArray(); + foreach (var c in s) + { + add(res, res); + add(res, new[] { c }); + } + + str = string.Join("", res.Reverse().Select(x => (char)x).ToArray()); + } + return radix switch + { + 1 => "0b" + str, + 16 => "0x" + str, + _ => (radix == 10 ? string.Empty : "0_") + str + }; + } + + public IntN(RuntimeBase vm, int n = 32) + { + if (n / 8 > chars.Length) + throw new FatalException($"n too large: {n} ({n / 8})"); + N = n; + Bytes = new byte[(int)Math.Ceiling((double)n / 8)]; + ObjectId = vm.NextObjId(); + _clsInst = GetClsInst(vm, n); + } + + private void Set(byte[] bytes) + { + if (bytes.Length > N) + throw new ArgumentOutOfRangeException(nameof(bytes.Length), bytes.Length, "Set value too large"); + Array.Fill(Bytes, (byte)0); + Array.Copy(bytes, 0, Bytes, N - bytes.Length, bytes.Length); + } + + public long ObjectId { get; } + + public IClassInstance Type => _clsInst; + + public string ToString(short variant) => StringValue((byte)(variant == 0 ? 10 : variant)); + + public Stack Invoke(RuntimeBase vm, Stack stack, string member, params IObject?[] args) + { + throw new NotImplementedException(); + } + + public string GetKey() => $"int<{N}>: {StringValue(16)}"; + + private IClassInstance GetClsInst(RuntimeBase vm, int n) + { + if (_clsInsts.ContainsKey(n)) + return _clsInsts[n]; + return _clsInsts[n] = Class.IntType.CreateInstance(vm, Class.IntType, + new TypeParameter(N.ToString(), TypeParameterSpecializationType.N)); + } } \ No newline at end of file From d4a433fc71e2d02126e3246c7b3af2ae660a1a01 Mon Sep 17 00:00:00 2001 From: "Tobias Burdow [Kaleidox]" Date: Sun, 24 Apr 2022 16:56:18 +0200 Subject: [PATCH 2/3] Update Numeric.cs --- kscr-core/Std/Numeric.cs | 50 ++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/kscr-core/Std/Numeric.cs b/kscr-core/Std/Numeric.cs index 8e4fa93..c72f9b2 100644 --- a/kscr-core/Std/Numeric.cs +++ b/kscr-core/Std/Numeric.cs @@ -639,31 +639,6 @@ public IObjectRef OpCircumflex(RuntimeBase vm, Numeric right) return rev; } - public override string ToString() - { - return ToString(0); - } - - public static string CreateKey(string num) - { - return "num:" + num; - } - - public static string CreateKey(long num) - { - return CreateKey(num.ToString()); - } - - public static string CreateKey(float num) - { - return CreateKey(num.ToString(CultureInfo.InvariantCulture)); - } - - public static string CreateKey(double num) - { - return CreateKey(num.ToString(CultureInfo.InvariantCulture)); - } - public IObjectRef Sqrt(RuntimeBase vm) { switch (Mode) @@ -735,6 +710,31 @@ public IObjectRef Tan(RuntimeBase vm) throw new ArgumentOutOfRangeException(); } } + + public override string ToString() + { + return ToString(0); + } + + public static string CreateKey(string num) + { + return "num:" + num; + } + + public static string CreateKey(long num) + { + return CreateKey(num.ToString()); + } + + public static string CreateKey(float num) + { + return CreateKey(num.ToString(CultureInfo.InvariantCulture)); + } + + public static string CreateKey(double num) + { + return CreateKey(num.ToString(CultureInfo.InvariantCulture)); + } } public sealed class IntN : IObject From fcba160ed6f3fc774d712fa15366a689399b325a Mon Sep 17 00:00:00 2001 From: "Tobias Burdow [Kaleidox]" Date: Sat, 14 Jan 2023 21:28:29 +0100 Subject: [PATCH 3/3] stuff --- grammar/KScrLexer.g4 | 6 +- kscr-core/Model/INativeRunner.cs | 4 +- kscr-core/Std/Numeric.cs | 199 +++++++++---------------------- 3 files changed, 63 insertions(+), 146 deletions(-) diff --git a/grammar/KScrLexer.g4 b/grammar/KScrLexer.g4 index a939854..9c0791c 100644 --- a/grammar/KScrLexer.g4 +++ b/grammar/KScrLexer.g4 @@ -151,9 +151,9 @@ RREQARROW: '=>>'; //RBOXARROW: '|>'; //DBOXARROW: '<|>'; -ID: LETTER (DIGIT | LETTER)*; -DIGIT: [0-9]; -LETTER: [a-zA-Z_$£#]; +fragment ID: LETTER (DIGIT | LETTER)*; +fragment DIGIT: [0-9]; +fragment LETTER: [a-zA-Z_$£#]; SING_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN); WS: [ \n\r\t] -> channel(HIDDEN); diff --git a/kscr-core/Model/INativeRunner.cs b/kscr-core/Model/INativeRunner.cs index 55df9b6..8d9c276 100644 --- a/kscr-core/Model/INativeRunner.cs +++ b/kscr-core/Model/INativeRunner.cs @@ -15,9 +15,9 @@ public abstract class NativeObj : IObject { private readonly uint _internalId; - public NativeObj(RuntimeBase vm) + public NativeObj(uint internalId) { - _internalId = vm.NextObjId(); + _internalId = internalId; } public long ObjectId => RuntimeBase.CombineHash(_internalId, Type.FullDetailedName); diff --git a/kscr-core/Std/Numeric.cs b/kscr-core/Std/Numeric.cs index c72f9b2..e0ba3fc 100644 --- a/kscr-core/Std/Numeric.cs +++ b/kscr-core/Std/Numeric.cs @@ -4,6 +4,7 @@ using System.Globalization; using System.Linq; using System.Numerics; +using System.Text; using System.Text.RegularExpressions; using KScr.Core.Exception; using KScr.Core.Model; @@ -14,21 +15,20 @@ namespace KScr.Core.Std; public enum NumericMode { Int, + IntN, Float, Double } -public sealed class Numeric : NativeObj +public class Numeric : NativeObj { public static readonly Regex NumberRegex = new(@"([\d]+(i|l|f|d|s|b)?)([.,]([\d]+)(f|d))?"); - public static readonly Numeric Zero = new(0) { Mutable = false, Bytes = BitConverter.GetBytes((byte)0), Mode = NumericMode.Int }; - public static readonly Numeric One = new(1) { Mutable = false, @@ -36,26 +36,22 @@ public sealed class Numeric : NativeObj Mode = NumericMode.Int }; - private static readonly ConcurrentDictionary Cache = new(); - - private readonly bool _constant; + protected virtual bool _constant { get; } - private readonly uint _objId; - - internal Numeric(RuntimeBase vm, bool constant = false) : base(vm) + private Numeric(byte value) : base((uint)(value + 1)) { - _constant = constant; - _objId = vm.NextObjId(); } - public bool Mutable + internal Numeric(RuntimeBase vm, bool constant = false) : base(vm.NextObjId()) { - get => !_constant && _mutable; - private set => _mutable = value; + _constant = constant; } - public NumericMode Mode { get; private set; } = NumericMode.Int; - public byte[] Bytes { get; private set; } = BitConverter.GetBytes((short)0); + [Obsolete] + public bool Mutable => !_constant; + + public NumericMode Mode { get; protected set; } = NumericMode.Int; + public byte[] Bytes { get; protected set; } = BitConverter.GetBytes((short)0); public IntN IntNValue => GetAs(); public float FloatValue => GetAs(); public double DoubleValue => GetAs(); @@ -84,7 +80,7 @@ public override Stack InvokeNative(RuntimeBase vm, Stack stack, string member, p stack[StackOutput.Default] = String.Instance(vm, StringValue); break; case "ExitCode": - stack[StackOutput.Default] = Constant(vm, IntValue); + stack[StackOutput.Default] = Constant(vm, GetAs()); break; case "equals": if (args[0] is not Numeric other) @@ -251,20 +247,23 @@ private void SetAs(T value) private T GetAs() { - var type = typeof(T); + switch (Mode, typeof(T).Name) + { + case (NumericMode.Int, "byte"): + case (NumericMode.IntN, "byte"): + case (NumericMode.Float, "byte"): + case (NumericMode.Double, "byte"): + break; + } if (type == typeof(byte)) { - if (Mode == NumericMode.Byte) - return (T)(object)Bytes[0]; switch (Mode) { - case NumericMode.Short: - return (T)(object)(byte)ShortValue; case NumericMode.Int: - return (T)(object)(byte)IntValue; - case NumericMode.Long: - return (T)(object)(byte)LongValue; + return (T)(object)(byte)IntNValue.IntValue; + case NumericMode.IntN: + return (T)(object) case NumericMode.Float: return (T)(object)(byte)FloatValue; case NumericMode.Double: @@ -737,81 +736,33 @@ public static string CreateKey(double num) } } -public sealed class IntN : IObject +public sealed class IntN : Numeric { - public static readonly char[] digits = new[] { - '0', - '1', - '2', - '3', - '4', - '5', - '6', - '7', - '8', - '9' - }; - public static readonly char[] chars = new[] { - 'A', - 'B', - 'C', - 'D', - 'E', - 'F', - 'G', - 'H', - 'I', - 'J', - 'K', - 'L', - 'M', - 'N', - 'O', - 'P', - 'Q', - 'R', - 'S', - 'T', - 'U', - 'V', - 'W', - 'X', - 'Y', - 'Z', - 'a', - 'b', - 'c', - 'd', - 'e', - 'f', - 'g', - 'h', - 'i', - 'j', - 'k', - 'l', - 'm', - 'n', - 'o', - 'p', - 'q', - 'r', - 's', - 't', - 'u', - 'v', - 'w', - 'x', - 'y', - 'z' - }; - + public const int NSteps = 8; + //private static readonly ConcurrentDictionary Cache = new(); private static readonly Dictionary _clsInsts = new(); private readonly IClassInstance _clsInst; - public readonly int N; - public readonly byte[] Bytes; - + public int N + { + get => Bytes.Length * NSteps; + set + { + var arr = new byte[value / NSteps]; + Bytes.CopyTo(arr, 0); + Bytes = arr; + } + } + + public IntN(RuntimeBase vm, int n = 32) : base(vm) + { + if (n / 8 > chars.Length) + throw new FatalException($"n too large: {n} ({n / 8})"); + N = n; + Bytes = new byte[(int)Math.Ceiling((double)n / 8)]; + _clsInst = GetClsInst(vm, n); + } + private byte[] Bits { get @@ -848,57 +799,25 @@ public long LongValue set => Set(BitConverter.GetBytes(value)); } - public BigInteger BitIntValue + public BigInteger BigIntValue { get => new(Bytes); set => Set(value.ToByteArray()); } - public string StringValue(byte radix) - { // todo: inspect - string str = string.Empty; - if (radix == 1) - str = string.Join("", Bits.Select(x => x.ToString())); - else - { - (int div, int mod) divmod(int x, int y) => (x / y, x % y); - void add(int[] output, int[] input) - { - int carry = 0; - for (int i = 0; i < input.Length; i++) - (carry, output[i]) = divmod(output[i] + input[i] + carry, radix); - for (int i = 0; carry > 0; i++) - (carry, output[i]) = divmod(output[i] + carry, radix); - } - - int[] res = new int[(int)Math.Ceiling(str.Length * Math.Log(2) / Math.Log(10))], - s = StringValue(1).Substring(2).Select(x => (int)x).ToArray(); - foreach (var c in s) - { - add(res, res); - add(res, new[] { c }); - } - - str = string.Join("", res.Reverse().Select(x => (char)x).ToArray()); - } + public new string StringValue(byte radix = 10) + { + var str = Convert.ToString(LongValue, radix); return radix switch { - 1 => "0b" + str, + 2 => "0b" + str, + 8 => "0o" + str, + 10 => str, 16 => "0x" + str, - _ => (radix == 10 ? string.Empty : "0_") + str + _ => "0_" + str }; } - public IntN(RuntimeBase vm, int n = 32) - { - if (n / 8 > chars.Length) - throw new FatalException($"n too large: {n} ({n / 8})"); - N = n; - Bytes = new byte[(int)Math.Ceiling((double)n / 8)]; - ObjectId = vm.NextObjId(); - _clsInst = GetClsInst(vm, n); - } - private void Set(byte[] bytes) { if (bytes.Length > N) @@ -907,18 +826,16 @@ private void Set(byte[] bytes) Array.Copy(bytes, 0, Bytes, N - bytes.Length, bytes.Length); } - public long ObjectId { get; } - - public IClassInstance Type => _clsInst; + public override IClassInstance Type => _clsInst; - public string ToString(short variant) => StringValue((byte)(variant == 0 ? 10 : variant)); + public override string ToString(short variant) => StringValue((byte)(variant == 0 ? 10 : variant)); public Stack Invoke(RuntimeBase vm, Stack stack, string member, params IObject?[] args) { throw new NotImplementedException(); } - public string GetKey() => $"int<{N}>: {StringValue(16)}"; + public override string GetKey() => $"int<{N}>: {StringValue(16)}"; private IClassInstance GetClsInst(RuntimeBase vm, int n) {