add handlers and routing

This commit is contained in:
Qrakhen 2026-01-07 18:39:31 +01:00
parent bb13c0ae2b
commit bdd1322a82
6 changed files with 71 additions and 11 deletions

View File

@ -7,7 +7,7 @@ namespace Qrakhen.Qamp.Core.Collections;
/// <summary> /// <summary>
/// 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. /// 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.
/// </summary> /// </summary>
public class Memory<TValue> : public class Addreg<TValue> :
IGetSet<Address, TValue>, IGetSet<Address, TValue>,
IToArray<TValue>, IToArray<TValue>,
IEnumerable<KeyValuePair<Address, TValue>> IEnumerable<KeyValuePair<Address, TValue>>
@ -27,7 +27,7 @@ public class Memory<TValue> :
set => _data[index] = value; set => _data[index] = value;
} }
public Memory(int size = 4096) public Addreg(int size = 4096)
{ {
Size = size; Size = size;
_data = new TValue[size]; _data = new TValue[size];

View File

@ -8,11 +8,13 @@ public readonly record struct Operation(OpCode OpCode, Value Left, Value Right);
public delegate Value OperationHandler(Operation operation); 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<OpCode, OperationHandler> _operations; private readonly Register<OpCode, OperationHandler> _operations;
public bool CanResolve(OpCode opCode) => (opCode & OpCode.F_Operation) > 0;
public static Value Resolve(Operation operation) public static Value Resolve(Operation operation)
{ {
@ -41,7 +43,7 @@ public static class ValueOperation
}; };
} }
static ValueOperation() static AlgorithmicHandler()
{ {
_operations = new Register<OpCode, OperationHandler> { _operations = new Register<OpCode, OperationHandler> {
{ OpCode.Equal, Equal }, { OpCode.Equal, Equal },

View File

@ -43,6 +43,7 @@ public enum OpCode
BitwiseXor = 0x67, BitwiseXor = 0x67,
BitwiseLeft = 0x68, BitwiseLeft = 0x68,
BitwiseRight = 0x69, BitwiseRight = 0x69,
F_Unary = 0x0a, F_Unary = 0x0a,
Not = 0x6a, Not = 0x6a,
Negate = 0x6b, Negate = 0x6b,

View File

@ -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<IOperationResolver> _handlers = [];
private readonly Dictionary<OpCode, IOperationResolver> _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 public class Runner : IDisposable
{ {
private readonly ILogger _logger = LoggerService.Get<Runner>(); private readonly ILogger _logger = LoggerService.Get<Runner>();
@ -96,13 +146,13 @@ public class Runner : IDisposable
//IO.Console.Write($"{opCode}: \n - {string.Join("\n - ", Stack.ToArray().Subset(0, Stack.Count))}"); //IO.Console.Write($"{opCode}: \n - {string.Join("\n - ", Stack.ToArray().Subset(0, Stack.Count))}");
if (TestFlag(opCode, Op.F_Operation)) { if (TestFlag(opCode, Op.F_Operation)) {
Value result = ValueOperation.Resolve(PopOperation(opCode)); Value result = AlgorithmicHandler.Resolve(PopOperation(opCode));
Push(result); Push(result);
continue; continue;
} }
if (TestFlag(opCode, Op.F_Compare)) { if (TestFlag(opCode, Op.F_Compare)) {
Value result = ValueOperation.Resolve(PopOperation(opCode)); Value result = AlgorithmicHandler.Resolve(PopOperation(opCode));
Push(result); Push(result);
continue; continue;
} }

View File

@ -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<Obj> _register = [];
}
public class Obj(ValueType type) : ITypedValue public class Obj(ValueType type) : ITypedValue
{ {

View File

@ -9,7 +9,7 @@ public readonly struct Ptr
{ {
private static readonly PushStack<Obj> _register = new(); private static readonly PushStack<Obj> _register = new();
private static readonly Collections.Memory<Obj> _memory = []; private static readonly Collections.Addreg<Obj> _memory = [];
[Serialized] public readonly Address Address; [Serialized] public readonly Address Address;