Add "at" operator.
This commit is contained in:
@@ -90,6 +90,7 @@ namespace Cryville.Common.Pdt {
|
|||||||
}
|
}
|
||||||
public partial class PdtInterpreter<T> {
|
public partial class PdtInterpreter<T> {
|
||||||
readonly static Dictionary<char, int> OP_PRIORITY = new Dictionary<char, int> {
|
readonly static Dictionary<char, int> OP_PRIORITY = new Dictionary<char, int> {
|
||||||
|
{ '@', 7 },
|
||||||
{ '*', 6 }, { '/', 6 }, { '%', 6 },
|
{ '*', 6 }, { '/', 6 }, { '%', 6 },
|
||||||
{ '+', 5 }, { '-', 5 },
|
{ '+', 5 }, { '-', 5 },
|
||||||
{ '=', 4 }, { '<', 4 }, { '>', 4 },
|
{ '=', 4 }, { '<', 4 }, { '>', 4 },
|
||||||
@@ -100,6 +101,7 @@ namespace Cryville.Common.Pdt {
|
|||||||
{ '$', -1 },
|
{ '$', -1 },
|
||||||
};
|
};
|
||||||
readonly static Dictionary<char, int> OP_TYPE = new Dictionary<char, int> {
|
readonly static Dictionary<char, int> OP_TYPE = new Dictionary<char, int> {
|
||||||
|
{ '@', 0 },
|
||||||
{ '*', 0 }, { '/', 0 }, { '%', 0 },
|
{ '*', 0 }, { '/', 0 }, { '%', 0 },
|
||||||
{ '+', 0 }, { '-', 0 },
|
{ '+', 0 }, { '-', 0 },
|
||||||
{ '=', 0 }, { '<', 0 }, { '>', 0 },
|
{ '=', 0 }, { '<', 0 }, { '>', 0 },
|
||||||
|
@@ -42,28 +42,33 @@ namespace Cryville.Common.Pdt {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the memory of the span as a number.
|
/// Gets the memory of the span as a number.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="offset">The offset on the span to start reading from.</param>
|
||||||
/// <returns>A number.</returns>
|
/// <returns>A number.</returns>
|
||||||
/// <exception cref="InvalidCastException">The span does not represent a number.</exception>
|
/// <exception cref="InvalidCastException">The span at the offset does not represent a number.</exception>
|
||||||
public float AsNumber() {
|
public float AsNumber(int offset = 0) {
|
||||||
if (Type != PdtInternalType.Number)
|
if (Type != PdtInternalType.Number)
|
||||||
throw new InvalidCastException("Not a number");
|
throw new InvalidCastException("Not a number");
|
||||||
float value;
|
float value;
|
||||||
byte* ptr = (byte*)&value;
|
byte* ptr = (byte*)&value;
|
||||||
for (int i = 0; i < sizeof(float); i++)
|
for (int i = 0; i < sizeof(float); i++)
|
||||||
ptr[i] = _ptr[i];
|
ptr[i] = _ptr[i + offset];
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets the memory of the span to a number.
|
/// Sets the memory of the span to a number.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value">The number.</param>
|
/// <param name="value">The number.</param>
|
||||||
/// <exception cref="InvalidCastException">The span does not represent a number.</exception>
|
/// <param name="offset">The offset from the start of the span.</param>
|
||||||
public void SetNumber(float value) {
|
/// <exception cref="InvalidCastException">The span at the offset does not represent a number.</exception>
|
||||||
|
/// <exception cref="InvalidOperationException">The length of the span is not sufficient.</exception>
|
||||||
|
public void SetNumber(float value, int offset = 0) {
|
||||||
if (Type != PdtInternalType.Number)
|
if (Type != PdtInternalType.Number)
|
||||||
throw new InvalidCastException("Not a number");
|
throw new InvalidCastException("Not a number");
|
||||||
|
if (Length < sizeof(float) + offset)
|
||||||
|
throw new InvalidOperationException("Frame length not sufficient");
|
||||||
byte* ptr = (byte*)&value;
|
byte* ptr = (byte*)&value;
|
||||||
for (int i = 0; i < sizeof(float); i++)
|
for (int i = 0; i < sizeof(float); i++)
|
||||||
_ptr[i] = ptr[i];
|
_ptr[i + offset] = ptr[i];
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the memory of the span as a string.
|
/// Gets the memory of the span as a string.
|
||||||
|
@@ -11,10 +11,10 @@ namespace Cryville.Crtr {
|
|||||||
readonly Dictionary<int, PdtOperator> _ctxops = new Dictionary<int, PdtOperator>();
|
readonly Dictionary<int, PdtOperator> _ctxops = new Dictionary<int, PdtOperator>();
|
||||||
|
|
||||||
readonly byte[] _numbuf = new byte[4];
|
readonly byte[] _numbuf = new byte[4];
|
||||||
static int _var_w = IdentifierManager.SharedInstance.Request("w");
|
static readonly int _var_w = IdentifierManager.SharedInstance.Request("w");
|
||||||
static int _var_h = IdentifierManager.SharedInstance.Request("h");
|
static readonly int _var_h = IdentifierManager.SharedInstance.Request("h");
|
||||||
static int _var_true = IdentifierManager.SharedInstance.Request("true");
|
static readonly int _var_true = IdentifierManager.SharedInstance.Request("true");
|
||||||
static 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) {
|
||||||
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; }
|
||||||
@@ -64,7 +64,7 @@ namespace Cryville.Crtr {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
static int _op_sep = IdentifierManager.SharedInstance.Request(",");
|
static readonly int _op_sep = IdentifierManager.SharedInstance.Request(",");
|
||||||
protected override PdtOperator GetOperator(PdtOperatorSignature sig) {
|
protected override PdtOperator GetOperator(PdtOperatorSignature sig) {
|
||||||
PdtOperator result;
|
PdtOperator result;
|
||||||
if (_shortops.TryGetValue(sig, out result)) {
|
if (_shortops.TryGetValue(sig, out result)) {
|
||||||
@@ -84,8 +84,8 @@ namespace Cryville.Crtr {
|
|||||||
else throw new KeyNotFoundException(string.Format("Undefined operator {0}", sig));
|
else throw new KeyNotFoundException(string.Format("Undefined operator {0}", sig));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _colop_and = IdentifierManager.SharedInstance.Request("&");
|
static readonly int _colop_and = IdentifierManager.SharedInstance.Request("&");
|
||||||
static 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 (name == _colop_and) return param.AsNumber() == 0;
|
if (name == _colop_and) return param.AsNumber() == 0;
|
||||||
else if(name == _colop_or) return param.AsNumber() != 0;
|
else if(name == _colop_or) return param.AsNumber() != 0;
|
||||||
@@ -116,6 +116,8 @@ namespace Cryville.Crtr {
|
|||||||
_ctxops.Add(IdentifierManager.SharedInstance.Request("max"), new func_max(() => ContextSelfValue));
|
_ctxops.Add(IdentifierManager.SharedInstance.Request("max"), new func_max(() => ContextSelfValue));
|
||||||
}
|
}
|
||||||
static PdtEvaluator() {
|
static PdtEvaluator() {
|
||||||
|
_shortops.Add(new PdtOperatorSignature("@", 2), new op_at_2());
|
||||||
|
|
||||||
_shortops.Add(new PdtOperatorSignature("*", 2), new op_mul_2());
|
_shortops.Add(new PdtOperatorSignature("*", 2), new op_mul_2());
|
||||||
_shortops.Add(new PdtOperatorSignature("/", 2), new op_div_2());
|
_shortops.Add(new PdtOperatorSignature("/", 2), new op_div_2());
|
||||||
_shortops.Add(new PdtOperatorSignature("%", 2), new op_mod_2());
|
_shortops.Add(new PdtOperatorSignature("%", 2), new op_mod_2());
|
||||||
@@ -232,6 +234,19 @@ namespace Cryville.Crtr {
|
|||||||
return type == PdtInternalType.Number;
|
return type == PdtInternalType.Number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
class op_at_2 : PdtOperator {
|
||||||
|
public op_at_2() : base(2) { }
|
||||||
|
protected override void Execute() {
|
||||||
|
int _, pc;
|
||||||
|
var op0 = GetOperand(0);
|
||||||
|
var op1 = (int)Math.Round(GetOperand(1).AsNumber());
|
||||||
|
if (op0.Type != PdtInternalType.Vector) throw new InvalidOperationException("Not a vector");
|
||||||
|
op0.GetArraySuffix(out _, out pc);
|
||||||
|
if (op1 >= pc) throw new IndexOutOfRangeException();
|
||||||
|
float result = GetOperand(0).AsNumber(op1 * sizeof(float));
|
||||||
|
GetReturnFrame(PdtInternalType.Number, sizeof(float)).SetNumber(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
class func_frame_seq : PdtOperator {
|
class func_frame_seq : PdtOperator {
|
||||||
public func_frame_seq() : base(3) { }
|
public func_frame_seq() : base(3) { }
|
||||||
protected override unsafe void Execute() {
|
protected override unsafe void Execute() {
|
||||||
|
Reference in New Issue
Block a user