public double CastDouble(double encoded) { var type = NanTags.TypeOf(encoded); double result; switch (type) { case DataType.Number: return(encoded); case DataType.ValInt32: return(NanTags.DecodeInt32(encoded)); case DataType.ValUInt32: return(NanTags.DecodeUInt32(encoded)); case DataType.VariableRef: // Follow scope var next = Variables.Resolve(NanTags.DecodeVariableRef(encoded)); return(CastDouble(next)); case DataType.ValSmallString: double.TryParse(NanTags.DecodeShortStr(encoded), out result); return(result); case DataType.PtrStaticString: case DataType.PtrString: NanTags.DecodePointer(encoded, out var target, out _); double.TryParse(DereferenceString(target), out result); return(result); // All the things that can't be meaningfully cast default: return(0.0d); } }
private string Stringify(double token, DataType type, HashLookup <string> debugSymbols) { switch (type) { case DataType.Invalid: return(""); case DataType.NoValue: return(""); case DataType.VariableRef: var rref = NanTags.DecodeVariableRef(token); if (debugSymbols?.ContainsKey(rref) == true) { return("'" + debugSymbols[rref] + "' (" + rref.ToString("X") + ")"); } return(rref.ToString("X")); case DataType.Opcode: NanTags.DecodeLongOpCode(token, out var ccls, out var cact, out var refr); if (ccls == 'm') { if (debugSymbols?.ContainsKey(refr) == true) { return(ccls + "" + cact + " '" + debugSymbols[refr] + "' (" + refr.ToString("X") + ")"); } } if (ccls == 'i') { if (debugSymbols?.ContainsKey(refr) == true) { return("Incr " + ((sbyte)cact) + " '" + debugSymbols[refr] + "' (" + refr.ToString("X") + ")"); } } NanTags.DecodeOpCode(token, out _, out _, out var p1, out var p2); return(ccls + "" + cact + " (" + p1 + ", " + p2 + ")"); case DataType.ValSmallString: return("[" + NanTags.DecodeShortStr(token) + "]"); case DataType.PtrHashtable: case DataType.PtrGrid: case DataType.PtrSet: case DataType.PtrVector: case DataType.PtrString: case DataType.PtrStaticString: NanTags.DecodePointer(token, out var targ, out _); return(" -> " + targ); case DataType.ValInt32: return(NanTags.DecodeInt32(token).ToString()); case DataType.ValUInt32: return(NanTags.DecodeUInt32(token).ToString()); case DataType.Number: return(token.ToString(CultureInfo.InvariantCulture)); default: throw new ArgumentOutOfRangeException(nameof(type), type, null); } }
public void int32_overflows_the_same_way_as_native() { unchecked { for (int i = 1; i > 0; i += i) { int original = i * 2; double enc = NanTags.EncodeInt32(original); int result = NanTags.DecodeInt32(enc); Assert.That(result, Is.EqualTo(original)); } } }
public int CastInt(double encoded) { int result; var type = NanTags.TypeOf(encoded); switch (type) { case DataType.Invalid: case DataType.Opcode: case DataType.NoValue: return(0); case DataType.VariableRef: // Follow scope var next = Variables.Resolve(NanTags.DecodeVariableRef(encoded)); return(CastInt(next)); case DataType.ValSmallString: int.TryParse(NanTags.DecodeShortStr(encoded), out result); return(result); case DataType.PtrStaticString: case DataType.PtrString: NanTags.DecodePointer(encoded, out var target, out _); int.TryParse(DereferenceString(target), out result); return(result); case DataType.PtrHashtable: case DataType.PtrGrid: case DataType.PtrSet: case DataType.PtrVector: return(0); case DataType.Number: return((int)encoded); case DataType.ValInt32: return(NanTags.DecodeInt32(encoded)); case DataType.ValUInt32: return((int)NanTags.DecodeUInt32(encoded)); default: throw new ArgumentOutOfRangeException(); } }
public string CastString(double encoded) { var type = NanTags.TypeOf(encoded); switch (type) { case DataType.Invalid: return("<invalid value>"); case DataType.Number: return(encoded.ToString(CultureInfo.InvariantCulture)); case DataType.Opcode: return("<Op Code>"); case DataType.NoValue: return(""); case DataType.VariableRef: // Follow scope var next = Variables.Resolve(NanTags.DecodeVariableRef(encoded)); return(CastString(next)); case DataType.ValSmallString: return(NanTags.DecodeShortStr(encoded)); case DataType.PtrStaticString: case DataType.PtrString: NanTags.DecodePointer(encoded, out var target, out _); return(DereferenceString(target)); case DataType.PtrHashtable: case DataType.PtrGrid: case DataType.PtrSet: case DataType.PtrVector: return("<complex type>"); case DataType.ValInt32: return(NanTags.DecodeInt32(encoded).ToString()); case DataType.ValUInt32: return(NanTags.DecodeUInt32(encoded).ToString()); default: throw new ArgumentOutOfRangeException(); } }
public bool CastBoolean(double encoded) { var type = NanTags.TypeOf(encoded); switch (type) { case DataType.Number: return(Math.Abs(encoded) > double.Epsilon); case DataType.ValInt32: return(NanTags.DecodeInt32(encoded) != 0); case DataType.ValUInt32: return(NanTags.DecodeUInt32(encoded) != 0); case DataType.ValSmallString: { var strVal = NanTags.DecodeShortStr(encoded); return(StringTruthyness(strVal)); } case DataType.PtrString: case DataType.PtrStaticString: { NanTags.DecodePointer(encoded, out var ptr, out _); var strVal = DereferenceString(ptr); return(StringTruthyness(strVal)); } case DataType.VariableRef: // Follow scope var next = Variables.Resolve(NanTags.DecodeVariableRef(encoded)); return(CastBoolean(next)); // All the things that can't be meaningfully cast are 'false' default: return(false); } }