rewrite Pointer<T>
This commit is contained in:
parent
ada9fc766e
commit
703410b548
|
|
@ -10,9 +10,12 @@ namespace Qrakhen.Qamp.Core.Execution;
|
|||
|
||||
using Op = OpCode;
|
||||
|
||||
/// <summary>
|
||||
/// Dynamic Pointer able to point to any object implementing the <see cref="IGetSet{long, TValue}"/> interface.
|
||||
/// </summary>
|
||||
public class Pointer<T>
|
||||
{
|
||||
public IGetSet<long, T> Target;
|
||||
protected IGetSet<long, T> Target;
|
||||
public long Ptr;
|
||||
|
||||
public Pointer(IGetSet<long, T> target, long pointer = 0)
|
||||
|
|
@ -21,17 +24,30 @@ public class Pointer<T>
|
|||
Ptr = pointer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the next item from <see cref="Target"/> and increases the pointer by 1.
|
||||
/// </summary>
|
||||
public T Next() => Target.Get(Ptr++);
|
||||
|
||||
public void Set(long position, T value)
|
||||
{
|
||||
Target.Set(position, value);
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets the value of <see cref="Target"/> at <paramref name="position"/>.
|
||||
/// </summary>
|
||||
public void Set(long position, T value) => Target.Set(position, value);
|
||||
|
||||
public T Get(long position)
|
||||
{
|
||||
return Target.Get(position);
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets the value of <see cref="Target"/> at the current <see cref="Ptr"/> location.
|
||||
/// </summary>
|
||||
public void Set(T value) => Set(Ptr, value);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of <see cref="Target"/> at <paramref name="position"/>.
|
||||
/// </summary>
|
||||
public T Get(long position) => Target.Get(position);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of <see cref="Target"/> at the current <see cref="Ptr"/> location.
|
||||
/// </summary>
|
||||
public T Get() => Get(Ptr);
|
||||
}
|
||||
|
||||
// this is all a bit cheesy imho
|
||||
|
|
@ -94,13 +110,13 @@ public class InstructionPtr : Pointer<Instruction>
|
|||
public class Call
|
||||
{
|
||||
public Closure Closure;
|
||||
public InstructionPtr Ptr;
|
||||
public InstructionPtr Instruction;
|
||||
public Pointer<Value> StackPtr;
|
||||
|
||||
public Call(Closure closure, StackLike<Value> stack, long stackOffset)
|
||||
{
|
||||
Closure = closure;
|
||||
Ptr = new InstructionPtr(Closure.Function.Segment);
|
||||
Instruction = new InstructionPtr(Closure.Function.Segment);
|
||||
StackPtr = new Pointer<Value>(stack, stackOffset);
|
||||
}
|
||||
}
|
||||
|
|
@ -152,10 +168,10 @@ public class Runner : IDisposable
|
|||
_logger.Method();
|
||||
Call call = Calls.Peek(-1);
|
||||
do {
|
||||
Op opCode = call.Ptr.Next();
|
||||
Op opCode = call.Instruction.Next();
|
||||
_logger.Verbose($"OpCode: {opCode}");
|
||||
switch (opCode) {
|
||||
case Op.Constant: Push(call.Ptr.NextConstant()); break;
|
||||
case Op.Constant: Push(call.Instruction.NextConstant()); break;
|
||||
case Op.Pop: Pop(); break;
|
||||
|
||||
case Op.Not: OpNot(); break;
|
||||
|
|
@ -173,21 +189,21 @@ public class Runner : IDisposable
|
|||
case Op.BitwiseRight: OpBitwiseRight(); break;
|
||||
|
||||
case Op.GetLocal: {
|
||||
long slot = call.Ptr.NextDynamic();
|
||||
long slot = call.Instruction.NextDynamic();
|
||||
_logger.Verbose($"getting slot {slot} which is {call.StackPtr.Get(slot)}");
|
||||
Push(call.StackPtr.Get(slot));
|
||||
break;
|
||||
}
|
||||
|
||||
case Op.SetLocal: {
|
||||
long slot = call.Ptr.NextDynamic();
|
||||
long slot = call.Instruction.NextDynamic();
|
||||
_logger.Verbose($"setting stackptr {slot} to {Peek()}");
|
||||
call.StackPtr.Set(slot, Peek());
|
||||
break;
|
||||
}
|
||||
|
||||
case Op.DefineGlobal: {
|
||||
string? name = call.Ptr.GetString(call.Ptr.NextDynamic())?.Value;
|
||||
string? name = call.Instruction.GetString(call.Instruction.NextDynamic())?.Value;
|
||||
if (string.IsNullOrEmpty(name))
|
||||
throw new ExecutionException($"tried to define global variable with empty name");
|
||||
Globals[name] = Pop();
|
||||
|
|
@ -196,7 +212,7 @@ public class Runner : IDisposable
|
|||
}
|
||||
|
||||
case Op.SetGlobal: {
|
||||
string? name = call.Ptr.GetString(call.Ptr.NextDynamic())?.Value;
|
||||
string? name = call.Instruction.GetString(call.Instruction.NextDynamic())?.Value;
|
||||
if (string.IsNullOrEmpty(name))
|
||||
throw new ExecutionException($"tried to set global variable with empty name");
|
||||
if (!Globals.Has(name))
|
||||
|
|
@ -206,10 +222,8 @@ public class Runner : IDisposable
|
|||
break;
|
||||
}
|
||||
|
||||
// todo: add closure
|
||||
|
||||
case Op.GetGlobal: {
|
||||
string? name = call.Ptr.GetString(call.Ptr.NextDynamic())?.Value;
|
||||
string? name = call.Instruction.GetString(call.Instruction.NextDynamic())?.Value;
|
||||
if (string.IsNullOrEmpty(name))
|
||||
throw new ExecutionException($"tried to set global variable with empty name");
|
||||
if (!Globals.Has(name))
|
||||
|
|
@ -246,7 +260,7 @@ public class Runner : IDisposable
|
|||
break;
|
||||
}
|
||||
|
||||
} while (call.Ptr.Segment.Instructions.Length > call.Ptr.Ptr);
|
||||
} while (call.Instruction.Segment.Instructions.Length > call.Instruction.Ptr);
|
||||
|
||||
return ExecutionResult.OK;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue