public void PopInnerLocal([NotNull] ZilAtom atom) { SpareLocals.Push(Locals[atom].LocalBuilder); if (OuterLocals.TryGetValue(atom, out var stk)) { Locals[atom] = stk.Pop(); if (stk.Count == 0) { OuterLocals.Remove(atom); } } else { Locals.Remove(atom); } }
public ILocalBuilder PushInnerLocal([NotNull] IRoutineBuilder rb, [NotNull] ZilAtom atom, LocalBindingType reason, ISourceLine src) { if (Locals.TryGetValue(atom, out var prev)) { // save the old binding if (OuterLocals.TryGetValue(atom, out var stk) == false) { stk = new Stack <LocalBindingRecord>(); OuterLocals.Add(atom, stk); } stk.Push(prev); } ILocalBuilder result; if (SpareLocals.Count > 0) { // reuse a spare variable result = SpareLocals.Pop(); } else { // allocate a new variable with a unique name var tempName = MakeUniqueVariableName(atom); try { result = rb.DefineLocal(tempName.Text); } catch (InvalidOperationException) { throw new CompilerError(CompilerMessages.Expression_Needs_Temporary_Variables_Not_Allowed_Here); } TempLocalNames.Add(tempName); } var lbr = new LocalBindingRecord(reason, src, atom.Text, result); Locals[atom] = lbr; AllLocalBindingRecords.Add(lbr); return(result); }