コード例 #1
0
        private void DoIndexedGet(Stack <double> valueStack, ushort paramCount)
        {
            var target = valueStack.Pop();
            var value  = _memory.Variables.Resolve(NanTags.DecodeVariableRef(target));
            var type   = NanTags.TypeOf(value);

            switch (type)
            {
            // Note: Numeric types should read the bit at index
            // Hashes and arrays do the obvious lookup
            // Sets return true/false for occupancy
            case DataType.PtrString:
            case DataType.PtrStaticString:
                // get the other indexes. If more than one, build a string out of the bits?
                // What to do with out-of-range?
                var str = _memory.DereferenceString(NanTags.DecodePointer(value));
                var sb  = new StringBuilder(paramCount - 1);
                for (int i = 0; i < paramCount; i++)
                {
                    var idx = _memory.CastInt(valueStack.Pop());
                    if (idx >= 0 && idx < str.Length)
                    {
                        sb.Append(str[idx]);
                    }
                }

                var result = _memory.StoreStringAndGetReference(sb.ToString());
                valueStack.Push(result);
                return;

            default:
                throw new Exception("Indexing of type '" + type + "' is not yet supported");
            }
        }
コード例 #2
0
        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);
            }
        }
コード例 #3
0
        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);
            }
        }
コード例 #4
0
        private int HandleFunctionDefinition(ushort argCount, ushort tokenCount, int position, Stack <double> valueStack)
        {
            var functionNameHash = NanTags.DecodeVariableRef(valueStack.Pop());

            if (Functions.ContainsKey(functionNameHash))
            {
                throw new Exception("Function '" + functionNameHash + "' redefined at " + position + ". Original at " + Functions[functionNameHash]);
            }

            Functions.Add(functionNameHash, new FunctionDefinition {
                StartPosition = position,
                ParamCount    = argCount
            });

            return(position + tokenCount + 1); // + definition length + terminator
        }
コード例 #5
0
        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();
            }
        }
コード例 #6
0
        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();
            }
        }
コード例 #7
0
        private int PrepareFunctionCall(int position, ushort nbParams, Stack <double> valueStack, Stack <int> returnStack)
        {
            var functionNameHash = NanTags.DecodeVariableRef(valueStack.Pop());

            var param = ReadParams(position, nbParams, valueStack);

            // Evaluate function.
            var evalResult = EvaluateFunctionCall(ref position, functionNameHash, nbParams, param, returnStack, valueStack);

            // Add result on stack as a value.
            if (NanTags.TypeOf(evalResult) != DataType.NoValue)
            {
                valueStack.Push(evalResult);
            }
            else if (NanTags.DecodeNonValue(evalResult) == NonValueType.Unit)
            {
                valueStack.Push(evalResult);
            }

            return(position);
        }
コード例 #8
0
ファイル: NanBoxingTests.cs プロジェクト: i-e-b/NanBoxing
        public void identifier_names_can_be_encoded_and_survive_a_round_trip()
        {
            var enc  = NanTags.EncodeVariableRef("HelloWorld", out var crush);
            var type = NanTags.TypeOf(enc);

            var enc2  = NanTags.EncodeVariableRef("Hel" + "lo" + "Wo" + 'r' + 'l' + 'd', out var crush2);
            var other = NanTags.EncodeVariableRef("HelloWorld2", out var crushOther);

            Console.WriteLine("Crush:   " + crush.ToString("X"));
            Console.WriteLine("Crush:   " + crushOther.ToString("X"));

            var checkCrush = NanTags.DecodeVariableRef(enc);

            Assert.That(checkCrush, Is.EqualTo(crush));

            Assert.That(type, Is.EqualTo(DataType.VariableRef));
            Assert.That(NanTags.AreEqual(enc, enc2), Is.True);
            Assert.That(NanTags.AreEqual(enc, other), Is.False);
            Assert.That(crush, Is.EqualTo(crush2));
            Assert.That(crush, Is.Not.EqualTo(crushOther));
        }
コード例 #9
0
        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);
            }
        }