From 88a46127d72fca34a10e6c66f1f317c6692f7d03 Mon Sep 17 00:00:00 2001 From: PopSlime Date: Mon, 29 May 2023 17:04:22 +0800 Subject: [PATCH] Adapt PDT evaluator to pseudo-lambda expressions. --- .../Cryville/Common/Pdt/PdtEvaluatorBase.cs | 78 +++++++++---------- Assets/Cryville/Common/Pdt/PdtExpression.cs | 12 +-- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/Assets/Cryville/Common/Pdt/PdtEvaluatorBase.cs b/Assets/Cryville/Common/Pdt/PdtEvaluatorBase.cs index 0001054..82d3e29 100644 --- a/Assets/Cryville/Common/Pdt/PdtEvaluatorBase.cs +++ b/Assets/Cryville/Common/Pdt/PdtEvaluatorBase.cs @@ -17,7 +17,6 @@ namespace Cryville.Common.Pdt { readonly StackFrame[] _stack = new StackFrame[256]; readonly byte[] _mem = new byte[0x100000]; bool _revokepttconst; - LinkedListNode _ip; /// /// Evaluates an expression and passes the result to a target operator. /// @@ -25,15 +24,16 @@ namespace Cryville.Common.Pdt { /// The expression to evaluate. /// Whether the evaluaton succeeded. public bool Evaluate(PdtOperator target, PdtExpression exp) { - _framecount = 0; - _goffset = 0; + var prevFrameCount = _framecount; _revokepttconst = false; - for (_ip = exp.Instructions.First; _ip != null; _ip = _ip.Next) - _ip.Value.Execute(this); + for (var ip = exp.Instructions.First; ip != null; ip = ip.Next) + ip.Value.Execute(this, ref ip); if (exp.IsPotentialConstant) { exp.IsConstant = exp.IsPotentialConstant = !_revokepttconst; } - return Operate(target, _framecount, true); + var ret = Operate(target, _framecount - prevFrameCount, true); + for (var i = prevFrameCount; i < _framecount; i++) DiscardStack(); + return ret; } /// /// Optimizes an expression by merging its instructions. @@ -45,14 +45,14 @@ namespace Cryville.Common.Pdt { List ct; var cols = new Dictionary, List>(); var il = exp.Instructions; - _ip = il.First; - while (_ip != null) { + var ip = il.First; + while (ip != null) { bool nextFlag = false; - var i = _ip.Value; + var i = ip.Value; if (i is PdtInstruction.Operate) { int fc0 = _framecount; int fc1 = ((PdtInstruction.Operate)i).Signature.ParamCount; - try { i.Execute(this); } catch (Exception) { } + try { i.Execute(this, ref ip); } catch (Exception) { } if (fc0 - _framecount == fc1) { unsafe { fixed (StackFrame* frame = &_stack[_framecount++]) { @@ -65,37 +65,37 @@ namespace Cryville.Common.Pdt { else { var frame = _stack[_framecount - 1]; if (frame.Type != PdtInternalType.Error) { - ReplaceIP(il, new PdtInstruction.PushConstant(frame.Type, _mem, frame.Offset, frame.Length), cols); - for (var j = 0; j < fc1; j++) il.Remove(_ip.Previous); + ReplaceIP(il, ref ip, new PdtInstruction.PushConstant(frame.Type, _mem, frame.Offset, frame.Length), cols); + for (var j = 0; j < fc1; j++) il.Remove(ip.Previous); } } } else if (i is PdtInstruction.Collapse) { var t = (PdtInstruction.Collapse)i; try { - var pins = _ip; - i.Execute(this); + var pins = ip; + i.Execute(this, ref ip); if (_stack[_framecount - 1].Type == PdtInternalType.Error) { throw new EvaluationFailureException(); } - if (_ip == pins) { - _ip = _ip.Next; - il.Remove(_ip.Previous); - il.Remove(_ip.Previous); - _ip = _ip.Previous; - if (_ip == null) { - _ip = il.First; + if (ip == pins) { + ip = ip.Next; + il.Remove(ip.Previous); + il.Remove(ip.Previous); + ip = ip.Previous; + if (ip == null) { + ip = il.First; nextFlag = true; } } else { - _ip = pins.Previous; - while (_ip.Next != t.Target) il.Remove(_ip.Next); - il.Remove(_ip.Next); + ip = pins.Previous; + while (ip.Next != t.Target) il.Remove(ip.Next); + il.Remove(ip.Next); if (cols.TryGetValue(t.Target, out ct)) { - foreach (var u in ct) u.Target = _ip; + foreach (var u in ct) u.Target = ip; cols.Remove(t.Target); - cols.Add(_ip, ct); + cols.Add(ip, ct); } } } @@ -105,14 +105,14 @@ namespace Cryville.Common.Pdt { } } else if (i is PdtInstruction.PushVariable) { - i.Execute(this); + i.Execute(this, ref ip); var frame = _stack[_framecount - 1]; if (frame.Type != PdtInternalType.Undefined && frame.Type != PdtInternalType.Error) { - ReplaceIP(il, new PdtInstruction.PushConstant(frame.Type, _mem, frame.Offset, frame.Length), cols); + ReplaceIP(il, ref ip, new PdtInstruction.PushConstant(frame.Type, _mem, frame.Offset, frame.Length), cols); } } - else i.Execute(this); - if (_ip != null && cols.TryGetValue(_ip, out ct)) { + else i.Execute(this, ref ip); + if (ip != null && cols.TryGetValue(ip, out ct)) { unsafe { fixed (StackFrame* frame = &_stack[_framecount - 1]) { frame->Type = PdtInternalType.Error; @@ -121,7 +121,7 @@ namespace Cryville.Common.Pdt { } } } - if (!nextFlag) _ip = _ip.Next; + if (!nextFlag) ip = ip.Next; } exp.IsConstant = true; exp.IsPotentialConstant = true; @@ -135,12 +135,12 @@ namespace Cryville.Common.Pdt { } } } - void ReplaceIP(LinkedList il, PdtInstruction ins, Dictionary, List> cols) { + void ReplaceIP(LinkedList il, ref LinkedListNode ip, PdtInstruction ins, Dictionary, List> cols) { List cins; - if (cols.TryGetValue(_ip, out cins)) cols.Remove(_ip); - _ip = il.AddAfter(_ip, ins); - il.Remove(_ip.Previous); - if (cins != null) cols.Add(_ip, cins); + if (cols.TryGetValue(ip, out cins)) cols.Remove(ip); + ip = il.AddAfter(ip, ins); + il.Remove(ip.Previous); + if (cins != null) cols.Add(ip, cins); } /// /// Revokes the potential constant mark of the current expression. @@ -210,17 +210,17 @@ namespace Cryville.Common.Pdt { return true; } } - internal unsafe void Collapse(int name, LinkedListNode target) { + internal unsafe void Collapse(int name, ref LinkedListNode self, LinkedListNode target) { fixed (byte* pmem = _mem) { var frame = _stack[--_framecount]; if (frame.Type == PdtInternalType.Error) { _stack[_framecount++] = new StackFrame { Type = PdtInternalType.Error, Offset = _goffset, Length = 0 }; - _ip = target; + self = target; return; } if (Collapse(name, new PdtVariableMemory(frame.Type, pmem + frame.Offset, frame.Length))) { _framecount++; - _ip = target; + self = target; } } } diff --git a/Assets/Cryville/Common/Pdt/PdtExpression.cs b/Assets/Cryville/Common/Pdt/PdtExpression.cs index 0266c80..0f63d38 100644 --- a/Assets/Cryville/Common/Pdt/PdtExpression.cs +++ b/Assets/Cryville/Common/Pdt/PdtExpression.cs @@ -51,7 +51,7 @@ namespace Cryville.Common.Pdt { } } internal abstract class PdtInstruction { - internal abstract void Execute(PdtEvaluatorBase etor); + internal abstract void Execute(PdtEvaluatorBase etor, ref LinkedListNode self); public class PushConstant : PdtInstruction { public int Type { get; private set; } public byte[] Value { get; private set; } @@ -64,7 +64,7 @@ namespace Cryville.Common.Pdt { Value = new byte[len]; Array.Copy(buffer, offset, Value, 0, len); } - internal override void Execute(PdtEvaluatorBase etor) { + internal override void Execute(PdtEvaluatorBase etor, ref LinkedListNode self) { etor.PushConstant(Type, Value); } public override string ToString() { @@ -76,7 +76,7 @@ namespace Cryville.Common.Pdt { public bool Forced { get; private set; } public PushVariable(int name, bool forced = false) { Name = name; Forced = forced; } public PushVariable(string name, bool forced = false) : this(IdentifierManager.Shared.Request(name)) { Forced = forced; } - internal override void Execute(PdtEvaluatorBase etor) { + internal override void Execute(PdtEvaluatorBase etor, ref LinkedListNode self) { etor.PushVariable(Name, Forced); } public override string ToString() { @@ -91,7 +91,7 @@ namespace Cryville.Common.Pdt { public Operate(string name, int paramCount) { Signature = new PdtOperatorSignature(name, paramCount); } - internal override void Execute(PdtEvaluatorBase etor) { + internal override void Execute(PdtEvaluatorBase etor, ref LinkedListNode self) { etor.Operate(Signature); } public override string ToString() { @@ -105,8 +105,8 @@ namespace Cryville.Common.Pdt { Name = IdentifierManager.Shared.Request(name); Target = target; } - internal override void Execute(PdtEvaluatorBase etor) { - etor.Collapse(Name, Target); + internal override void Execute(PdtEvaluatorBase etor, ref LinkedListNode self) { + etor.Collapse(Name, ref self, Target); } public override string ToString() { return string.Format("col {0}{{{1}}}", IdentifierManager.Shared.Retrieve(Name), Target.Value);