Haskell: Pugs 6.0.5をビルドするためのパッチ
Pugs 6.0.5(リビジョン29)をビルドするためのパッチを作ってみた。
ただし、このパッチは完全じゃない。makeはできるけれども、make testが通らない。本当に単純なexpression、例えば「1+2」はうまく評価できるけれども、サブルーチンが絡んでくるとうまく評価できない。原因はよくわかっていない。(原因がわかった。追記を参照。) このパッチは、インポートによる関数の衝突(特にData.SetとData.List)が発生しないようにしただけなので、それがまずいのかもしれない。
それでも試したい方は、
を参考にしてパッチを当ててみるとよいかもしれない。
ビルドしてできたpugsインタプリタを実行すると以下のような感じで動作する。このバージョンでは、評価の過程がダンプされるのでちょっと楽しい。
% ./pugs .=====. __ __ ____ ___ _________________________________________ || || || || || || ||__' Pugs 6: Based on the Perl 6 Synopses ||====' ||__|| ||__|| __|| Copyright 2005 by Autrijus Tang || `====' ___|| `===' World Wide Web: http://autrijus.org/pugs || `====' Report bugs to: autrijus@autrijus.org == Version: ========================================= Welcome to Pugs -- Perl6 User's Golfing System Type :h for help pugs> 1+2 *** Evl: Syn ";" {{ App "&infix:+" [Val (VInt 1),Val (VInt 2)] [] }} *** Evl: App "&infix:+" [Val (VInt 1),Val (VInt 2)] [] *** Evl: Syn "[]" {{ Syn "," {{ }}; (0, ...) }} *** Evl: Syn "," {{ }} *** Ret: () *** Ret: () *** Ret: 3 *** Ret: 3 3 pugs> "hello, " ~ "world" *** Evl: Syn ";" {{ App "&infix:~" [Val (VStr "hello, "),Val (VStr "world")] [] }} *** Evl: App "&infix:~" [Val (VStr "hello, "),Val (VStr "world")] [] *** Evl: Syn "[]" {{ Syn "," {{ }}; (0, ...) }} *** Evl: Syn "," {{ }} *** Ret: () *** Ret: () *** Ret: "hello, world" *** Ret: "hello, world" "hello, world"
以下独り言。
Pugs 6.0.5のコードは、6.0.0のコードと比べて理解するのが非常に難しい。
特に、
の辺り。
これらがわからないと読めそうにない。
Parser.hsやEval.hsも初期バージョンと比べると断然進化している。
Evalの型が
type Eval x = ContT Val (ReaderT Env IO) x
だと言われても、今は全然ピンと来ない。
でも、上で挙げた3つの概念と実際のコードとの対応が理解できれば、ひとまず山は越えられそうな予感。
追記 (2006/04/14 08:40)
make testが通らない訳がわかった。Pugs 6.0.5(リビジョン29)では、後で定義するサブルーチンを他のサブルーチンから呼び出すとまずいらしい。
この原因は、Pugsのコミットログがヒントになってわかった。以下のような記述が残っていたので、気になって差分を見てみた。
r30 | autrijus | 2005-02-16 15:24:13 +0900 (水, 16 2月 2005) | 1 line * bandaid to cure lexical scope bugs
単に呼び出し順序を変えただけのようだ。この変更を適用すると、無事make testが通るようになった。
Index: t/01basic.t =================================================================== --- t/01basic.t (revision 29) +++ t/01basic.t (revision 30) @@ -11,9 +11,9 @@ open PUGS, "| $pugs" or die "Cannot pipe out to $pugs: $!"; print PUGS << '.'; - sub cool { fine($_) ~ " # We've got " ~ toys }; sub fine { "ok " ~ $_ }; sub toys { "fun and games!\n" }; + sub cool { fine($_) ~ " # We've got " ~ toys }; cool 2 . close PUGS;