diff --git a/Assets/Cryville/Common/Pdt/PdtEvaluatorBase.cs b/Assets/Cryville/Common/Pdt/PdtEvaluatorBase.cs
index 9d5fabe..d73caf7 100644
--- a/Assets/Cryville/Common/Pdt/PdtEvaluatorBase.cs
+++ b/Assets/Cryville/Common/Pdt/PdtEvaluatorBase.cs
@@ -1,4 +1,6 @@
using System;
+using System.Collections.Generic;
+using static Cryville.Crtr.Cocos2dFrames;
namespace Cryville.Common.Pdt {
///
@@ -15,6 +17,7 @@ namespace Cryville.Common.Pdt {
readonly StackFrame[] _stack = new StackFrame[256];
readonly byte[] _mem = new byte[0x100000];
bool _revokepttconst;
+ LinkedListNode _rip;
///
/// Evaluates an expression and passes the result to a target operator.
///
@@ -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 target) {
+ fixed (byte* pmem = _mem) {
+ var frame = _stack[--_framecount];
+ if (Collapse(name, new PdtVariableMemory(frame.Type, pmem + frame.Offset, frame.Length))) {
+ _framecount++;
+ _rip = target;
+ }
+ }
+ }
+ ///
+ /// Gets whether to jump to the target of a collapse instruction.
+ ///
+ /// The name of the collapse operator.
+ /// The top frame in the stack as the parameter.
+ /// Whether to jump to the target of the collapse instruction.
+ 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;
diff --git a/Assets/Cryville/Common/Pdt/PdtExpression.cs b/Assets/Cryville/Common/Pdt/PdtExpression.cs
index 769cedc..2da3b79 100644
--- a/Assets/Cryville/Common/Pdt/PdtExpression.cs
+++ b/Assets/Cryville/Common/Pdt/PdtExpression.cs
@@ -77,15 +77,42 @@ namespace Cryville.Common.Pdt {
return string.Format("op {0}({1})", Name, ParamCount);
}
}
+ public class Collapse : PdtInstruction {
+ private string m_name;
+ public string Name { get { return m_name; } }
+ public LinkedListNode Target { get; private set; }
+ public Collapse(string name, LinkedListNode target) {
+ m_name = name;
+ Target = target;
+ }
+ internal override void Execute(PdtEvaluatorBase etor) {
+ etor.Collapse(ref m_name, Target);
+ }
+ public override string ToString() {
+ return string.Format("col {0}{{{1}}}", Name, Target.Value);
+ }
+ }
}
public partial class PdtInterpreter {
- readonly static Dictionary pri = new Dictionary {
- { '*', 5 }, { '/', 5 }, { '%', 5 },
- { '+', 4 }, { '-', 4 },
- { '=', 3 }, { '<', 3 }, { '>', 3 },
+ readonly static Dictionary OP_PRIORITY = new Dictionary {
+ { '*', 6 }, { '/', 6 }, { '%', 6 },
+ { '+', 5 }, { '-', 5 },
+ { '=', 4 }, { '<', 4 }, { '>', 4 },
+ { '!', 3 },
{ '&', 2 },
- { '|', 1 }, { '!', 1 },
+ { '|', 1 },
{ ',', 0 },
+ { '$', -1 },
+ };
+ readonly static Dictionary OP_TYPE = new Dictionary {
+ { '*', 0 }, { '/', 0 }, { '%', 0 },
+ { '+', 0 }, { '-', 0 },
+ { '=', 0 }, { '<', 0 }, { '>', 0 },
+ { '!', 0 },
+ { '&', 1 },
+ { '|', 1 },
+ { ',', -2 },
+ { '$', -1 },
};
readonly static PdtExpression _emptyexp;
@@ -118,7 +145,7 @@ namespace Cryville.Common.Pdt {
}
public readonly static PdtExpToken EmptyOperator = new PdtExpToken {
Type = 0x0080,
- Value = "",
+ Value = "$",
};
}
@@ -131,7 +158,7 @@ namespace Cryville.Common.Pdt {
///
/// - -2The expression is in a root scope which ends at a semicolon.
/// - -1The expression is in a bracketed scope which ends at a closing parenthesis.
- /// - Any non-negative valuesThe expression is in an auxiliary scope which ends before a closing parenthesis or an operator whose priority is lower (less) than the value of this parameter.
+ /// - Any non-negative valuesThe expression is in an auxiliary scope which ends before a closing parenthesis or an operator whose priority is lower (less) than or equal to the value of this parameter.
///
///
/// The parameter count in this (sub)expression.
@@ -140,25 +167,33 @@ namespace Cryville.Common.Pdt {
PdtExpToken InterpretExp(LinkedList ins, int enc, out int pc, PdtExpToken? token = null) {
PdtExpToken t1, t2;
int insc0 = ins.Count;
+ Dictionary, string> colp = null;
pc = 1;
if (token == null) t1 = PdtExpToken.EmptyOperator;
- else t1 = token.Value;
+ else {
+ t1 = token.Value;
+ if (OP_TYPE[t1.Value[0]] == 1)
+ colp = new Dictionary, string> { { ins.Last, token.Value.Value } };
+ }
while (true) {
t2 = InterpretExpBlock(ins);
panic:
switch (t2.Type) {
case 0x0080:
- if (t1.Value != "") {
- int p1 = pri[t1.Value[0]];
- int p2 = pri[t2.Value[0]];
+ if (OP_TYPE[t1.Value[0]] != -1) {
+ int p1 = OP_PRIORITY[t1.Value[0]];
+ int p2 = OP_PRIORITY[t2.Value[0]];
if (p2 <= enc) goto exit;
if (p2 > p1) {
int _;
t2 = InterpretExp(ins, p1, out _, t2);
goto panic;
}
- if (t1.Value != ",") ins.AddLast(new PdtInstruction.Operate(t1.Value, 2));
- else pc++;
+ switch (OP_TYPE[t1.Value[0]]) {
+ case 0: ins.AddLast(new PdtInstruction.Operate(t1.Value, 2)); break;
+ case 1: colp.Add(ins.Last, t2.Value); break;
+ default: pc++; break;
+ }
}
t1 = t2;
break;
@@ -171,8 +206,14 @@ namespace Cryville.Common.Pdt {
}
}
exit:
- if (t1.Value != "," && t1.Value != "") ins.AddLast(new PdtInstruction.Operate(t1.Value, 2));
- else if (t1.Value == ",") pc++;
+ switch (OP_TYPE[t1.Value[0]]) {
+ case 0: ins.AddLast(new PdtInstruction.Operate(t1.Value, 2)); break;
+ case 1:
+ foreach (var p in colp)
+ ins.AddAfter(p.Key, new PdtInstruction.Collapse(p.Value, ins.Last));
+ break;
+ case -2: pc++; break;
+ }
return t2;
}
diff --git a/Assets/Cryville/Common/Pdt/PdtInternalType.cs b/Assets/Cryville/Common/Pdt/PdtInternalType.cs
index a1fcc4a..51ede3f 100644
--- a/Assets/Cryville/Common/Pdt/PdtInternalType.cs
+++ b/Assets/Cryville/Common/Pdt/PdtInternalType.cs
@@ -17,7 +17,7 @@
///
public readonly static int String = "string".GetHashCode();
///
- /// A sequence of UTF-16 code units representing the name of an undefined variable.
+ /// A sequence of UTF-16 code units, with a prefix indicating the number of the code units, representing the name of an undefined variable.
///
public readonly static int Undefined = "undefined".GetHashCode();
///