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