「コンピュータシステムの理論と実装」
第6章 アセンブラ まで進んだ。
第一段階のシンボルフリーなHackアセンブラをOCamlで実装した。
https://github.com/takeisa/ocaml-hack-assembler
- 依存ライブラリはCoreとRe2。
- コマンドラインの解析は、Coreのライブラリを使用。ここを参考に実装した。
実行例
デバッグ用出力がいろいろ出ているが、Add.asmをアセンブルして、Add.hackを出力している。
$ ./assembler Add.asm && echo "----" && cat Add.hack
ignore : 1 43 [// This file is part of www.nand2tetris.org]
ignore : 2 51 [// and the book "The Elements of Computing Systems"]
ignore : 3 36 [// by Nisan and Schocken, MIT Press.]
ignore : 4 37 [// File name: projects/06/add/Add.asm]
ignore : 5 0 []
ignore : 6 22 [// Computes R0 = 2 + 3]
ignore : 7 0 []
command: 8 2 [@2]
command: 9 3 [D=A]
dest=2 comp=48 jump=0
command: 10 2 [@3]
command: 11 5 [D=D+A]
dest=2 comp=2 jump=0
command: 12 2 [@0]
command: 13 3 [M=D]
dest=1 comp=12 jump=0
----
0000000000000010
1110110000010000
0000000000000011
1110000010010000
0000000000000000
1110001100001000
その他
デバッグ用に、レコード型やバリアント型の値を文字列に変換して表示したかったので、以前、Twitterで教えていただいた
meta_convを使って、変換する関数を自動で生成させようとした。
とりあえず、以下の単純なコードを作成して、
==hello.ml==
open Meta_conv.Open
open Ocaml_conv
type hello =
| Foo of string
| Bar of int
with conv(ocaml)
ocamlfindでコンパイルすると、エラーとなった。
$ ocamlfind ocamlc -verbose -package meta_conv,ocaml_conv -syntax camlp4o -package meta_conv.syntax hello.ml
findlib: [WARNING] Interface topdirs.cmi occurs in several directories: /home/satoshi/.opam/4.02.1/lib/ocaml, /home/satoshi/.opam/4.02.1/lib/ocaml/compiler-libs
Effective set of preprocessor predicates: preprocessor,syntax,camlp4o
Effective set of compiler predicates: pkg_meta_conv,pkg_compiler-libs,pkg_compiler-libs.common,pkg_ocaml_conv,pkg_camlp4,pkg_type_conv,pkg_meta_conv.syntax,syntax,autolink,byte
+ ocamlc.opt -verbose -I /home/satoshi/.opam/4.02.1/lib/ocaml/compiler-libs -I /home/satoshi/.opam/4.02.1/lib/ocaml_conv -I /home/satoshi/.opam/4.02.1/lib/ocaml/camlp4 -I /home/satoshi/.opam/4.02.1/lib/type_conv -I /home/satoshi/.opam/4.02.1/lib/meta_conv -pp "camlp4 '-I' '/home/satoshi/.opam/4.02.1/lib/ocaml/camlp4' '-I' '/home/satoshi/.opam/4.02.1/lib/type_conv' '-I' '/home/satoshi/.opam/4.02.1/lib/meta_conv' '-I' '/home/satoshi/.opam/4.02.1/lib/meta_conv' '-parser' 'o' '-parser' 'op' '-printer' 'p' 'pa_type_conv.cma' 'meta_conv.cmo' 'pa_meta_conv.cma' " hello.ml
+ camlp4 '-I' '/home/satoshi/.opam/4.02.1/lib/ocaml/camlp4' '-I' '/home/satoshi/.opam/4.02.1/lib/type_conv' '-I' '/home/satoshi/.opam/4.02.1/lib/meta_conv' '-I' '/home/satoshi/.opam/4.02.1/lib/meta_conv' '-parser' 'o' '-parser' 'op' '-printer' 'p' 'pa_type_conv.cma' 'meta_conv.cmo' 'pa_meta_conv.cma' 'hello.ml' > /tmp/ocamlpp86694c
File "hello.ml", line 1:
Error: Error while linking hello.cmo:
Reference to undefined global `Ocaml_conv'
ocamlc.opt returned with exit code 2
Ocaml_convがうまく参照できないようだ。
きっとライブラリの指定の方法か、OCamlの開発環境に原因があるのだろう。
こちらは、そのうち調べてみよう。