예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
        }