예제 #1
0
        public void Test_Get_K_ClosestPlanetsFromEarth()
        {
            Planet[] result = null;
            using (var sr = new StreamReader("PlanetDistanceFromEarth.txt"))
            {
                result = HeapUtils.Get_K_ClosestPlanetsFromEarth(5, sr);
            }

            Console.WriteLine(string.Join <Planet>(Environment.NewLine, result));
        }
예제 #2
0
        public void TestSortAlmostSorted()
        {
            var A = new int[] { 3, -1, 2, 6, 4, 5, 8 };
            var B = HeapUtils.SortAlmostSortedArray(A, 2);

            Assert.IsTrue(B[0] == -1);
            Assert.IsTrue(string.Join(",", B) == "-1,2,3,4,5,6,8");

            A = new int[] { 6, 10, 9, 8, 11, 13, 12, 15 };
            B = HeapUtils.SortAlmostSortedArray(A, 2);
            Assert.IsTrue(B[0] == 6);
            Assert.IsTrue(string.Join(",", B) == "6,8,9,10,11,12,13,15");
        }
예제 #3
0
        public static StackValue Coerce(StackValue sv, Type targetType, Core core)
        {
            //@TODO(Jun): FIX ME - abort coersion for default args
            if (sv.IsDefaultArgument)
            {
                return(sv);
            }

            if (!(
                    (int)sv.metaData.type == targetType.UID ||
                    (core.ClassTable.ClassNodes[(int)sv.metaData.type].ConvertibleTo(targetType.UID)) ||
                    sv.IsArray))
            {
                core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kConversionNotPossible, ProtoCore.RuntimeData.WarningMessage.kConvertNonConvertibleTypes);
                return(StackValue.Null);
            }

            //if it's an array
            if (sv.IsArray && !targetType.IsIndexable)
            {
                //This is an array rank reduction
                //this may only be performed in recursion and is illegal here
                string errorMessage = String.Format(ProtoCore.RuntimeData.WarningMessage.kConvertArrayToNonArray, core.TypeSystem.GetType(targetType.UID));
                core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kConversionNotPossible, errorMessage);
                return(StackValue.Null);
            }


            if (sv.IsArray &&
                targetType.IsIndexable)
            {
                Validity.Assert(sv.IsArray);

                //We're being asked to convert an array into an array
                //walk over the structure converting each othe elements

                if (targetType.UID == (int)PrimitiveType.kTypeVar && targetType.rank == DSASM.Constants.kArbitraryRank && core.Heap.IsTemporaryPointer(sv))
                {
                    return(sv);
                }

                //Validity.Assert(targetType.rank != -1, "Arbitrary rank array conversion not yet implemented {2EAF557F-62DE-48F0-9BFA-F750BBCDF2CB}");

                //Decrease level of reductions by one
                Type newTargetType = new Type();
                newTargetType.UID = targetType.UID;
                if (targetType.rank != Constants.kArbitraryRank)
                {
                    newTargetType.rank = targetType.rank - 1;
                }
                else
                {
                    if (ArrayUtils.GetMaxRankForArray(sv, core) == 1)
                    {
                        //Last unpacking
                        newTargetType.rank = 0;
                    }
                    else
                    {
                        newTargetType.rank = Constants.kArbitraryRank;
                    }
                }

                return(ArrayUtils.CopyArray(sv, newTargetType, core));
            }

            if (!sv.IsArray && !sv.IsNull &&
                targetType.IsIndexable &&
                targetType.rank != DSASM.Constants.kArbitraryRank)
            {
                //We're being asked to promote the value into an array
                if (targetType.rank == 1)
                {
                    Type newTargetType = new Type();
                    newTargetType.UID  = targetType.UID;
                    newTargetType.Name = targetType.Name;
                    newTargetType.rank = 0;

                    //Upcast once
                    StackValue coercedValue = Coerce(sv, newTargetType, core);
                    GCUtils.GCRetain(coercedValue, core);
                    StackValue newSv = HeapUtils.StoreArray(new StackValue[] { coercedValue }, null, core);
                    return(newSv);
                }
                else
                {
                    Validity.Assert(targetType.rank > 1, "Target rank should be greater than one for this clause");

                    Type newTargetType = new Type();
                    newTargetType.UID  = targetType.UID;
                    newTargetType.Name = targetType.Name;
                    newTargetType.rank = targetType.rank - 1;

                    //Upcast once
                    StackValue coercedValue = Coerce(sv, newTargetType, core);
                    GCUtils.GCRetain(coercedValue, core);
                    StackValue newSv = HeapUtils.StoreArray(new StackValue[] { coercedValue }, null, core);
                    return(newSv);
                }
            }

            if (sv.IsPointer)
            {
                StackValue ret = ClassCoerece(sv, targetType, core);
                return(ret);
            }

            //If it's anything other than array, just create a new copy
            switch (targetType.UID)
            {
            case (int)PrimitiveType.kInvalidType:
                Validity.Assert(false, "Can't convert invalid type");
                break;

            case (int)PrimitiveType.kTypeBool:
                return(sv.ToBoolean(core));

            case (int)PrimitiveType.kTypeChar:
            {
                StackValue newSV = sv.ShallowClone();
                newSV.metaData = new MetaData {
                    type = (int)PrimitiveType.kTypeChar
                };
                return(newSV);
            }

            case (int)PrimitiveType.kTypeDouble:
                return(sv.ToDouble());

            case (int)PrimitiveType.kTypeFunctionPointer:
                if (sv.metaData.type != (int)PrimitiveType.kTypeFunctionPointer)
                {
                    core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kTypeMismatch, ProtoCore.RuntimeData.WarningMessage.kFailToConverToFunction);
                    return(StackValue.Null);
                }
                return(sv);

            case (int)PrimitiveType.kTypeHostEntityID:
            {
                StackValue newSV = sv.ShallowClone();
                newSV.metaData = new MetaData {
                    type = (int)PrimitiveType.kTypeHostEntityID
                };
                return(newSV);
            }

            case (int)PrimitiveType.kTypeInt:
            {
                if (sv.metaData.type == (int)PrimitiveType.kTypeDouble)
                {
                    core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kTypeConvertionCauseInfoLoss, ProtoCore.RuntimeData.WarningMessage.kConvertDoubleToInt);
                }
                return(sv.ToInteger());
            }

            case (int)PrimitiveType.kTypeNull:
            {
                if (sv.metaData.type != (int)PrimitiveType.kTypeNull)
                {
                    core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kTypeMismatch, ProtoCore.RuntimeData.WarningMessage.kFailToConverToNull);
                    return(StackValue.Null);
                }
                return(sv);
            }

            case (int)PrimitiveType.kTypePointer:
            {
                if (sv.metaData.type != (int)PrimitiveType.kTypeNull)
                {
                    core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kTypeMismatch, ProtoCore.RuntimeData.WarningMessage.kFailToConverToPointer);
                    return(StackValue.Null);
                }
                return(sv);
            }

            case (int)PrimitiveType.kTypeString:
            {
                StackValue newSV = sv.ShallowClone();
                newSV.metaData = new MetaData {
                    type = (int)PrimitiveType.kTypeString
                };
                if (sv.metaData.type == (int)PrimitiveType.kTypeChar)
                {
                    char ch = EncodingUtils.ConvertInt64ToCharacter(newSV.opdata);
                    newSV = StackValue.BuildString(ch.ToString(), core.Heap);
                }
                return(newSV);
            }

            case (int)PrimitiveType.kTypeVar:
            {
                return(sv);
            }

            case (int)PrimitiveType.kTypeArray:
            {
                return(ArrayUtils.CopyArray(sv, targetType, core));
            }

            default:
                if (sv.IsNull)
                {
                    return(StackValue.Null);
                }
                else
                {
                    throw new NotImplementedException("Requested coercion not implemented");
                }
            }

            throw new NotImplementedException("Requested coercion not implemented");
        }
예제 #4
0
        public StackValue Evaluate(List <StackValue> args, StackFrame stackFrame)
        {
            // Build the stackframe
            var runtimeCore = interpreter.runtime.Core;

            int        classScopeCaller = (int)stackFrame.GetAt(StackFrame.AbsoluteIndex.kClass).opdata;
            int        returnAddr       = (int)stackFrame.GetAt(StackFrame.AbsoluteIndex.kReturnAddress).opdata;
            int        blockDecl        = procNode.runtimeIndex;
            int        blockCaller      = (int)stackFrame.GetAt(StackFrame.AbsoluteIndex.kFunctionCallerBlock).opdata;
            int        framePointer     = runtimeCore.Rmem.FramePointer;
            StackValue thisPtr          = StackValue.BuildPointer(-1);

            // Functoion has variable input parameter. This case only happen
            // for FFI functions whose last parameter's type is (params T[]).
            // In this case, we need to convert argument list from
            //
            //    {a1, a2, ..., am, v1, v2, ..., vn}
            //
            // to
            //
            //    {a1, a2, ..., am, {v1, v2, ..., vn}}
            if (procNode.isVarArg)
            {
                int paramCount = procNode.argInfoList.Count;
                Validity.Assert(paramCount >= 1);

                int varParamCount = args.Count - (paramCount - 1);
                var varParams     = args.GetRange(paramCount - 1, varParamCount).ToArray();
                args.RemoveRange(paramCount - 1, varParamCount);

                var packedParams = HeapUtils.StoreArray(varParams, null, interpreter.runtime.Core);
                args.Add(packedParams);
            }

            bool isCallingMemberFunciton = procNode.classScope != Constants.kInvalidIndex &&
                                           !procNode.isConstructor &&
                                           !procNode.isStatic;

            bool isValidThisPointer = true;

            if (isCallingMemberFunciton)
            {
                Validity.Assert(args.Count >= 1);
                thisPtr = args[0];
                if (thisPtr.IsArray)
                {
                    isValidThisPointer = ArrayUtils.GetFirstNonArrayStackValue(thisPtr, ref thisPtr, runtimeCore);
                }
                else
                {
                    args.RemoveAt(0);
                }
            }

            if (!isValidThisPointer || (!thisPtr.IsPointer && !thisPtr.IsArray))
            {
                runtimeCore.RuntimeStatus.LogWarning(WarningID.kDereferencingNonPointer,
                                                     WarningMessage.kDeferencingNonPointer);
                return(StackValue.Null);
            }

            var callerType = (StackFrameType)stackFrame.GetAt(StackFrame.AbsoluteIndex.kStackFrameType).opdata;

            interpreter.runtime.TX = StackValue.BuildCallingConversion((int)ProtoCore.DSASM.CallingConvention.BounceType.kImplicit);

            StackValue svBlockDecl = StackValue.BuildBlockIndex(blockDecl);

            interpreter.runtime.SX = svBlockDecl;

            var repGuides = new List <List <ProtoCore.ReplicationGuide> >();

            List <StackValue> registers = new List <StackValue>();

            interpreter.runtime.SaveRegisters(registers);
            var newStackFrame = new StackFrame(thisPtr,
                                               classScopeCaller,
                                               1,
                                               returnAddr,
                                               blockDecl,
                                               blockCaller,
                                               callerType,
                                               StackFrameType.kTypeFunction,
                                               0,   // depth
                                               framePointer,
                                               registers,
                                               null);

            bool isInDebugMode = runtimeCore.Options.IDEDebugMode &&
                                 runtimeCore.ExecMode != InterpreterMode.kExpressionInterpreter;

            if (isInDebugMode)
            {
                runtimeCore.DebugProps.SetUpCallrForDebug(runtimeCore,
                                                          interpreter.runtime,
                                                          procNode,
                                                          returnAddr - 1,
                                                          false,
                                                          callsite,
                                                          args,
                                                          repGuides,
                                                          newStackFrame);
            }

            StackValue rx = callsite.JILDispatchViaNewInterpreter(
                new Runtime.Context(),
                args,
                repGuides,
                newStackFrame,
                runtimeCore);

            if (isInDebugMode)
            {
                runtimeCore.DebugProps.RestoreCallrForNoBreak(runtimeCore, procNode);
            }

            interpreter.runtime.DecRefCounter(rx);

            return(rx);
        }