Add forced variable syntax in PDT.
This commit is contained in:
@@ -105,7 +105,7 @@ namespace Cryville.Common.Pdt {
|
|||||||
else if (i is PdtInstruction.PushVariable) {
|
else if (i is PdtInstruction.PushVariable) {
|
||||||
i.Execute(this);
|
i.Execute(this);
|
||||||
var frame = _stack[_framecount - 1];
|
var frame = _stack[_framecount - 1];
|
||||||
if (frame.Type != PdtInternalType.Undefined) {
|
if (frame.Type != PdtInternalType.Undefined && frame.Type != PdtInternalType.Error) {
|
||||||
_rip = il.AddAfter(_rip, new PdtInstruction.PushConstant(frame.Type, _mem, frame.Offset, frame.Length));
|
_rip = il.AddAfter(_rip, new PdtInstruction.PushConstant(frame.Type, _mem, frame.Offset, frame.Length));
|
||||||
il.Remove(_rip.Previous);
|
il.Remove(_rip.Previous);
|
||||||
}
|
}
|
||||||
@@ -148,10 +148,10 @@ namespace Cryville.Common.Pdt {
|
|||||||
_goffset += value.Length;
|
_goffset += value.Length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internal unsafe void PushVariable(int name) {
|
internal unsafe void PushVariable(int name, bool forced) {
|
||||||
fixed (StackFrame* frame = &_stack[_framecount++]) {
|
fixed (StackFrame* frame = &_stack[_framecount++]) {
|
||||||
byte[] value;
|
byte[] value;
|
||||||
GetVariable(name, out frame->Type, out value);
|
GetVariable(name, forced, out frame->Type, out value);
|
||||||
frame->Offset = _goffset;
|
frame->Offset = _goffset;
|
||||||
frame->Length = value.Length;
|
frame->Length = value.Length;
|
||||||
Array.Copy(value, 0, _mem, _goffset, value.Length);
|
Array.Copy(value, 0, _mem, _goffset, value.Length);
|
||||||
@@ -162,9 +162,10 @@ namespace Cryville.Common.Pdt {
|
|||||||
/// Gets a variable of the specified name.
|
/// Gets a variable of the specified name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name of the variable.</param>
|
/// <param name="name">The name of the variable.</param>
|
||||||
|
/// <param name="forced">Whether to produce an error stack instead of an identifier stack if the variable is not found.</param>
|
||||||
/// <param name="type">The type of the variable.</param>
|
/// <param name="type">The type of the variable.</param>
|
||||||
/// <param name="value">The value of the variable.</param>
|
/// <param name="value">The value of the variable.</param>
|
||||||
protected abstract void GetVariable(int name, out int type, out byte[] value);
|
protected abstract void GetVariable(int name, bool forced, out int type, out byte[] value);
|
||||||
internal void Operate(PdtOperatorSignature sig) {
|
internal void Operate(PdtOperatorSignature sig) {
|
||||||
PdtOperator op;
|
PdtOperator op;
|
||||||
try { op = GetOperator(sig); }
|
try { op = GetOperator(sig); }
|
||||||
|
|||||||
@@ -51,13 +51,14 @@ namespace Cryville.Common.Pdt {
|
|||||||
}
|
}
|
||||||
public class PushVariable : PdtInstruction {
|
public class PushVariable : PdtInstruction {
|
||||||
public int Name { get; private set; }
|
public int Name { get; private set; }
|
||||||
public PushVariable(int name) { Name = name; }
|
public bool Forced { get; private set; }
|
||||||
public PushVariable(string name) : this(IdentifierManager.SharedInstance.Request(name)) { }
|
public PushVariable(int name, bool forced = false) { Name = name; Forced = forced; }
|
||||||
|
public PushVariable(string name, bool forced = false) : this(IdentifierManager.SharedInstance.Request(name)) { Forced = forced; }
|
||||||
internal override void Execute(PdtEvaluatorBase etor) {
|
internal override void Execute(PdtEvaluatorBase etor) {
|
||||||
etor.PushVariable(Name);
|
etor.PushVariable(Name, Forced);
|
||||||
}
|
}
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
return string.Format("pushv {0}", IdentifierManager.SharedInstance.Retrieve(Name));
|
return string.Format(Forced ? "pushv ?{0}" : "pushv {0}", IdentifierManager.SharedInstance.Retrieve(Name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public class Operate : PdtInstruction {
|
public class Operate : PdtInstruction {
|
||||||
@@ -239,7 +240,11 @@ namespace Cryville.Common.Pdt {
|
|||||||
if (defs.TryGetValue(buf.Value.Value, out def)) {
|
if (defs.TryGetValue(buf.Value.Value, out def)) {
|
||||||
foreach (var i in def.Instructions) ins.AddLast(i);
|
foreach (var i in def.Instructions) ins.AddLast(i);
|
||||||
}
|
}
|
||||||
else ins.AddLast(new PdtInstruction.PushVariable(buf.Value.Value));
|
else {
|
||||||
|
var name = buf.Value.Value;
|
||||||
|
if (name[0] == '?') ins.AddLast(new PdtInstruction.PushVariable(name.Substring(1), true));
|
||||||
|
else ins.AddLast(new PdtInstruction.PushVariable(name));
|
||||||
|
}
|
||||||
buf = null;
|
buf = null;
|
||||||
TryPushAdjMul(ins, ref flag);
|
TryPushAdjMul(ins, ref flag);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ namespace Cryville.Common.Pdt {
|
|||||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000,
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0001, 0x0000, 0x0000, 0x0001, 0x0000, 0x0000,
|
||||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||||
0x0001, 0x0080, 0x0100, 0x0000, 0x0030, 0x0080, 0x0080, 0x0000, 0x0200, 0x0400, 0x0080, 0x0080, 0x0080, 0x0080, 0x0040, 0x0080,
|
0x0001, 0x0080, 0x0100, 0x0000, 0x0030, 0x0080, 0x0080, 0x0000, 0x0200, 0x0400, 0x0080, 0x0080, 0x0080, 0x0080, 0x0040, 0x0080,
|
||||||
0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x1000, 0x1800, 0x0080, 0x0080, 0x0080, 0x0000,
|
0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x0050, 0x1000, 0x1800, 0x0080, 0x0080, 0x0080, 0x0030,
|
||||||
0x0080, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030,
|
0x0080, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030,
|
||||||
0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0000, 0x0000, 0x0000, 0x0000, 0x0030,
|
0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0000, 0x0000, 0x0000, 0x0000, 0x0030,
|
||||||
0x0000, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030,
|
0x0000, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030,
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ namespace Cryville.Crtr {
|
|||||||
static readonly int _var_true = IdentifierManager.SharedInstance.Request("true");
|
static readonly int _var_true = IdentifierManager.SharedInstance.Request("true");
|
||||||
static readonly int _var_false = IdentifierManager.SharedInstance.Request("false");
|
static readonly int _var_false = IdentifierManager.SharedInstance.Request("false");
|
||||||
protected override void GetVariable(int name, out int type, out byte[] value) {
|
protected override void GetVariable(int name, out int type, out byte[] value) {
|
||||||
|
protected override void GetVariable(int name, bool forced, out int type, out byte[] value) {
|
||||||
if (name == _var_w) { LoadNum(ChartPlayer.hitRect.width); type = PdtInternalType.Number; value = _numbuf; }
|
if (name == _var_w) { LoadNum(ChartPlayer.hitRect.width); type = PdtInternalType.Number; value = _numbuf; }
|
||||||
else if (name == _var_h) { LoadNum(ChartPlayer.hitRect.height); type = PdtInternalType.Number; value = _numbuf; }
|
else if (name == _var_h) { LoadNum(ChartPlayer.hitRect.height); type = PdtInternalType.Number; value = _numbuf; }
|
||||||
else if (name == _var_true) { LoadNum(1); type = PdtInternalType.Number; value = _numbuf; }
|
else if (name == _var_true) { LoadNum(1); type = PdtInternalType.Number; value = _numbuf; }
|
||||||
@@ -44,6 +45,10 @@ namespace Cryville.Crtr {
|
|||||||
if (result != null) {
|
if (result != null) {
|
||||||
result.Get(out type, out value);
|
result.Get(out type, out value);
|
||||||
}
|
}
|
||||||
|
else if (forced) {
|
||||||
|
type = PdtInternalType.Error;
|
||||||
|
value = _nullbuf;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
type = PdtInternalType.Undefined;
|
type = PdtInternalType.Undefined;
|
||||||
LoadIdent(name);
|
LoadIdent(name);
|
||||||
@@ -84,6 +89,7 @@ namespace Cryville.Crtr {
|
|||||||
static readonly int _colop_and = IdentifierManager.SharedInstance.Request("&");
|
static readonly int _colop_and = IdentifierManager.SharedInstance.Request("&");
|
||||||
static readonly int _colop_or = IdentifierManager.SharedInstance.Request("|");
|
static readonly int _colop_or = IdentifierManager.SharedInstance.Request("|");
|
||||||
protected override bool Collapse(int name, PdtVariableMemory param) {
|
protected override bool Collapse(int name, PdtVariableMemory param) {
|
||||||
|
if (param.Type == PdtInternalType.Error) throw new ArgumentException("Error");
|
||||||
if (name == _colop_and) return param.Type == PdtInternalType.Number && param.AsNumber() <= 0;
|
if (name == _colop_and) return param.Type == PdtInternalType.Number && param.AsNumber() <= 0;
|
||||||
else if (name == _colop_or) return param.Type != PdtInternalType.Number || param.AsNumber() > 0;
|
else if (name == _colop_or) return param.Type != PdtInternalType.Number || param.AsNumber() > 0;
|
||||||
else throw new KeyNotFoundException(string.Format("Undefined collapse operator {0}", IdentifierManager.SharedInstance.Retrieve(name)));
|
else throw new KeyNotFoundException(string.Format("Undefined collapse operator {0}", IdentifierManager.SharedInstance.Retrieve(name)));
|
||||||
|
|||||||
Reference in New Issue
Block a user