2008.10.27 Mon. ehaskell : eruby や erb のように haskell ソースコードを テキストに埋め込めるようにする。 <% ... %> <%= ... %> IO String を返すものを基本とする。 その上で、 String, Show a => IO a, Show a => a の3つを使えるようにしよう。 <%== ... %> <%=$ ... %> <%==$ ... %> とかかな。 例えばそれぞれ、 <%= getLine %> <%== "hello" %> <%=$ getLine >>= return . length %> <%==$ 88 * 9 %> とかかな。 また、 <% そのものを表示するためにはどうしたらいいか。 <%== "<%" %> とかでいいか。 _ehs フォルダにソースをコピーして、そこでコンパイルするという方法でいいかな。 2008.10.28 Tue. 平文を引数とすることができるようにする。 つまり、 <% when True -%>something<%--%>other<%-%> が when True (do {putStr something;}) (do {putStr other;}) のようになるようにしたらどうか。 また class を利用して、Showable と String をひとつにできないか。 OPTIONS_GHC で、 -XTypeSynonymInstances -XFlexibleInstances -fallow-undecidable-instances -XOverlappingInstances を指定すれば、Striing と Show a はひとつにできる。 しかし、そうすると ghc に限られてしまう。 いずれにしても、 ghc を走らせる以上は ghc に限られてしまうわけではあるが、 しかし、そうであっても言語仕様で定義されていない特長を使うことは、 どうだろうか。 将来のバージョンでこれらの特長が採用されなかった場合にうまくない感じになってしまう。 むずかしいところだ。 2008.10.29 Wed. 単純にコードを実行するものと、 IO のなかにいれるものをわけなくてはならない。 <% %> と、<%% %%>とかかな。 まとめると、 <% ... %> <%% ... %%> <%= ... %> <%== ... %> <%=$ ... %> <%==$ ... %> <% ... -%> ... <%- ... -%> ... <%- ... %> 例 <% hello = "hello" %> <%% good-bye <- return "good-bye" %%> <%= return hello %> <%== hello %> <%=$ return 88 %> <%==$ 88 %> <% if True then -%> ... <%- else -%> ... <%-%> こんな感じかな。 とにかく作りはじめようか。 mtlparse を使おう。 まずは、とりあえずのファイルを作成しよう。 で、 return () をするだけのパッケージを作ることにする。 2008.11.1 Sat. yjtools に ghcMake と updateFile もいれたことだし、 そろそろ開発を始められるだろう。 まず始めは引数でとったファイルを単純に出力するようにする。 それは以下の段階をふんで発展させていく。 0. なんのことない readFile >>= putStr 1. MTLParse を使用して、出力。 2. updateFile を使用して、_ehs 以下にコピーを作成してから出力 3. escape した文字列として出力。 4. escape した文字列に putStr をくっつけて、それをコンパイルして出力。 2008.11.2 Sun. 5. putStr を do { ;} で囲う。 6. <%= %> のなかのものに、; >>= putStr; をつける。 7. <% %> のなかのものを先頭にもってくる。(Bool, String) を使う。 2008.11.3 Mon. <% %> と <%% %%> は逆にする。 8. 次は、<% -%> <%- -%> <%- %> <%== %> と <%= %> を逆にする。 次は -o オプションを実装する。 2008.11.4 Wed. 別のファイルを include できるようにする。 require "Hoge" で同じディレクトリに Hoge.hs ファイルを持っていくようにしようか。 2008.11.7 Fri. readFile や、hPutStr を UTF8 のにする。 2008.11.8 Sat. <% %> 内で、"" や () で囲まれた部分に %> が書けるようにする。 コマンドライン引数から、変数の設定ができるようにする。 var=some と書くか、あるいは、--top="var=some","import Some" 的にするか。 前者のほうがすっきりしているが。 後者のほうが多機能である。 前者でいいかな。 import するモジュールをそのつど変えるという機能は便利ではあるが、必須ではないと思う。 2008.11.9 Sun. 今は、-o でファイルを作るときに、executable file よりも、作るべきファイルが新しい場合に、 実行しないようにしているが、やはり実行するのでいいと思う。 そこらへんのめんどうは hake が見るわけだし、 executable file が新しくならなくても、入力ファイルなどが変わるかもしれないし。 parse error が起きたときには src を削除するようにしたほうがいいのかな。 というより、最初から作らないというか。 あと、unit test を作成しよう。 次は、refactoring をしなくてはならない。 そして、変数の default を指定できるようにしようか。 2008.11.10 Mon. unit test を作成する前に、module をわけなくてはならないだろう。 2008.11.11 Tue. example/tests の Some.hs を darcs にいれ忘れた。 test の都合上、copyImports は、src と dist を返して、 それを Main 側でコピーするようにしようか。 古かったらコピーしないという処理も忘れないようにしよう。 本当なら darcs mv Main.hs EHaskell.hs とするべきだったことに思い至るが、 今それをやるのは危険と判断し、diff file に非常に冗長性が出てしまうものの、 このまま続行する。 本来ならば、Main と Ehaskell をわけた段階で、 darcs record するべきだったかもしれない。 2008.11.27 Thr. let ver = val; の形式に対応する必要がある。 2008.12.4 Thr. <%== function -%>some<%- -%>other<%-%> みたいなのを作りたい。 ただし、これには今のようなやりかたではだめだ。 parseEHaskell を IO String を返すように作るべきだったかもしれない。 で、最後に >>= hPutStr h をつけるほうが良かったな。 いまさらだけどやってみようか。 ただ、そうすると、<% putStrLn "hoge" %> のようなものの扱いが変化するし。 いろいろと複雑な問題がある。 腰をすえてやらなければならなそうだな。 StateT String IO () を利用しようかな。 ひととおりやってみたが、a <- someIO のような場合に、 a <- lift someIO のようにしなければいけない。 2008.12.6 Sat. <% ... %> の中をとりだしたあとで、そのなかみを見るようにしようか。 "" と () のなかだけを特別に扱うようにする。 (())のペアを整えることを考えると regexPR ではうまくいかないと思う。 だから、両方とも mtlParse を使おうか。 それと、mkOutput は (Pos, String) を返すようにしようか。 2008.12.7 Sun. <% ... %> の種類。 <% %>, <%% %%>, <% -%>, <%- -%>, <%- %>, <%= %>, <%== %>, <%=$ %>, <%==$ %> の9種類。 問題は、<%-%> は一段上のレベルの parse をしないと決定されないという点。 両方の候補を試行して、正しいほうを取るようにするべきだろう。 それぞれ、 Code, CodeTop, CodeBegin, CodeCont, CodeEnd, CodeEq, CodeEqEq, CodeEqShow, CodeEqEqShow としよう。 失敗したら exit するようにしよう。 だいたいできてきた。 あとは command line からの = と、current directory での import だ。 次は、command line option を GetOpt を利用して扱うようにすること。 2008.12.8 Mon. エラーが起きたときには、-o ファイルをアップデートしないようにしたい。 2008.12.10 Wed. span を利用するとか、span っぽい関数を探すとか、yjtools に作るとかを考えよう。 2008.12.11 Thr. applyInfile が infile を dir と file にわけてからどうの、といった感じにすること。 2008.12.12 Fri. EHaskell.hs では、[ (CodePos, String) ] を返すようにして、 MkCode で、そこから code を作成するようにしよう。 2008.12.13 Sat. Text - Inner Code - Inner CodeBegin, CodeCont, CodeEnd - Inner CodeEq - Inner CodeEqEq - Inner CodeEqShow - Inner CodeEqEqShow - Inner CodeTop - Top CodeTop - Import CodeTop - Definition data CodePos = Import { getModName :: String } | Top | Definition { getVar :: String } | Inner CodeText 2008.12.17 Wed. intoBody "title" の title 部分を抽出しよう。 それをならべて目次とする。 章番号のあつかいについては、多少考慮の余地あり。 まずはそこから。 小項目をつけるのは後。 あるいはないほうがいいのかもしれない。 2008.12.18 Thr. web page を作成中。 short tutorial の contents を自動作成するようにしたい。 そのためには、それぞれの章が自身を List に登録して、 それを txt ファイルに書き出すようにしたらいいと思われる。 hPrint とか read あたりを利用したらどうだろうか。 あるいは、read を利用するよりも、module として、 .hs ファイルに書き出してしまう というのもひとつの手か。 また、module が同じ directory 内になくちゃいけないという ehaskell の制限について 考えなければならない。 今のところは hake を利用して copy を作成することで対応しているが。 2010.5.10 Mon. 標準入力からの入力を受けるようにする。