From bdd1322a825595f475cb2bb08ab3aa633680d944 Mon Sep 17 00:00:00 2001 From: Qrakhen Date: Wed, 7 Jan 2026 18:39:31 +0100 Subject: [PATCH] add handlers and routing --- .../Collections/{Memory.cs => Addreg.cs} | 6 +-- ...alueOperation.cs => AlgorithmicHandler.cs} | 10 ++-- Qrakhen.Qamp.Core/Execution/OpCode.cs | 1 + Qrakhen.Qamp.Core/Execution/Runner.cs | 54 ++++++++++++++++++- Qrakhen.Qamp.Core/Values/Objects/Obj.cs | 9 +++- Qrakhen.Qamp.Core/Values/Ptr.cs | 2 +- 6 files changed, 71 insertions(+), 11 deletions(-) rename Qrakhen.Qamp.Core/Collections/{Memory.cs => Addreg.cs} (95%) rename Qrakhen.Qamp.Core/Execution/{ValueOperation.cs => AlgorithmicHandler.cs} (95%) diff --git a/Qrakhen.Qamp.Core/Collections/Memory.cs b/Qrakhen.Qamp.Core/Collections/Addreg.cs similarity index 95% rename from Qrakhen.Qamp.Core/Collections/Memory.cs rename to Qrakhen.Qamp.Core/Collections/Addreg.cs index 2723c79..45e3d67 100644 --- a/Qrakhen.Qamp.Core/Collections/Memory.cs +++ b/Qrakhen.Qamp.Core/Collections/Addreg.cs @@ -7,7 +7,7 @@ namespace Qrakhen.Qamp.Core.Collections; /// /// Similar to a register with the caveat that the memory can free up or reserve blocks within itself, returning the next writeable address when storing data. /// -public class Memory : +public class Addreg : IGetSet, IToArray, IEnumerable> @@ -27,7 +27,7 @@ public class Memory : set => _data[index] = value; } - public Memory(int size = 4096) + public Addreg(int size = 4096) { Size = size; _data = new TValue[size]; @@ -53,7 +53,7 @@ public class Memory : if (mask < BLOCK_FULL) { int index = 0; - while ((mask & (1 << index)) > 0) + while ((mask & (1 << index)) > 0) index++; return (Address)((long)block * BLOCK_SIZE + index); diff --git a/Qrakhen.Qamp.Core/Execution/ValueOperation.cs b/Qrakhen.Qamp.Core/Execution/AlgorithmicHandler.cs similarity index 95% rename from Qrakhen.Qamp.Core/Execution/ValueOperation.cs rename to Qrakhen.Qamp.Core/Execution/AlgorithmicHandler.cs index 7f52389..da8c933 100644 --- a/Qrakhen.Qamp.Core/Execution/ValueOperation.cs +++ b/Qrakhen.Qamp.Core/Execution/AlgorithmicHandler.cs @@ -8,11 +8,13 @@ public readonly record struct Operation(OpCode OpCode, Value Left, Value Right); public delegate Value OperationHandler(Operation operation); -public static class ValueOperation +public class AlgorithmicHandler : IOperationResolver { - private static readonly ILogger _logger = LoggerService.Get(nameof(ValueOperation)); + private readonly ILogger _logger = LoggerService.Get(nameof(AlgorithmicHandler)); - private static readonly Register _operations; + private readonly Register _operations; + + public bool CanResolve(OpCode opCode) => (opCode & OpCode.F_Operation) > 0; public static Value Resolve(Operation operation) { @@ -41,7 +43,7 @@ public static class ValueOperation }; } - static ValueOperation() + static AlgorithmicHandler() { _operations = new Register { { OpCode.Equal, Equal }, diff --git a/Qrakhen.Qamp.Core/Execution/OpCode.cs b/Qrakhen.Qamp.Core/Execution/OpCode.cs index 811e764..af47099 100644 --- a/Qrakhen.Qamp.Core/Execution/OpCode.cs +++ b/Qrakhen.Qamp.Core/Execution/OpCode.cs @@ -43,6 +43,7 @@ public enum OpCode BitwiseXor = 0x67, BitwiseLeft = 0x68, BitwiseRight = 0x69, + F_Unary = 0x0a, Not = 0x6a, Negate = 0x6b, diff --git a/Qrakhen.Qamp.Core/Execution/Runner.cs b/Qrakhen.Qamp.Core/Execution/Runner.cs index 68e7cb7..51ffe5d 100644 --- a/Qrakhen.Qamp.Core/Execution/Runner.cs +++ b/Qrakhen.Qamp.Core/Execution/Runner.cs @@ -25,6 +25,56 @@ public class Call } } +public interface IOperationResolver +{ + bool CanResolve(OpCode code); + OperationResult Resolve(OpCode code); +} + +public struct OperationResult +{ + public bool Success; + public Value Value; + public RuntimeException? Error; + + public static OperationResult MakeSuccess(Value value) + { + return new OperationResult { Success = true, Value = value }; + } + + public static OperationResult MakeError(RuntimeException exception) + { + return new OperationResult { Success = false, Value = Value.Void, Error = exception }; + } +} + +public class OperationRouter +{ + private readonly List _handlers = []; + private readonly Dictionary _cache = []; + + public void Register(IOperationResolver resolver) + { + _handlers.Add(resolver); + } + + public OperationResult Route(OpCode opCode) + { + if (!_cache.TryGetValue(opCode, out IOperationResolver? resolver)) { + resolver = _handlers.FirstOrDefault(h => h.CanResolve(opCode)); + if (resolver == null) + return OperationResult.MakeError( + new RuntimeException( + $"Could not find an IOperationHandler for OpCode {opCode}.", + opCode)); + + _cache[opCode] = resolver; + } + + return resolver.Resolve(opCode); + } +} + public class Runner : IDisposable { private readonly ILogger _logger = LoggerService.Get(); @@ -96,13 +146,13 @@ public class Runner : IDisposable //IO.Console.Write($"{opCode}: \n - {string.Join("\n - ", Stack.ToArray().Subset(0, Stack.Count))}"); if (TestFlag(opCode, Op.F_Operation)) { - Value result = ValueOperation.Resolve(PopOperation(opCode)); + Value result = AlgorithmicHandler.Resolve(PopOperation(opCode)); Push(result); continue; } if (TestFlag(opCode, Op.F_Compare)) { - Value result = ValueOperation.Resolve(PopOperation(opCode)); + Value result = AlgorithmicHandler.Resolve(PopOperation(opCode)); Push(result); continue; } diff --git a/Qrakhen.Qamp.Core/Values/Objects/Obj.cs b/Qrakhen.Qamp.Core/Values/Objects/Obj.cs index f2861a4..bf76bcf 100644 --- a/Qrakhen.Qamp.Core/Values/Objects/Obj.cs +++ b/Qrakhen.Qamp.Core/Values/Objects/Obj.cs @@ -1,4 +1,11 @@ -namespace Qrakhen.Qamp.Core.Values.Objects; +using Qrakhen.Qamp.Core.Collections; + +namespace Qrakhen.Qamp.Core.Values.Objects; + +public static class ObjRegister +{ + private static readonly Addreg _register = []; +} public class Obj(ValueType type) : ITypedValue { diff --git a/Qrakhen.Qamp.Core/Values/Ptr.cs b/Qrakhen.Qamp.Core/Values/Ptr.cs index f22fca0..430029d 100644 --- a/Qrakhen.Qamp.Core/Values/Ptr.cs +++ b/Qrakhen.Qamp.Core/Values/Ptr.cs @@ -9,7 +9,7 @@ public readonly struct Ptr { private static readonly PushStack _register = new(); - private static readonly Collections.Memory _memory = []; + private static readonly Collections.Addreg _memory = []; [Serialized] public readonly Address Address;