Implement collapse instruction. Update docs.

This commit is contained in:
2022-10-29 16:22:35 +08:00
parent c0d6b89edc
commit 4101ee8c8e
3 changed files with 84 additions and 26 deletions

View File

@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using static Cryville.Crtr.Cocos2dFrames;
namespace Cryville.Common.Pdt {
/// <summary>
@@ -15,6 +17,7 @@ namespace Cryville.Common.Pdt {
readonly StackFrame[] _stack = new StackFrame[256];
readonly byte[] _mem = new byte[0x100000];
bool _revokepttconst;
LinkedListNode<PdtInstruction> _rip;
/// <summary>
/// Evaluates an expression and passes the result to a target operator.
/// </summary>
@@ -24,8 +27,8 @@ namespace Cryville.Common.Pdt {
_framecount = 0;
_goffset = 0;
_revokepttconst = false;
for (var ins = exp.Instructions.First; ins != null; ins = ins.Next)
ins.Value.Execute(this);
for (_rip = exp.Instructions.First; _rip != null; _rip = _rip.Next)
_rip.Value.Execute(this);
Operate(target, _framecount, true);
if (exp.IsPotentialConstant) {
exp.IsConstant = exp.IsPotentialConstant = !_revokepttconst;
@@ -39,8 +42,8 @@ namespace Cryville.Common.Pdt {
_framecount = 0;
_goffset = 0;
var il = exp.Instructions;
for (var ins = il.First; ins != null; ins = ins.Next) {
var i = ins.Value;
for (_rip = il.First; _rip != null; _rip = _rip.Next) {
var i = _rip.Value;
if (i is PdtInstruction.Operate) {
int fc0 = _framecount;
int fc1 = ((PdtInstruction.Operate)i).ParamCount;
@@ -56,18 +59,16 @@ namespace Cryville.Common.Pdt {
}
else {
var frame = _stack[_framecount - 1];
il.AddAfter(ins, new PdtInstruction.PushConstant(frame.Type, _mem, frame.Offset, frame.Length));
ins = ins.Next;
for (var j = 0; j <= fc1; j++) il.Remove(ins.Previous);
_rip = il.AddAfter(_rip, new PdtInstruction.PushConstant(frame.Type, _mem, frame.Offset, frame.Length));
for (var j = 0; j <= fc1; j++) il.Remove(_rip.Previous);
}
}
else if (i is PdtInstruction.PushVariable) {
i.Execute(this);
var frame = _stack[_framecount - 1];
if (frame.Type != PdtInternalType.Undefined) {
il.AddAfter(ins, new PdtInstruction.PushConstant(frame.Type, _mem, frame.Offset, frame.Length));
ins = ins.Next;
il.Remove(ins.Previous);
_rip = il.AddAfter(_rip, new PdtInstruction.PushConstant(frame.Type, _mem, frame.Offset, frame.Length));
il.Remove(_rip.Previous);
}
}
else i.Execute(this);
@@ -138,6 +139,22 @@ namespace Cryville.Common.Pdt {
op.Call(pmem + _goffset, noset);
}
}
internal unsafe void Collapse(ref string name, LinkedListNode<PdtInstruction> target) {
fixed (byte* pmem = _mem) {
var frame = _stack[--_framecount];
if (Collapse(name, new PdtVariableMemory(frame.Type, pmem + frame.Offset, frame.Length))) {
_framecount++;
_rip = target;
}
}
}
/// <summary>
/// Gets whether to jump to the target of a collapse instruction.
/// </summary>
/// <param name="name">The name of the collapse operator.</param>
/// <param name="param">The top frame in the stack as the parameter.</param>
/// <returns>Whether to jump to the target of the collapse instruction.</returns>
protected abstract bool Collapse(string name, PdtVariableMemory param);
internal unsafe PdtVariableMemory StackAlloc(int type, byte* ptr, int len) {
fixed (StackFrame* frame = &_stack[_framecount++]) {
frame->Type = type;