2007/06/13

Erlang/OTP R11B-5 has been released

Erlang/OTP R11B-5 がリリースされました。
バイナリ内包表記はまだリリースされないみたいです。

2007/06/11

Erlang 文字列をコンパイルする

文字列をコンパイルする方法です。

erl_scan:tokens で1文ずつスキャン。
erl_parse:parse_form で1文ずつパース。
compile:forms でモジュール単位でコンパイル。
code:load_binary でコンパイルしたものをロードです。

改行コードは \n にしておかないとだめです。


-module(compile_string).
-export([compile/1, test/0]).

compile(FormsStr) ->
Forms = mk_forms(lists:flatten(FormsStr)),
{ok, M, B} = compile:forms(Forms),
{module, M} = code:load_binary(M, atom_to_list(M), B),
M.

mk_forms(String) ->
mk_forms(String, []).

mk_forms([], Acc) ->
lists:reverse(Acc);
mk_forms(S, Acc) ->
{done, {ok, Tokens, _Line}, Rest} = erl_scan:tokens([], S, 0),
{ok, Parsed} = erl_parse:parse_form(Tokens),
mk_forms(Rest, [Parsed|Acc]).

test() ->
S = "-module(fib).
-export([fib/1]).
fib(1) -> 1;
fib(2) -> 1;
fib(N) -> fib(N-1) + fib(N-2).
",
compile(S),
fib:fib(10). % コンパイルした関数を呼出す。

もっと簡単な方法があるような気がします。
Common Lisp ならマクロでおしまいですね。
正規表現を入力にコンパイルされた関数を返す、なんて使い方をしようかと思っています。

2007/06/08

体重が

53.7kg
もうちょっと食べないとまずいかな。

ちかごろうまくステップが踏めていない。
「躍りなせい」と、ばのーらの羊が言った。

Erlang で正規表現を実装して遊んでいる。
多少はかたちになった。

2007/05/22

Erlang Emakefile の実行には erl -make

Emakefile の実行は対話環境から make:all(). でもよいけど、コマンドラインの erl -make でもよいです。
Makefile に書くには erl -make がすっきりしてていいですね。escript だなんて戯言を言っていました。


%%-*-erlang-*-
{'*', [debug_info,
{outdir, "../ebin"}]}.

erlc を使ってもいいのですが。

2007/05/20

Erlang ディレクトリ内のファイルを(再帰的に)処理する

filelib:fold_files/5 という関数があります。
1番目の引数がディレクトリ。
2番目が処理対象か否かを判定するための正規表現。
3番目がサブディレクトリも再帰的に処理するか否か。
4番目が各ファイルに適用する関数。
5番目が初期値。
4番目の引数である関数は引数を2つとります。最初の引数は処理対象のファイル。次は最初は5番目に指定した引数で、それ以降はこの関数の返り値です。

サフィックスが erl のファイルをリストにして取得するには次のように書きます。


>1 filelib:fold_files("/home/ancient/letter/erlang", "\\.erl$", true, fun(X, Acc) -> [X|Acc] end, []).
["/home/ancient/letter/erlang/a/fib.erl",
"/home/ancient/letter/erlang/chat/_darcs/pristine/chat.erl",
"/home/ancient/letter/erlang/chat/_darcs/pristine/test_chat.erl",
"/home/ancient/letter/erlang/chat/chat.erl",
[...]|...]

でも、へんにリンクがあるとだめです。

言語は思考を規定する

やはりそうでしょう。
では、思考の可能性を最も広げてくれる言語は何でしょうか。
もっとも、広げるだけ広げてもそれでよい思考が生まれるわけでもないでしょう。
すくなくとも思考の可能性は生まれる。

間違いを犯しやすいからといって限定する言語は嫌いです。

新しい視野を示してくれる言語は素晴らしい。
想像力しだいで何もかもが自由になる言語は素晴らしい。

2007/05/19

Erlang クエックブックにインデックスを付ける。プロセスバージョン。

やっぱりプロセスを使わないと。


-module(make_index).
-compile(export_all).

start() ->
lists:foreach(fun(X) -> register(X, spawn_link(?MODULE, holder, [[]])) end,
[head, tail, index]),
register(contents, spawn_link(?MODULE, contents, [head])),
{ok, In} = file:read_file("cookbook_src.html"),
loop(binary_to_list(In)).

holder(V) ->
receive
{get, From} ->
From ! lists:reverse(V);
X ->
holder([X|V])
end.

contents(HorT) ->
receive
tail ->
contents(tail);
'終ったよ' ->
file:write_file("cookbook.html",
[begin
P ! {get, self()},
receive X -> X end
end || P <- [head, index, tail]]);
X ->
HorT ! X,
contents(HorT)
end.

loop([]) ->
contents ! '終ったよ';
loop("****index_place****" ++ T) ->
contents ! tail,
loop(T);
loop("<h2>" ++ T) ->
[Ast|Ref] = erlang:ref_to_list(make_ref()),
index ! io_lib:format("<h3><a href='~s'>", [[Ast|Ref]]),
contents ! io_lib:format("<h2><a name='~s'>", [Ref]),
h2(T);
loop("<h3>" ++ T) ->
[Ast|Ref] = erlang:ref_to_list(make_ref()),
index ! io_lib:format("<a href='~s'>", [[Ast|Ref]]),
contents ! io_lib:format("<h3><a name='~s'>", [Ref]),
h3(T);
loop([X|T]) ->
contents ! X,
loop(T).

h2("</h2>" ++ T) ->
index ! "</a></h3>",
contents ! "</a></h2>",
loop(T);
h2([X|T]) ->
index ! X,
contents ! X,
h2(T).

h3("</h3>" ++ T) ->
index ! "</a><br>",
contents ! "</a></h3>",
loop(T);
h3([X|T]) ->
index ! X,
contents ! X,
h3(T).