†ASTができたので続いてバイトコード生成です。トップレベルのPyAST_CompileObjectを眺めるとPySymtable_BuildObjectを呼び出した後にcompiler_modを呼び出しています。いうかファイルの先頭にステップが書いてあるので見ていましょう。†PySymtable_BuildObjectを見ていくとまずtopを引数にsymtable_enter_blockを読んでいます。topは名前通りトップレベルなのでしょう。下を見るとsymtable_exit_blockがあるのでブロックに入る前にenterしてブロックが終わったらexitしているようです(そのまんまですが)symtable_enter_blockを見てみます。1;}STEntryという名前にだまされ気味ですが、このオブジェクトはシンボルテーブルの1エントリではなく、あるブロックに存在する全変数を保持しています。ste;}PyObjectとか出てきてますが深くは気にしません。シンボルテーブルにブロックが登録されているということだけ覚えておきます。†さて、というわけでsymtableの仕組みがわかったので次に実際にシンボルテーブルにシンボルが登録されていく様子を見てきましょう。PySymtable_BuildObjectではsymtable_visit_stmtが呼び出されています。symtable_visit_stmtの中身はswitch文、今回は見ませんが関数定義やクラス定義でsymtable_enter_blockを呼んでおり新しいブロックを作成しています。対象としているASTは以下。Num(10)Exprなので以下のコードが実行されます。0);というわけで、symtable_visit_exprに続く。symtable_visit_exprもswitch文です。ListCompなのでsymtable_visit_listcompに進んで各種comprehensionを処理しているsymtable_handle_comprehensionへ。*)e);}outermostはComprephensionでiterはCall、targetはName(n)、ifsはCompareです。eltもName(n)です(ListComp直下の方)。ここでポイントなのは内包表記はFunctionのブロックが新しく作られるということ、テンポラリな名前が割り当てられていることです。symtable_new_tmpnameを見るとわかりますがその名前は_[0]なようです。†さて、というわけで内包表記の各要素についてVISITされ最終的にsymtable_visit_exprでNameが処理されます。0);コンテキストがLoadの場合はUSEを設定、それ以外(Storeなど)の場合はローカル変数として定義、と読み取れます。symtable_add_defは以下のような感じでシンボルテーブルに名前が登録されます。0;}最終的にシンボルテーブルには以下のようにブロックが登録されます。listcompはtopの子供になります。†シンボルテーブルができたら次にsymtable_analyzeが呼ばれています。symtable_analyzeで何をやっているかの説明は400行目ぐらい(3.5.1の場合)に書いてあります。*/freeというのがいまいちわかりません。コードを見ていくことにしましょう。symtable_analyzeはトップレベルのSTEntryに対してanalyze_blockを呼んでいるだけです。success;}削っても長いですが、ブロックにあるシンボルを収集して(analyze_name)子シンボルにその情報を渡して解析(analyze_child_block)最後に情報を更新(update_symbols)ということをやっているようです。わからないので先に進みましょう。†まず、analyze_name。GLOBAL_IMPLICIT);DEF_BOUNDなんてセットしているところないぞ?と思ったらInclude/symtable.hで次のように定義されていました。DEF_IMPORT)というわけで内包表記内で定義されているnはlocalに設定されます。analyze_blockおよび上記のコメントを参考にするとboundは親ブロックのローカル変数集合です。親ブロックの変数を参照しているとfreeという集合に入れられるようです。a]みたいに書くとaがfreeになるようです。rangeはGLOBAL_IMPLICITになります。言語仕様を考えると当たり前ですがこれらのことが行われています。globalを作ってanalyze_blockを再帰呼び出し、update_symbolsは判明したスコープを各シンボル情報を格納したdictに設定しています。長くなったのでいったんここまでで区切りとします。