Returns whether PDT evaluation succeeded.

This commit is contained in:
2023-04-03 17:00:05 +08:00
parent 072703efe7
commit 2e69035618

View File

@@ -23,16 +23,18 @@ namespace Cryville.Common.Pdt {
/// </summary> /// </summary>
/// <param name="target">The target operator.</param> /// <param name="target">The target operator.</param>
/// <param name="exp">The expression to evaluate.</param> /// <param name="exp">The expression to evaluate.</param>
public void Evaluate(PdtOperator target, PdtExpression exp) { /// <returns>Whether the evaluaton succeeded.</returns>
public bool Evaluate(PdtOperator target, PdtExpression exp) {
_framecount = 0; _framecount = 0;
_goffset = 0; _goffset = 0;
_revokepttconst = false; _revokepttconst = false;
for (_rip = exp.Instructions.First; _rip != null; _rip = _rip.Next) for (_rip = exp.Instructions.First; _rip != null; _rip = _rip.Next)
_rip.Value.Execute(this); _rip.Value.Execute(this);
Operate(target, _framecount, true); if (!Operate(target, _framecount, true)) return false;
if (exp.IsPotentialConstant) { if (exp.IsPotentialConstant) {
exp.IsConstant = exp.IsPotentialConstant = !_revokepttconst; exp.IsConstant = exp.IsPotentialConstant = !_revokepttconst;
} }
return true;
} }
/// <summary> /// <summary>
/// Patches an expression with a lefthand variable and a compound operator. /// Patches an expression with a lefthand variable and a compound operator.
@@ -184,7 +186,7 @@ namespace Cryville.Common.Pdt {
/// <returns>An operator of the specific name.</returns> /// <returns>An operator of the specific name.</returns>
/// <remarks>The parameter count of the returned operator does not necessarily equal to <paramref name="pc" />.</remarks> /// <remarks>The parameter count of the returned operator does not necessarily equal to <paramref name="pc" />.</remarks>
protected abstract PdtOperator GetOperator(PdtOperatorSignature sig); protected abstract PdtOperator GetOperator(PdtOperatorSignature sig);
unsafe void Operate(PdtOperator op, int pc, bool noset = false) { unsafe bool Operate(PdtOperator op, int pc, bool noset = false) {
fixed (byte* pmem = _mem) { fixed (byte* pmem = _mem) {
op.Begin(this, pc); op.Begin(this, pc);
for (int i = 0; i < pc; i++) { for (int i = 0; i < pc; i++) {
@@ -192,12 +194,13 @@ namespace Cryville.Common.Pdt {
if (frame.Type == PdtInternalType.Error) { if (frame.Type == PdtInternalType.Error) {
_framecount -= pc - i; _framecount -= pc - i;
_stack[_framecount++] = new StackFrame { Type = PdtInternalType.Error, Offset = _goffset, Length = 0 }; _stack[_framecount++] = new StackFrame { Type = PdtInternalType.Error, Offset = _goffset, Length = 0 };
return; return false;
} }
op.LoadOperand(new PdtVariableMemory(frame.Type, pmem + frame.Offset, frame.Length)); op.LoadOperand(new PdtVariableMemory(frame.Type, pmem + frame.Offset, frame.Length));
_goffset -= frame.Length; _goffset -= frame.Length;
} }
op.Call(pmem + _goffset, noset); op.Call(pmem + _goffset, noset);
return true;
} }
} }
internal unsafe void Collapse(int name, LinkedListNode<PdtInstruction> target) { internal unsafe void Collapse(int name, LinkedListNode<PdtInstruction> target) {