예제 #1
0
        /// <summary>
        /// Constructs a Code Node that has asm commands representing a free register allocation (if all are allocated already).
        /// Some variables could be deallocated randomly when calling this function.
        /// </summary>
        /// <param name="ctx">Current context.</param>
        /// <param name="parent">Parent Code Node</param>
        /// <returns>Constructed Code Node with asm commands representing a free register allocation.</returns>
        protected CodeNode GetFreeRegisterNode(Context?ctx, CodeNode?parent)
        {
            Generator g      = Program.currentCompiler.generator;
            CodeNode  frNode = new CodeNode("Get free register", parent);

            for (byte ri = 0; ri < g.regOccup.Length; ri++)
            {
                if (!g.regOccup[ri])
                {
                    g.OccupateReg(ri);
                    return(frNode.SetByteToReturn(ri));
                }
            }

            // If all are occupated, load out one of them (the first suitable one).
            // ATTENTION: Is it ok, or am I stupid?
            byte regToFree = 0;

            while (regToFree < 27) // God bless this while to not loop forever! NOTE: It won't
            {
                if (g.regAllocRTV.ContainsKey(regToFree))
                {
                    break;
                }
                regToFree++;
            }

            if (g.regAllocRTV.ContainsKey(regToFree))
            {
                string varName = g.regAllocRTV[regToFree];
                g.regAllocRTV.Remove(regToFree);
                g.regAllocVTR.Remove(varName);
                frNode.Children.AddLast(GetStoreVariableNode(frNode, varName, regToFree, ctx));
                return(frNode.SetByteToReturn(regToFree));
            }
            else
            {
                throw new CompilationErrorException("Out of registers!!!");
            }
        }