[インデックス 1895] ファイルの概要
このコミットは、Go言語の初期開発段階における重要なファイル構造の再編成を示しています。具体的には、抽象構文木(AST: Abstract Syntax Tree)を定義する ast.go
ファイルが、一時的な開発ディレクトリからGoの標準ライブラリの一部として永続的な場所へ移動されたことを記録しています。この変更は、Goコンパイラの基盤となるASTのコンポーネントが、より安定した、共有されるべきパッケージとして位置づけられたことを意味します。
コミット
commit b499da48a4d8a06ae3b0f6ccb2d861474a11a554
Author: Robert Griesemer <gri@golang.org>
Date: Thu Mar 26 17:51:44 2009 -0700
move AST into src/lib/go
R=r
DELTA=1509 (756 added, 751 deleted, 2 changed)
OCL=26799
CL=26801
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/b499da48a4d8a06ae3b0f6ccb2d861474a11a554
元コミット内容
このコミットの元のメッセージは「move AST into src/lib/go」と非常に簡潔です。これは、抽象構文木(AST)に関連するコードが、src/lib/go
ディレクトリに移動されたことを示しています。R=r
はレビュー担当者を示し、DELTA
は変更された行数(追加、削除、変更)の合計を示しています。OCL
と CL
は、Goプロジェクト内部の変更リスト番号に関連する可能性があります。
変更の背景
このコミットが行われた2009年3月は、Go言語がまだ一般に公開される前の、活発な初期開発段階にありました。Goのコンパイラや標準ライブラリの構造が固まりつつある時期であり、ast.go
の移動はそのプロセスの一部です。
usr/gri/pretty
のようなパスは、おそらく開発者(Robert Griesemer、gri
)の個人作業スペースや、特定の実験的な機能のための仮のディレクトリであったと推測されます。Goコンパイラの核となる要素であるASTの定義が、このような一時的な場所から src/lib/go
というGoの標準ライブラリの公式な場所へ移動されたことは、以下の重要な意味を持ちます。
- モジュールの安定化と標準化: ASTはGoコンパイラがソースコードを解析し、意味解析やコード生成を行う上で不可欠なデータ構造です。これが
src/lib/go
に移動されたことで、ASTの定義がGo言語の公式な、安定したAPIの一部として位置づけられたことを示します。これにより、他のコンパイラコンポーネントやツールがASTに依存しやすくなり、Goエコシステム全体の発展を促進します。 - コードベースの整理: 開発が進むにつれて、コードベースの論理的な整理と構造化は不可欠です。この移動は、Goプロジェクトが初期の試行錯誤段階から、より組織化された、長期的なメンテナンスを考慮した構造へと移行していることを示唆しています。
- 共有と再利用の促進:
src/lib/go
に配置されることで、ASTパッケージはGoの他の標準ライブラリパッケージと同様に、Goツールチェインの他の部分や、将来的にはサードパーティのツールからも容易に利用できるようになります。
前提知識の解説
抽象構文木(AST: Abstract Syntax Tree)
ASTは、プログラミング言語のソースコードの抽象的な構文構造を木構造で表現したものです。コンパイラやインタプリタがソースコードを処理する際の中心的なデータ構造として機能します。
- 構文解析(Parsing): ソースコードはまず字句解析(Lexical Analysis)によってトークン列に変換され、次に構文解析によってこれらのトークンからASTが構築されます。ASTは、プログラムの構造(関数定義、変数宣言、制御構造など)を階層的に表現します。
- 意味解析(Semantic Analysis): ASTは、型チェック、変数スコープの解決、エラー検出などの意味解析の段階で利用されます。
- コード生成(Code Generation): 最終的に、ASTは中間表現(IR)やターゲットマシンコードへの変換の基盤となります。
Go言語の go/ast
パッケージは、GoプログラムのASTを表現するための型と関数を提供します。これにより、Goのツール(go fmt
、go vet
、gopls
など)はソースコードをプログラム的に解析・操作することができます。
Go言語の初期開発とディレクトリ構造
2009年当時のGo言語は、Google社内で開発が進められており、まだ一般には公開されていませんでした。この時期のコードベースは、現在のGoの安定版とは異なるディレクトリ構造やビルドシステムを持っていました。
src/lib/go
: このディレクトリは、Go言語の標準ライブラリの初期の場所の一つであったと考えられます。Goのコアとなるパッケージ(fmt
,os
,io
など)がここに配置され、Goプログラムが利用できる基本的な機能を提供していました。usr/gri/pretty
:usr
ディレクトリは、Unix系システムでユーザー関連のファイルが置かれる慣習的な場所です。gri
は開発者Robert Griesemerのイニシャルまたはユーザー名を示唆しており、pretty
はコード整形ツールや、ASTの可視化に関連する一時的な作業ディレクトリであった可能性が高いです。このようなパスは、開発者が新しいアイデアを試したり、特定のコンポーネントを独立して開発したりする際に使用されることがあります。
MakefileとGoのビルドシステム(初期)
Go言語の初期のビルドシステムは、現在のような go build
コマンドが普及する前は、Makefile
に大きく依存していました。Makefile
は、プログラムのコンパイル、リンク、インストールなどのビルドプロセスを自動化するためのルールを定義するファイルです。
$(AR)
:AR
は "archiver" の略で、ライブラリファイル(.a
拡張子を持つアーカイブファイル)を作成・管理するためのコマンドです。Unix系システムではar
コマンドが一般的です。grc
: これはGo言語のビルドシステム特有のコマンドまたはフラグである可能性があります。Goの初期のツールチェインの一部として、アーカイブファイルを生成する際に使用されたと考えられます。.a
ファイル: Goの初期のビルドでは、コンパイルされたパッケージは.a
拡張子を持つアーカイブファイルとして生成され、他のパッケージからリンクされていました。これはC言語の静的ライブラリに似ています。$(GOROOT)/pkg
:GOROOT
はGoのインストールディレクトリのルートパスを示す環境変数です。pkg
ディレクトリは、コンパイルされたGoパッケージのアーカイブファイル(.a
ファイル)が配置される場所でした。他のGoプログラムがこれらのパッケージをインポートする際に、このディレクトリから必要なアーカイブファイルが検索されます。
技術的詳細
このコミットは、ast.go
ファイルの移動と、それに伴うビルドシステム(Makefile)の更新という2つの主要な変更を含んでいます。
-
ast.go
のファイル移動:usr/gri/pretty/ast.go
からsrc/lib/go/ast.go
へのファイル名変更(rename from
とrename to
で示される)が行われました。similarity index 100%
は、ファイルの内容が変更されずに移動されたことを意味します。これは、既存のAST定義がそのままGoの標準ライブラリに組み込まれたことを示しています。 -
src/lib/go/Makefile
の更新:ast.go
がsrc/lib/go
ディレクトリに移動されたことに伴い、このディレクトリのMakefile
が更新され、ASTパッケージがGoのビルドプロセスに適切に組み込まれるようになりました。-
O2
変数への追加:--- a/src/lib/go/Makefile +++ b/src/lib/go/Makefile @@ -35,8 +35,10 @@ O1=\ token.$O\ O2=\ +\tast.$O\ scanner.$O\
O2
は、ビルドの第2段階でコンパイルされるオブジェクトファイル(.o
)のリストです。ここにast.$O
が追加されたことで、ast.go
がコンパイル対象として認識されるようになりました。 -
ast.a
ターゲットの追加とアーカイブ化:--- a/src/lib/go/Makefile +++ b/src/lib/go/Makefile @@ -45,10 +47,12 @@ a1: $(O1)\ rm -f $(O1)\ a2: $(O2)\ +\t$(AR) grc ast.a ast.$O\ $(AR) grc scanner.a scanner.$O\ rm -f $(O2)\
ast.a: a1 a2
という行が追加され、ast.a
というアーカイブファイルがa1
とa2
のターゲットに依存することが示されました。a2
ターゲット内では、$(AR) grc ast.a ast.$O
というコマンドが追加されました。これは、コンパイルされたast.$O
オブジェクトファイルがast.a
というアーカイブファイルにまとめられることを意味します。これにより、ASTパッケージが他のGoパッケージからリンク可能なライブラリとして利用できるようになります。 -
newpkg
ターゲットへの追加:--- a/src/lib/go/Makefile +++ b/src/lib/go/Makefile @@ -45,10 +47,12 @@ a1: $(O1)\ rm -f $(O1)\ a2: $(O2)\ +\t$(AR) grc ast.a ast.$O\ $(AR) grc scanner.a scanner.$O\ rm -f $(O2)\ newpkg: clean +\t$(AR) grc ast.a\ $(AR) grc scanner.a\ $(AR) grc token.a\
newpkg
ターゲットは、新しいパッケージをクリーンな状態からビルドする際に使用されます。ここに$(AR) grc ast.a
が追加されたことで、ast.a
もこのプロセスで適切に生成されるようになりました。 -
nuke
ターゲットの更新:--- a/src/lib/go/Makefile +++ b/src/lib/go/Makefile @@ -56,11 +60,12 @@ $(O1): newpkg\ $(O2): a1\ nuke: clean -\trm -f $(GOROOT)/pkg/scanner.a $(GOROOT)/pkg/token.a\ +\trm -f $(GOROOT)/pkg/ast.a $(GOROOT)/pkg/scanner.a $(GOROOT)/pkg/token.a\
nuke
ターゲットは、ビルド成果物を完全に削除するクリーンアップ操作です。$(GOROOT)/pkg/ast.a
が削除対象に追加されたことで、ast.a
もクリーンアッププロセスに含まれるようになりました。 -
packages
ターゲットの更新:--- a/src/lib/go/Makefile +++ b/src/lib/go/Makefile @@ -56,11 +60,12 @@ $(O1): newpkg\ $(O2): a1\ nuke: clean -\trm -f $(GOROOT)/pkg/scanner.a $(GOROOT)/pkg/token.a\ +\trm -f $(GOROOT)/pkg/ast.a $(GOROOT)/pkg/scanner.a $(GOROOT)/pkg/token.a\ -packages: scanner.a token.a\ +packages: ast.a scanner.a token.a\ install: packages +\tcp ast.a $(GOROOT)/pkg/ast.a\ \tcp scanner.a $(GOROOT)/pkg/scanner.a\ \tcp token.a $(GOROOT)/pkg/token.a\ \n
packages
ターゲットは、すべてのパッケージをビルドする際に使用されます。ast.a
が依存関係に追加されたことで、packages
を実行するとast.a
もビルドされるようになりました。 -
install
ターゲットの更新:--- a/src/lib/go/Makefile +++ b/src/lib/go/Makefile @@ -56,11 +60,12 @@ $(O1): newpkg\ $(O2): a1\ nuke: clean -\trm -f $(GOROOT)/pkg/scanner.a $(GOROOT)/pkg/token.a\ +\trm -f $(GOROOT)/pkg/ast.a $(GOROOT)/pkg/scanner.a $(GOROOT)/pkg/token.a\ -packages: scanner.a token.a\ +packages: ast.a scanner.a token.a\ install: packages +\tcp ast.a $(GOROOT)/pkg/ast.a\ \tcp scanner.a $(GOROOT)/pkg/scanner.a\ \tcp token.a $(GOROOT)/pkg/token.a\ \n
install
ターゲットは、ビルドされたパッケージを$(GOROOT)/pkg
ディレクトリにコピーします。cp ast.a $(GOROOT)/pkg/ast.a
が追加されたことで、ast.a
もGoのインストールディレクトリに配置され、他のGoプログラムからインポート可能になります。
-
コアとなるコードの変更箇所
このコミットにおけるコアとなるコードの変更は、以下の2つのファイルに集約されます。
-
usr/gri/pretty/ast.go
からsrc/lib/go/ast.go
へのファイル移動(リネーム) これは、git diff
の出力でrename from usr/gri/pretty/ast.go
とrename to src/lib/go/ast.go
、そしてsimilarity index 100%
によって示されています。ファイルの内容自体は変更されていません。 -
src/lib/go/Makefile
の変更Makefile
の変更は、ast.go
が新しい場所に移動されたことに伴い、GoのビルドシステムがASTパッケージを適切に処理できるようにするためのものです。O2
変数にast.$O
を追加。ast.a
というターゲットと、そのビルドコマンド$(AR) grc ast.a ast.$O
をa2
ターゲット内に追加。newpkg
ターゲットに$(AR) grc ast.a
を追加。nuke
ターゲットのrm -f
コマンドに$(GOROOT)/pkg/ast.a
を追加。packages
ターゲットの依存関係にast.a
を追加。install
ターゲットにcp ast.a $(GOROOT)/pkg/ast.a
を追加。
コアとなるコードの解説
このコミットの核心は、Goコンパイラの基盤であるASTの定義を、Goの標準ライブラリの永続的な場所へ移動し、そのビルドプロセスを正式に組み込んだ点にあります。
ast.go
のリネームは、単なるファイル名の変更以上の意味を持ちます。これは、ASTがGo言語のツールチェイン全体で共有されるべき、安定した、重要なコンポーネントとして認識されたことを示します。usr/gri/pretty
のようなパスは、開発初期の実験的なコードや個人作業スペースを示唆しており、そこから src/lib/go
という標準ライブラリのパスへの移動は、そのコンポーネントが「製品レベル」の品質と安定性を持つと判断されたことを意味します。
Makefile
の変更は、このファイル移動をビルドシステムに反映させるための具体的な手順です。
O2
へのast.$O
の追加は、ast.go
がコンパイル対象のソースファイルとして認識され、オブジェクトファイルast.$O
が生成されることを保証します。ast.a
ターゲットと$(AR) grc ast.a ast.$O
コマンドの追加は、コンパイルされたASTのオブジェクトファイルがast.a
というアーカイブファイル(静的ライブラリ)にまとめられることを意味します。これにより、他のGoパッケージやコンパイラのコンポーネントが、このast.a
ライブラリをリンクしてASTの機能を利用できるようになります。newpkg
,nuke
,packages
,install
ターゲットへのast.a
の組み込みは、ASTパッケージがGoのビルド、クリーンアップ、およびインストールプロセス全体にわたって、他の標準ライブラリパッケージと同様に扱われることを保証します。特にinstall
ターゲットでast.a
が$(GOROOT)/pkg
にコピーされることは、GoのツールチェインがASTパッケージを標準的な方法で発見し、利用できるようになることを意味します。
これらの変更により、ASTはGo言語のコンパイラとツールチェインの不可欠な部分として、その後のGo言語の発展を支える基盤が確立されました。
関連リンク
- Go言語の公式ウェブサイト: https://go.dev/
- Go言語のASTパッケージ (
go/ast
): https://pkg.go.dev/go/ast - Go言語の初期開発に関する情報(Goの歴史など): Go言語の公式ブログや初期のメーリングリストアーカイブに情報がある可能性があります。
参考にした情報源リンク
- Go言語のソースコードリポジトリ: https://github.com/golang/go
- Go言語の初期のコミット履歴(GitHubまたはGoの公式リポジトリ)
- Go言語のビルドシステムに関するドキュメント(初期のGoに関する技術記事やメーリングリストの議論など)
- 抽象構文木(AST)に関する一般的なコンピュータサイエンスの資料。
- Makefileの基本的な使い方に関するドキュメント。
ar
コマンドに関するUnix/Linuxのマニュアルページ。- Robert Griesemer氏のGo言語に関する講演や記事。 (これらの情報は、一般的な知識と、Go言語の初期開発に関する公開されている情報源に基づいています。特定のURLは、検索結果によって変動する可能性があります。)