/// <summary>
 /// Pushes a new evaluation frame against the specified node.
 /// </summary>
 /// <param name="node">Node.</param>
 /// <param name="childCounter">Child counter.</param>
 public void Push(AstNode node, int childCounter = 0)
 {
     var frame = new EvaluationFrame(node, (cur_scope == null) ? 0 :
                                           ShouldIntroduceScope(node) ? stack.Count : cur_scope.ScopeFramePointer,
                                     childCounter, this);
     frames.Add(frame);
     if(node is CallExpression)
         cur_scope = frame;
 }
 /// <summary>
 /// Pushes a new evaluation frame without introducing a new scope.
 /// </summary>
 /// <param name="node">Node.</param>
 /// <param name="childCounter">Child counter.</param>
 public void PushWithoutScope(AstNode node, int childCounter = 0)
 {
     var frame = new EvaluationFrame(node, (cur_scope != null) ? cur_scope.ScopeFramePointer : 0, childCounter, this);
     frames.Add(frame);
 }
        /// <summary>
        /// Pops the top evalution frame.
        /// </summary>
        /// <returns>The removed evaluation frame.</returns>
        public EvaluationFrame Pop()
        {
            if(frames.Count == 0)
                throw new InvalidOperationException();

            var tmp = frames[frames.Count - 1];
            frames.RemoveAt(frames.Count - 1);
            if(tmp.TargetNode is ScopeStatement)	//一つ上のスコープに対応する評価フレームをセットする
                cur_scope = ((IEnumerable<EvaluationFrame>)frames).Reverse().FirstOrDefault(x => x.TargetNode is CallExpression);

            return tmp;
        }