Camlp4 3.10 のさわり [OCaml]
そろそろ Camlp4 3.10 を調べていこうかと思った。
* Camlp4 で何もしない
OCaml ソースを構文木にしてさらに OCaml コードに戻すだけのコマンドラインは以下のようになる。
camlp4 -parser OCaml -printer OCaml tryme.ml
これは以下と同じ
camlp4 Camlp4OCamlParser.cmo Camlp4OCamlPrinter.cmo tryme.ml
以前の Camlp4 では出力でコードに戻す場合と構文木のままダンプしてコンパイラに渡す場合でプリンタを変えなければいけなかったけど 3.10 では -printer Auto とすると適宜に選んでくれる。
camlp4 -parser OCaml -printer Auto tryme.ml # この場合コードを出力
ocamlc -pp 'camlp4 -parser OCaml -printer Auto' tryme.ml # この場合構文木のダンプ
* 付属の構文拡張を使ってみる
Camlp4 3.10 には Haskell 風のリスト内包表記が書ける構文がついてくる。
KURO-BOX% ocaml -I +camlp4/Camlp4Parsers Objective Caml version 3.10.0 # #load "camlp4o.cma";; Camlp4 Parsing version 3.10.0 # #load "Camlp4ListComprehension.cmo";; # [x * 2 | x <- [1; 2; 3] ];; - : int list = [2; 4; 6] # [x | x <- [1; 2; 3; 4; 5; 6]; x mod 2 = 0];; - : int list = [2; 4; 6] # [(x, y) | x <- [1; 2; 3]; y <- ['a'; 'b'; 'c'] ];; - : (int * char) list = [(1, 'a'); (1, 'b'); (1, 'c'); (2, 'a'); (2, 'b'); (2, 'c'); (3, 'a'); (3, 'b'); (3, 'c')]
* 構文木の姿を捉える
Camlp4.PreCast.Syntax.parse_implem 関数で OCaml ソースを構文木に変換できる。これは 3.9 のときと違って参照型ではない。どういう設計に変わったのかな?
KURO-BOX% ocaml Objective Caml version 3.10.0 # #load "camlp4o.cma";; Camlp4 Parsing version 3.10.0 # Camlp4.PreCast.Syntax.parse_implem Camlp4.PreCast.Loc.ghost (Stream.of_string "let _ = 1");; - : Camlp4.PreCast.Syntax.Ast.str_item = Camlp4.PreCast.Syntax.Ast.StExp (<abstr>, Camlp4.PreCast.Syntax.Ast.ExInt (<abstr>, "1"))
* クォーテーションを使う
camlp4oof を使うとクォーテーションも使えるようになる。
KURO-BOX% ocaml Objective Caml version 3.10.0 # #load "camlp4oof.cma";; Camlp4 Parsing version 3.10.0 # open Camlp4.PreCast;; # let _loc = Camlp4.PreCast.Loc.ghost;; val _loc : Camlp4.PreCast.Loc.t = <abstr> # <:str_item< print_string "Hello World!" >>;; - : Camlp4.PreCast.Ast.str_item = Camlp4.PreCast.Ast.StSem (<abstr>, Camlp4.PreCast.Ast.StExp (<abstr>, Camlp4.PreCast.Ast.ExApp (<abstr>, Camlp4.PreCast.Ast.ExId (<abstr>, Camlp4.PreCast.Ast.IdLid (<abstr>, "print_string")), Camlp4.PreCast.Ast.ExStr (<abstr>, "Hello World!"))), Camlp4.PreCast.Ast.StNil <abstr>)
とりあえずここまで。
エラー出た時はここが参考になりました
http://d.hatena.ne.jp/cheshireCat/20110723/1311427039
by h_sakurai (2014-05-01 10:07)
OCaml3.11のCamlp4からDynlinkライブラリが必要になったようです。
#load "dynlink.cma";;
#load "campl4o.cma";;
でうまくいったと。
by h_sakurai (2014-05-01 10:12)