//#region License
///* **********************************************************************************
// * Copyright (c) Roman Ivantsov
// * This source code is subject to terms and conditions of the MIT License
// * for Irony. A copy of the license can be found in the License.txt file
// * at the root of this distribution. 
// * By using this source code in any fashion, you are agreeing to be bound by the terms of the 
// * MIT License.
// * You must not remove this notice from this software.
// * **********************************************************************************/
//#endregion

//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;

//using Irony.Ast;
//using Irony.Parsing;

//namespace Irony.Interpreter.Ast
//{

//    public class ForNode : AstNode
//    {
//        object result = null;
//        private AstNode InitializeAst;
//        private AstNode ConditionAst;
//        private AstNode UpdateLoopAst;
//        private AstNode LoopBody;


//        public override void Init(AstContext context , ParseTreeNode treeNode)
//        {
//            base.Init(context , treeNode);
//            //treenodeのchildnodeが２つあるとき、返値用のASTノードを追加
//            if (treeNode.ChildNodes != null && treeNode.ChildNodes.Count >= 4)
//            {
//                //仮変数＝初期値ノードをASTに追加
//                InitializeAst = AddChild(NodeUseType.ValueReadWrite , "ItelatorInit" , treeNode.ChildNodes[1]);

//                //終了値ノードをASTに追加
//                ConditionAst = AddChild(NodeUseType.ValueReadWrite , "LoopEndValue" , treeNode.ChildNodes[3]);

//                //ループボディをASTに追加　　　　.CallTarget？？
//                LoopBody = AddChild(NodeUseType.Unknown , "LoopBody" , treeNode.ChildNodes[4]);

                
//            }
//            else
//            {
//                //刻み値の指定は別で対処。
                
//                //AddChild(NodeUseType.ValueRead , "NullreturnValue" , null);
                
//            }
//            AsString = "for";
//        }

//        object LockObject = new object();
//        protected override object DoEvaluate(ScriptThread thread)
//        {

//            //return、break、Continueを受け取る
//            resultWithReturnType resWithRet = null;

//            thread.CurrentNode = this;  //standard prolog

//            //ループカウンタ初期化
//            InitializeAst.Evaluate(thread);

//            //変数名を取得し、インクリメントの式を作成する
//            var loopCounterName = ((IdentifierNode)InitializeAst.ChildNodes[0]).Symbol;
//            var CounterUpdateParseTree = thread.App.Parser.Parse(loopCounterName + "++");

//            //条件値を取得し、評価式を作成
//            var endValue = ConditionAst.Evaluate(thread);
//            var Test = thread.App.Parser.Parse(loopCounterName + "<=" + endValue);


//            //ループ処理
//            while ( TestCondition(thread , Test) )
//            {
//                //ブロック実行
//                result = LoopBody.Evaluate(thread);

//                //Break,Continueで途中で抜けた場合、resultWithReturnTypeが戻ってくる。
//                resWithRet = result as resultWithReturnType;
//                if (resWithRet != null)
//                {
//                    if (resWithRet.retType == ReturnType.EXIT_LOOP )
//                    {
//                        //１階層上に戻る
//                        result = resWithRet.resultObj;
//                        break;
//                    }

//                    if ( resWithRet.retType == ReturnType.EXIT_FUNCTION)
//                    {
//                        //１階層上に戻るが、関数を抜けるまでフラグを立てたままにする。
//                        break;
//                    }

//                    if (resWithRet.retType == ReturnType.CONTINUE_LOOP)
//                    {
//                        Update(thread  , CounterUpdateParseTree);
//                        continue;
//                    }
//                }
//                Update(thread , CounterUpdateParseTree);
//            } 

//            thread.CurrentNode = Parent; //standard epilog
//            return result;
//        }//method


//        private void Update(ScriptThread thread  , ParseTree CounterUpdateParseTree)
//        {
//            ////インクリメントの結果、評価結果が表示されないようにするため、
//            ////保存しておく
//            //var outputSaveInt = thread.App.OutputBuffer.Length;

//            //インクリメント実施
//            thread.App.Evaluate(CounterUpdateParseTree , thread.CurrentScope);

//            ////出力内容を戻す
//            //thread.App.OutputBuffer.Remove(outputSaveInt , thread.App.OutputBuffer.Length - outputSaveInt);
//        }

//        private bool TestCondition(ScriptThread thread , ParseTree Test)
//        {
//            ////インクリメントの結果、評価結果が表示されないようにするため、
//            ////保存しておく
//            //var outputSaveInt = thread.App.OutputBuffer.Length;
            
//            //条件式評価
//            var result = (bool)thread.App.Evaluate(Test , thread.CurrentScope);

//            ////出力内容を戻す
//           //thread.App.OutputBuffer.Remove(outputSaveInt , thread.App.OutputBuffer.Length - outputSaveInt);.

//            return result;
//        }

//    }//class

//}//namespace
