/// <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!!!"); } }