private static void WriteDo(LanguageWriter w, IDoStatement state)
 {
     w.WriteKeyword("do");
     w.PushScope();
     w.Write(" {");
     w.WriteLine();
     w.WriteIndent();
     if (state.Body != null)
     {
         WriteBlock(w, state.Body);
     }
     w.WriteOutdent();
     w.Write("} ");
     w.PopScope();
     w.WriteKeyword("while");
     w.Write("(");
     if (state.Condition != null)
     {
         w.SkipWriteLine = true;
         ExpressionWriter.WriteExpression(w, state.Condition, false);
         w.SkipWriteLine = false;
     }
     w.Write(");");
     w.WriteLine();
 }
        private static void WriteLock(LanguageWriter w, ILockStatement statement)
        {
            w.Write("{");
            w.WriteIndent();
            w.WriteLine();

            Scope.VariableData data = new Scope.VariableData("<lock_statement>" + WriteLock_counter++.ToString(), true);
            data.disp_name     = "lock";
            w.scope[data.name] = data;

            // msclr::lock を初期化
            w.WriteReference("msclr", "", null);
            w.Write("::");
            w.WriteReference("lock", "#include <msclr/lock.h> で使用して下さい", null);
            w.Write(" ");
            w.WriteDeclaration(data.disp_name);
            w.Write("(");
            ExpressionWriter.WriteExpression(w, statement.Expression, false);
            w.Write(");");
            w.WriteLine();

            // 中身を書込
            if (statement.Body != null)
            {
                WriteBlock(w, statement.Body);
            }

            w.WriteOutdent();
            w.Write("}");
            w.WriteLine();
        }
        public void Write(LanguageWriter w)
        {
            w.PushScope();
            //---------------------------------------------
            if (!this.noblock)
            {
                w.Write("{");
                w.WriteLine();
                w.WriteIndent();
            }
            if (!w.SuppressOutput)
            {
                //*
#warning local-ref: 上層で無駄な宣言を取り除くべき
                if (w.scope.ContainsVariable(this.var_name))
                {
                    w.scope[this.var_name].local_scope = true;
                }
                else
                {
                    w.scope.RegisterVariable(this.var_name, true);
                }
                //*/
            }

            bool nohandle = this.exp is IObjectCreateExpression;           // ハンドル表記でなくても良いかどうか

            this.WriteVariableDecl(w, nohandle);

            // 後に続く内容
            w.WriteLine();
            StatementWriter.WriteBlock(w, this.block);

            // ハンドル表記で宣言した場合はちゃんと delete
            if (!nohandle)
            {
                StatementWriter.WriteStatement(w, new DeleteStatement(new VariableReferenceExpression(this.decl)));
            }

            if (!this.noblock)
            {
                w.WriteOutdent();
                w.Write("}");
                w.WriteLine();
            }
            if (this.labelname != null)
            {
                w.__WriteLabel(this.labelname);
                w.Write(";");
                w.WriteLine();
            }
            //---------------------------------------------
            w.PopScope();
        }
 private static void WriteSwitch(LanguageWriter w, ISwitchStatement state)
 {
     w.WriteKeyword("switch");
     w.Write(" (");
     ExpressionWriter.WriteExpression(w, state.Expression, false);
     w.Write(") {");
     w.WriteLine();
     w.WriteIndent();
     foreach (ISwitchCase _case in state.Cases)
     {
         IConditionCase case1 = _case as IConditionCase;
         if (case1 != null)
         {
             WriteSwitch_case(w, case1.Condition);
             w.WriteIndent();
             if (case1.Body != null)
             {
                 WriteStatement(w, case1.Body);
             }
             w.WriteOutdent();
         }
         IDefaultCase case2 = _case as IDefaultCase;
         if (case2 != null)
         {
             w.WriteKeyword("default");
             w.Write(":");
             w.WriteLine();
             w.WriteIndent();
             if (case2.Body != null)
             {
                 WriteStatement(w, case2.Body);
             }
             w.WriteOutdent();
             //this.Write("}");
             //this.WriteLine();
         }
     }
     w.WriteOutdent();
     w.Write("}");
     w.WriteLine();
 }
        private static void WriteBracedStatement(LanguageWriter w, IStatement statement)
        {
            w.PushScope();

            w.Write("{");
            w.WriteLine();
            w.WriteIndent();
            WriteStatement(w, statement);
            w.WriteOutdent();
            w.Write("}");

            w.PopScope();
        }
        private static void WriteFixed(LanguageWriter w, IFixedStatement state)
        {
            w.Write("{");
            w.WriteIndent();
            w.WriteLine();

            w.scope.RegisterVariable(state.Variable, false);
            w.WriteKeyword("pin_ptr");
            w.Write("<");
            new TypeRef(((IPointerType)state.Variable.VariableType).ElementType).WriteNameWithRef(w);
            w.Write("> ");
            w.WriteDeclaration(state.Variable.Name);
            w.Write(" = ");
            ExpressionWriter.WriteExpression(w, state.Expression, false);

            WriteBlock(w, state.Body);
            w.WriteOutdent();
            w.Write("}");
        }
 private static void WriteWhile(LanguageWriter w, IWhileStatement state)
 {
     w.WriteKeyword("while");
     w.Write(" ");
     w.Write("(");
     if (state.Condition != null)
     {
         w.SkipWriteLine = true;
         ExpressionWriter.WriteExpression(w, state.Condition, false);
         w.SkipWriteLine = false;
     }
     w.Write(") {");
     w.WriteLine();
     w.WriteIndent();
     if (state.Body != null)
     {
         WriteStatement(w, state.Body);
     }
     w.WriteOutdent();
     w.Write("}");
     w.WriteLine();
 }
 private static void WriteFor(LanguageWriter w, IForStatement state)
 {
     w.PushScope();
     w.WriteKeyword("for");
     w.Write(" ");
     w.Write("(");
     if (state.Initializer != null)
     {
         w.SkipWriteLine = true;
         WriteStatement(w, state.Initializer);
         w.SkipWriteLine = false;
         w.Write(" ");
     }
     w.Write("; ");
     if (state.Condition != null)
     {
         w.SkipWriteLine = true;
         ExpressionWriter.WriteExpression(w, state.Condition, false);
         w.SkipWriteLine = false;
     }
     w.Write("; ");
     if (state.Increment != null)
     {
         w.SkipWriteLine = true;
         WriteStatement(w, state.Increment);
         w.SkipWriteLine = false;
     }
     w.Write(") {");
     w.WriteLine();
     w.WriteIndent();
     if (state.Body != null)
     {
         WriteStatement(w, state.Body);
     }
     w.WriteOutdent();
     w.Write("}");
     w.WriteLine();
     w.PopScope();
 }
        // 匿名メソッドは、ラムダ式文法で代替する事にする。
        // 実際には、変数のキャプチャなどを行うと C++/CLI ではコンパイル出来ない。
        private static void WriteAnonymousMethod(LanguageWriter w, IAnonymousMethodExpression exp)
        {
            w.Write("[&]");
            w.WriteMethodParameterCollection(exp.Parameters);

            // 戻り型
            TypeRef return_type = new TypeRef(exp.ReturnType.Type);

            if (!return_type.IsVoid)
            {
                w.Write(" -> ");
                return_type.WriteNameWithRef(w);
            }

            // 中身
            w.PushScope();
            w.Write(" {");
            w.WriteLine();
            w.WriteIndent();
            w.WriteStatement(exp.Body);
            w.WriteOutdent();
            w.Write("}");
            w.PopScope();
        }
 private static void WriteForEach(LanguageWriter w, IForEachStatement state)
 {
     w.PushScope();
     w.WriteKeyword("for each");
     w.Write(" (");
     ExpressionWriter.WriteVariableDeclaration(w, state.Variable);
     w.Write(" ");
     w.WriteKeyword("in");
     w.Write(" ");
     w.SkipWriteLine = true;
     ExpressionWriter.WriteExpression(w, state.Expression, false);
     w.SkipWriteLine = false;
     w.Write(") {");
     w.WriteLine();
     w.WriteIndent();
     if (state.Body != null)
     {
         WriteBlock(w, state.Body);
     }
     w.WriteOutdent();
     w.Write("}");
     w.WriteLine();
     w.PopScope();
 }
        private static void WriteTryCatchFinally_catch(LanguageWriter w, ICatchClause clause)
        {
            w.Write(" ");
            w.WriteKeyword("catch");

            // 特別な場合 catch(...) を検出
            // → clauseBody を改変
            //    clauseBody は StatementAnalyze の時点で改変する様にした
            bool catchAll = clause.Condition is StatementAnalyze.IsCatchAll;
            IStatementCollection clause_body = clause.Body == null?null:clause.Body.Statements;

            TypeRef var_type = new TypeRef(clause.Variable.VariableType);

            /*
             * if(var_type.IsObject&&clause.Condition!=null) {
             *      ISnippetExpression iSnippent=clause.Condition as ISnippetExpression;
             *      if(iSnippent!=null&&iSnippent.Value=="?"&&StatementAnalyze.IsCatchAllClause(ref clause_body)){
             *              catchAll=true;
             *      }
             * }
             * //*/

            if (catchAll)
            {
                w.Write(" (...)");
            }
            else
            {
                if (clause.Variable.Name.Length != 0 || !var_type.IsObject)
                {
                    w.scope.RegisterVariable(clause.Variable, false);
                    w.Write(" (");
                    var_type.WriteNameWithRef(w);
                    w.Write(" ");
                    w.WriteDeclaration(clause.Variable.Name);
                    w.Write(")");
                }

                if (clause.Condition != null)
                {
                    w.Write(" ");
                    w.WriteKeyword("when");
                    w.Write(" ");
                    w.Write("(");
                    w.WriteExpression(clause.Condition);
                    w.Write(")");
                }
            }

            w.Write(" {");
            w.WriteLine();
            w.WriteIndent();

            if (clause_body != null)
            {
                for (int num = 0; num < clause_body.Count; num++)
                {
                    IStatement statement3 = clause_body[num];

#if EXTRA_TEMP
#warning catch: "コンストラクタの中で、最後の一行で、throw" の場合は書き込まない?
                    // →之は、恐らく、 constructor に function-try-statement を適用した時の話である
                    // よって無視する
                    if (w.SomeConstructor && num + 1 >= clause_body.Count && statement3 is IThrowExceptionStatement)
                    {
                        break;
                    }
#endif

                    WriteStatement(w, statement3);
                }
            }

            w.WriteOutdent();
            w.Write("}");
        }
        private static void WriteTryCatchFinally_try(LanguageWriter w, IBlockStatement _try)         //,int skipCount
        {
#if FUNC_TRY
            if (skipCount == 0)
            {
#endif
            w.WriteKeyword("try");
            w.Write(" {");
            w.WriteLine();
            w.WriteIndent();
#if FUNC_TRY
        }
#endif
            //
            //	try の中身
            //
            if (_try != null)
            {
#if EXTRA_TEMP
                IStatementCollection statementCollection = _try.Statements;
                int i = 0;
                foreach (IStatement state in _try.Statements)
                {
#warning try: 何故スキップが入るのか?
                    // →コンストラクタ内で  を全て delegation したから。
                    // ・delegation の検索は、最初に delegation が適用出来ない物が出た時に終了する
                    //   但し、その際に、ローカル変数 T var=xxx は無視している?
                    // ・最後の delegation が skipCount
                    if (i < skipCount)
                    {
                        i++;

                        IExpressionStatement state_exp = state as IExpressionStatement;
                        if (state_exp == null)
                        {
                            goto write;
                        }

                        IAssignExpression exp_assign = state_exp.Expression as IAssignExpression;
                        if (exp_assign != null)
                        {
                            // this 以外の物の field もスキップされてしまう...
                            if (exp_assign.Target is IFieldReferenceExpression)
                            {
                                continue;
                            }
                            goto write;
                        }

                        IMethodInvokeExpression exp_inv = state_exp.Expression as IMethodInvokeExpression;
                        if (exp_inv != null)
                        {
                            IMethodReferenceExpression method = exp_inv.Method as IMethodReferenceExpression;
                            if (method != null && method.Target is IBaseReferenceExpression)
                            {
                                continue;
                            }
                            goto write;
                        }
                    }
write:
                    WriteStatement(w, state);
                }
#else
                WriteBlock(w, _try);
#endif
            }
            w.WriteOutdent();
            w.Write("}");
        }
        private static void WriteTryCatchFinally(LanguageWriter w, ITryCatchFinallyStatement state)
        {
#if FUNC_TRY
            int skipTryCount = w.SkipTryCount;
            w.SkipTryCount = 0;
#endif

#if FALSE
            if (state.Try != null)
            {
                foreach (ICatchClause current in state.CatchClauses)
                {
                    if (current.Body.Statements.Count != 0)
                    {
                        goto write_try;
                    }
                }

                if (state.Finally.Statements.Count != 0)
                {
                    goto write_try;
                }
                if (state.Fault.Statements.Count != 0)
                {
                    goto write_try;
                }

                // 中身が何もない場合
                this.WriteBlockStatement(state.Try);
                if (skipTryCount != 0)
                {
                    this.WriteOutdent();
                    this.Write("}");
                    this.WriteLine();
                }
                return;
            }
write_try:
#endif

            WriteTryCatchFinally_try(w, state.Try);            //,skipTryCount

            //
            // catch 節
            //
            foreach (ICatchClause clause in state.CatchClauses)
            {
                WriteTryCatchFinally_catch(w, clause);
            }

            //
            // fault 節
            //
            if (state.Fault != null && state.Fault.Statements.Count > 0)
            {
                w.Write(" ");
                w.WriteKeyword("fault");
                w.Write(" {");
                w.WriteLine();
                w.WriteIndent();
                WriteBlock(w, state.Fault);
                w.WriteOutdent();
                w.Write("}");
            }

            //
            // finally 節
            //
            if (state.Finally != null && state.Finally.Statements.Count > 0)
            {
                w.Write(" ");
                w.WriteKeyword("finally");
                w.Write(" {");
                w.WriteLine();
                w.WriteIndent();
                WriteBlock(w, state.Finally);
                w.WriteOutdent();
                w.Write("}");
            }

            w.WriteLine();
        }
        private static void WriteLocalRefVariable(LanguageWriter w, LocalRefVariableStatement state)
        {
            state.Write(w);
            return;

            if (!state.noblock)
            {
                w.PushScope();
                //---------------------------------------------
                w.Write("{");
                w.WriteLine();
                w.WriteIndent();
            }
            if (!w.SuppressOutput)
            {
                //*
#warning local-ref: 上層で無駄な宣言を取り除くべき
                if (w.scope.ContainsVariable(state.var_name))
                {
                    w.scope[state.var_name].local_scope = true;
                }
                else
                {
                    w.scope.RegisterVariable(state.var_name, true);
                }
                //*/
            }

            IObjectCreateExpression exp_create = state.exp as IObjectCreateExpression;
            bool nohandle = exp_create != null;         // ハンドル表記でなくても良いかどうか
            if (nohandle)
            {
                // 変数型
                IOptionalModifier modopt = state.var_type as IOptionalModifier;
                if (modopt != null && modopt.Modifier.Namespace == "System.Runtime.CompilerServices" && modopt.Modifier.Name == "IsConst")
                {
                    state.var_type = modopt.ElementType;
                }
                new TypeRef(state.var_type).WriteName(w);

                // 変数名
                w.Write(" ");
                w.WriteDeclaration(state.var_name);

                // 初期化子
                if (exp_create.Arguments.Count == 0)
                {
                    w.WriteComment(" /* 既定のコンストラクタ */");
                }
                else
                {
                    w.Write("(");
                    w.WriteExpressionCollection(exp_create.Arguments);
                    w.Write(")");
                }
            }
            else
            {
                // = で代入の場合: ハンドル表記でないと、コンストラクタ呼び出しになってしまう

                // 変数型
                new TypeRef(state.var_type).WriteNameWithRef(w);

                // 変数名
                w.Write(" ");
                w.WriteDeclaration(state.var_name);

                // 代入する値
                w.Write("=");
                ExpressionWriter.WriteExpression(w, state.exp, false);
            }

            w.Write(";");

            // 後に続く内容
            w.WriteLine();
            WriteBlock(w, state.block);

            // ハンドル表記で宣言した場合はちゃんと delete
            if (!nohandle)
            {
                WriteStatement(w, new DeleteStatement(new VariableReferenceExpression(state.decl)));
            }

            w.WriteOutdent();
            w.Write("}");
            w.WriteLine();
            if (state.labelname != null)
            {
                w.__WriteLabel(state.labelname);
                w.Write(";");
                w.WriteLine();
            }
            if (!state.noblock)
            {
                //---------------------------------------------
                w.PopScope();
            }
            //*/
        }