/// <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; }