ひとりNand2Tetris(6)ーGo言語で作るアセンブラ

Posted by Hiraku on 2015-11-06

だいぶ間が空いてしまったけど、Nand2Tetrisもくもくの続き。ここからはソフトウェア層になります。まず作るべきはニーモニックの羅列を"Hack機械語"に変換するアセンブラ。単なる文字列操作の範疇なので割と簡単で、プログラミング言語を作ってる感覚はありません。


コンピュータシステムの理論と実装 ―モダンなコンピュータの作り方

Hackアセンブラについて

アセンブラって単語を聞いてwktkしているバイナリアンな人がいたら申し訳ないのだけど、Nand2Tetrisにおけるアセンブラはあくまで教育用のもので、現実のCPUで使われるものとはだいぶ異なると思います。アセンブル後に作成されるのはバイナリファイルではなく、"0100010101..."という、文字で書かれたテキストファイルです。読みやすいですね!

例えば、こんな感じで変換されます。

@i
M=1
@sum
M=0
0000000000010000
1110111111001000
0000000000010001
1110101010001000

コメント行やラベル行を取り除くと、XXX.asmファイルとXXX.hackファイルの行数は一致することになります。

文字列操作ができるプログラミング言語なら何を使っても作れます。 せっかくなので勉強を兼ねてGo言語を使ってみることにしました。

実装

今まではnand2tetrisのリポジトリ内に丸ごと置いていましたが、go getできた方がいいと思ったので、リポジトリを分割しました。

https://github.com/hirak/Assembler

$ go get github.com/hirak/Assembler

これでインストールされるのは「Assembler」という名前のコマンドです。Macで作っているのでWindowsでの動作は確認していません。エラー処理はいい加減ですが、一応テキストに付いていたテストは全部パスしたので、正常系を渡す限りは動くはず!

$ Assembler foo.asm
$ cat foo.hack
0000000100000000
1110110000010000
...

まだGoに慣れてなくて、Goらしくない書き方をしているかもしれませんが、何とか書けるものですね。

一応、テキスト通りに3つのモジュール的な物を作り、main関数で組み立てています。でもpackage mainだけだし、これぐらいなら一つのファイルで作ってしまう人もいるのかも?

  • Parser(ファイルを読み込んでニーモニックを分割解釈する)
  • Code(ニーモニック一つ一つを1010101...の文字列に変換する。素朴なswitch文の羅列)
  • SymbolTable(アセンブリ言語でラベル構文や変数が使えるように、グローバル変数みたいなものを覚えてくれるもの。mapにメソッドを生やしただけ)

次へ向けて

次章からコンパイラの実装に向けての作業になるので難易度が跳ね上がるっぽい。覚悟を決めてとりかかるしか無いな。。

etcの最新記事