forked from mkotha/ghcguide_ja
/
utils.xml
449 lines (351 loc) · 24 KB
/
utils.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="utils">
<title>その他のHaskellユーティリティプログラム</title>
<indexterm><primary>utilities, Haskell</primary></indexterm>
<para>この節では、配布物に含まれるその他のプログラムについて述べる。これらは、大いなるHaskellでのプログラミング作業に役立つものである。</para>
<!-- comment: hasktags was dropped in GHC 6.12
<sect1 id ="hasktags">
<title>Haskell用Ctags/Etags: <command>hasktags</command></title>
<indexterm><primary><command>hasktags</command></primary></indexterm>
<indexterm><primary>CTAGS for Haskell</primary></indexterm>
<para><command>hasktags</command>は非常に単純なHaskellプログラムであり、Haskellプログラムに対して、ctagsの「tags」ファイルやetagsの「TAGS」ファイルを生成する。</para>
<para>これをNEditやVim、Emacsなどのエディタにロードすると、複数ファイルからなるプログラムにおいて、関数、型、構築子の定義を探し、簡単に移動することができる。</para>
<para>起動構文</para>
<screen>
hasktags files
</screen>
<para>
これで、<option>files</option>中のファイルが全て読まれ、ctagsの「tags」ファイルとetagsの「TAGS」ファイルとがカレントディレクトリに生成される。</para>
<para>使用例</para>
<screen>
find -name \*.\*hs | xargs hasktags
</screen>
<para>この場合、カレントディレクトリ以下の全てのHaskellソースが探索され、それらを目録化したタグファイルがカレントディレクトリに生成される。</para>
<para><command>hasktags</command>は単純なプログラムであり、関数や構築子や型の定義を見つけるのにも単純な規則を使っている。全てを見つけることは保証されていないし、存在しないものに対して項目を作ることもあるが、通常はかなりよく働く。特に、関数は、型シグネチャが与えられているときにのみ項目化される。</para>
<para>hasktagsの前、<command>fptags</command>と<command>hstags</command>があった。これらは基本的には同じことをするものだが、どちらももはや保守されていないようである。</para>
<sect2>
<title>エディタからタグを使う</title>
<para>NEditでは、「File/Load Tags File」で「tags」ファイルをロードし、「Ctrl-D」でタグを検索する。</para>
<para>XEmacsでは、「visit-tags-table」で「TAGS」ファイルをロードし、「M-.」でタグを検索する。</para>
</sect2>
</sect1>
-->
<!-- comment: hstags doesn't work anymore
<sect1 id="hstags">
<title>Emacs `TAGS' for Haskell: <command>hstags</command></title>
<indexterm><primary><command>hstags</command></primary></indexterm>
<indexterm><primary>TAGS for Haskell</primary></indexterm>
<para>`Tags' is a facility for indexing the definitions of
programming-language things in a multi-file program, and then
using that index to jump around among these definitions.</para>
<para>Rather than scratch your head, saying “Now where did
we define `foo'?”, you just do (in Emacs) <Literal>M-. foo
RET</Literal>, and You're There! Some people go wild over this
stuff…</para>
<para>GHC comes with a program <command>hstags</command>, which
build Emacs-able TAGS files. The invocation syntax is:</para>
<screen>
hstags [GHC-options] file [files...]
</screen>
<para>The best thing is just to feed it your GHC command-line
flags. A good Makefile entry might be:</para>
<programlisting>
tags:
$(RM) TAGS
hstags $(GHC_FLAGS) *.lhs
</programlisting>
<para>The only flags of its own are: <Option>-v</Option> to be
verbose; <Option>-a</Option> to <Emphasis>APPEND</Emphasis> to the
TAGS file, rather than write to it.</para>
<para>Shortcomings: (1) Instance declarations don't get into
the TAGS file (but the definitions inside them do); as instances
aren't named, this is probably just as well.
(2) Data-constructor definitions don't get in. Go for the
corresponding type constructor instead.</para>
<para>Actually, GHC also comes with <command>etags</command>
[for C], and <command>perltags</command> [for You
Know What]. And—I cannot tell a lie—there is
Denis Howe's <command>fptags</command> [for Haskell,
etc.] in the <Filename>ghc/CONTRIB</Filename>
section…)</para>
</sect1>
-->
<sect1 id="happy">
<title>“Haskell用Yacc”: <command>happy</command></title>
<indexterm><primary>Happy</primary></indexterm>
<indexterm><primary>Yacc for Haskell</primary></indexterm>
<indexterm><primary>parser generator for Haskell</primary></indexterm>
<para>Andy GillとSimon Marlowが<command>happy</command>呼ばれるHaskell用パーサジェネレータを書いた。<indexterm><primary>happy parser generator</primary></indexterm><command>happy</command>は、<command>Yacc</command>がCで行うことをHaskellで行うものである。</para>
<para><command>happy</command>は<ulink url="http://www.haskell.org/happy/">the Happy Homepage</ulink>で手に入る。</para>
<para><command>happy</command>はGHCでコンパイルされたときに最大の力を発揮する。</para>
</sect1>
<!-- we don't distribute this anymore
<sect1 id="pphs">
<title>Pretty-printing Haskell: <command>pphs</command></title>
<indexterm><primary>pphs</primary></indexterm>
<indexterm><primary>pretty-printing Haskell code</primary></indexterm>
<para>Andrew Preece has written
<command>pphs</command>,<indexterm><primary>pphs</primary></indexterm><indexterm><primary>pretty-printing
Haskell</primary></indexterm> a utility to pretty-print Haskell
code in LaTeX documents. Keywords in bolds, variables in
italics—that sort of thing. It is good at lining up program
clauses and equals signs, things that are very tiresome to do by
hand.</para>
<para>The code is distributed with GHC in
<Filename>ghc/CONTRIB/pphs</Filename>.</para>
</sect1>
-->
<sect1 id="hsc2hs">
<title>CコードへのHaskellインタフェースを書く: <command>hsc2hs</command></title>
<indexterm><primary><command>hsc2hs</command></primary>
</indexterm>
<para><command>hsc2hs</command>コマンドを使うと、CコードのHaskellバインディングを書く作業を一部自動化することができる。このコマンドは、特別な構文要素の埋め込まれたHaskellのコードを読み、Cのヘッダから得た情報を使ってこれらの要素を処理し、本当のHaskellファイルを出力する。この特別な構文要素は、CのデータをHaskellからアクセスするにあたって必要なことを扱う。</para>
<para><command>hsc2hs</command>はCファイルとCヘッダを出力することもある。Cファイルには、プログラムにリンクすべき追加のC関数が置かれ、ヘッダファイルは、そのHaskellモジュールがコンパイルされてできるCコードからincludeされるものである。この二つのファイルは<literal>#def</literal>という構文要素(下記参照)が使われたときに作られる。</para>
<para><command>hsc2hs</command>は実際には直接Haskellコードを出力するわけではない。問題のヘッダをインクルードするCプログラムを作り、自動的にコンパイル・実行する。このプログラムがHaskellコードを生成する。</para>
<para>以下では、「Haskellファイル」は主たる出力ファイル(通常<literal>.hs</literal>)であり、「Haskellファイルのコンパイル結果」は、<command>ghc</command>がHaskellファイルをコンパイルしてできたもの(<literal>.hc</literal>ファイル)であり、「Cプログラム」はHaskellファイルを出力するプログラムであり、「Cファイル」は場合によって出力されるCファイルであり、「Cヘッダ」はそのヘッダファイルである。</para>
<sect2>
<title>コマンド行構文</title>
<para><command>hsc2hs</command>は、引数として、入力ファイルと、振る舞いを変更するフラグを受け付ける。</para>
<variablelist>
<varlistentry>
<term><literal>-o FILE</literal>または<literal>––output=FILE</literal></term>
<listitem>
<para>Haskellファイルの名前。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>-t FILE</literal>または<literal>––template=FILE</literal></term>
<listitem>
<para>テンプレートファイル(下記参照)。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>-c PROG</literal>または<literal>––cc=PROG</literal></term>
<listitem>
<para>利用するCコンパイラ(デフォルト: <command>gcc</command>)。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>-l PROG</literal>または<literal>––ld=PROG</literal></term>
<listitem>
<para>利用するリンカ(デフォルト: <command>gcc</command>)。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>-C FLAG</literal>または<literal>––cflag=FLAG</literal></term>
<listitem>
<para>Cコンパイラに渡す追加のフラグ。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>-I DIR</literal></term>
<listitem>
<para>Cコンパイラに渡される。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>-L FLAG</literal>または<literal>––lflag=FLAG</literal></term>
<listitem>
<para>リンカに渡す追加のフラグ。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>-i FILE</literal>または<literal>––include=FILE</literal></term>
<listitem>
<para>適切な<literal>#include</literal>がソース中に置かれたのと同様。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>-D NAME[=VALUE]</literal>または<literal>––define=NAME[=VALUE]</literal></term>
<listitem>
<para>ソース中に適切な<literal>#define</literal>が置かれたのと同様。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>––no-compile</literal></term>
<listitem>
<para>中間のCプログラムをディスクに書き込んだ後停止する。中間Cファイルの名前は、入力ファイル名の<literal>.hsc</literal>を<literal>_hsc_make.c</literal>で置き換えたものである。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>-k</literal> or
<literal>––keep-files</literal></term>
<listitem>
<para>通常通りに進行するが、中間ファイルを全く削除しない。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>-x</literal> or
<literal>––cross-compile</literal></term>
<listitem>
<para>クロスコンパイルモードを起動する(<xref linkend="hsc2hs_cross"/>を見よ)。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>––cross-safe</literal></term>
<listitem>
<para>.hscディレクティブを、<literal>--cross-compile</literal>モード(<xref linkend="hsc2hs_cross"/>を見よ)が対応しているものに限定する。これは、安全にクロスコンパイルされねばならない<literal>.hsc</literal>ファイルがあって、クロスコンパイル不能な要素が忍び込むことがないようにしたい場合に便利なはずである。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>-?</literal>または<literal>––help</literal></term>
<listitem>
<para>利用可能なフラグの要約を表示し、成功裡に終了する。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>-V</literal>または<literal>––version</literal></term>
<listitem>
<para>バージョン情報を表示し、成功裡に終了する。</para>
</listitem>
</varlistentry>
</variablelist>
<para>入力ファイルは.hscで終わっていなければならない。(これは素のHaskellソースでなければならない。文芸Haskellは未対応である)。出力ファイルはデフォルトでは<literal>.hsc</literal>接尾辞を次のもので置き換えた名前になる。</para>
<informaltable>
<tgroup cols="2">
<tbody>
<row>
<entry><literal>.hs</literal></entry>
<entry>Haskellファイル</entry>
</row>
<row>
<entry><literal>_hsc.h</literal></entry>
<entry>Cヘッダ</entry>
</row>
<row>
<entry><literal>_hsc.c</literal></entry>
<entry>Cファイル</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<para>CプログラムはHaskellコンパイラでコンパイルされる。これにより、<filename>HsFFI.h</filename>が使える。これは、自動的にCプログラムにincludeされる。</para>
</sect2>
<sect2><title>入力の構文</title>
<para>特殊な処理は全て<literal>#</literal>演算子で起動される。<literal>#</literal>を文字どおり出力したい場合は、<literal>##</literal>と二回書けば良い。文字列リテラルおよびコメントの中の<literal>#</literal>は処理されない。</para>
<para><literal>#</literal>の後にはスペースやタブ(省略可能)が続き、その後に、アルファベットと数字からなる、処理の種類を示すキーワードが書かれ、その後に引数が置かれる。引数は、Cの式をコンマで区切ったような形をしている(括弧では囲まない)。引数が終わるのは、対応するもののない<literal>)</literal>、<literal>]</literal>、<literal>}</literal>が現れるか、行の終わりに達したとき(ただし、<literal>() [] {} '' "" /**/</literal>のいずれにも囲まれておらず、バックスラッシュが前置されてもいない場合に限る)である。バックスラッシュと改行の対は消される。</para>
<para>さらに、<literal>#{何か}</literal>は<literal>#何か</literal>と同様だが、終わりが明確なので、行の最後に置いたり括弧の中に置いたりする必要がない。</para>
<para>個々のキーワードの意味は次の通り。</para>
<variablelist>
<varlistentry>
<term><literal>#include <file.h></literal></term>
<term><literal>#include "file.h"</literal></term>
<listitem>
<para>指定されたファイルが、Cプログラム、Haskellプログラムのコンパイル結果、Cヘッダにそれぞれincludeされる。<literal><HsFFI.h></literal>は自動的にincludeされる。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>#define 名前</literal></term>
<term><literal>#define 名前 値</literal></term>
<term><literal>#undef 名前</literal></term>
<listitem>
<para><literal>#include</literal>に似ている。<literal>#include</literal>と<literal>#define</literal>は一つのファイルに二回置かれることがあることに注意。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>#let 名前 引数列 = "定義"</literal></term>
<listitem>
<para>Haskellソースに適用されるマクロを定義する。引数名はコンマで区切り、括弧では囲まない。このようなマクロは、<literal>#名前</literal>で始まる構文要素で起動される。この定義は、Cプログラムにおいて、括弧で囲んで<literal>printf</literal>の引数として使われる。引数を参照するには、引用符を閉じ、引数を置き、再び引用符を開くことでCの文字列リテラルの連結を利用する。あるいは<literal>printf</literal>の書式指定子を使っても良い。引数は、Cプリプロセッサの<literal>#引数</literal>記法を使って明示的に文字列化するのでない限り、文字列として渡されなければならない。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>#def Cの定義</literal></term>
<listitem>
<para>この定義(関数定義、変数定義、構造体定義、typedef)がCファイルに書かれ、そのプロトタイプかextern宣言がCヘッダに書かれる。インライン関数も正しく扱われる。構造体定義とtypedefはCプログラムにも書き込まれる。<literal>inline</literal>、<literal>struct</literal>、<literal>typedef</literal>の各キーワードは<literal>def</literal>の直後に来なければならない。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>#if 条件 </literal></term>
<term><literal>#ifdef 名前</literal></term>
<term><literal>#ifndef 名前</literal></term>
<term><literal>#elif 条件</literal></term>
<term><literal>#else</literal></term>
<term><literal>#endif</literal></term>
<term><literal>#error メッセージ</literal></term>
<term><literal>#warning メッセージ</literal></term>
<listitem>
<para>条件コンパイルディレクティブは、Cプログラム、Cファイル、Cヘッダに変更なしで渡される。Cプログラムにも置かれるので、Haskellファイルの適当な部分が飛ばされることになる。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>#const Cの式</literal></term>
<listitem>
<para>式は<literal>long</literal>または<literal>unsigned long</literal>に変換可能でなければならない。その値(リテラル、またはリテラルを符号反転したもの)が出力される。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>#const_str Cの式</literal></term>
<listitem>
<para>式はcharへの定数ポインタに変換可能でなければならない。その値(文字列リテラル)が出力される。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>#type Cの型</literal></term>
<listitem>
<para>Cの数値型に対応する、Haskellでの同等の型が出力される。これは、<literal>{Int,Word}{8,16,32,64}</literal>、<literal>Float</literal>、<literal>Double</literal>、<literal>LDouble</literal>のいずれかである。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>#peek 構造体型, フィールド</literal></term>
<listitem>
<para>Cの構造体のフィールドを読み出す関数が出力される。型は<literal>Storable b => Ptr a -> IO b</literal>である。<literal>#peek</literal>と<literal>#poke</literal>を使って、与えられたCの構造体についての<literal>Storable</literal>クラスの演算を定義できるようにする、という意図である。(ライブラリ説明書の<literal>Foreign.Storable</literal>参照)</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>#poke 構造体型, フィールド</literal></term>
<listitem>
<para>pokeについても同様。型は<literal>Storable b => Ptr a -> b -> IO ()</literal>になる。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>#ptr 構造体型, フィールド</literal></term>
<listitem>
<para>構造体のフィールドへのポインタを作る。型は<literal>Ptr a -> Ptr b</literal>になる。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>#offset 構造体型, フィールド</literal></term>
<listitem>
<para><literal>構造体型</literal>中での<literal>フィールド</literal>のオフセットをバイト単位で計算する。型は<literal>Int</literal>になる。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>#size 構造体型</literal></term>
<listitem>
<para><literal>構造体型</literal>の大きさを、バイト単位で計算する。型は<literal>Int</literal>になる。</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>#enum 型, 構築子, 値, 値, ...</literal></term>
<listitem>
<para><literal>#const</literal>を使った複数の定義の代替となる略記法。それぞれの<literal>値</literal>はCの整定数(例えば列挙値)の名前である。この名前は、アンダースコアの次の文字を大文字にし、それ以外を小文字にし、アンダースコアを取り去ることで、Haskellの名前として使われる。<literal>値</literal>と書く代わりに<literal>Haskellでの名前 = Cの値</literal>と書くことで、自分で変換を指定することができる。この場合、<literal>Cの値</literal>は任意の式であって良い。<literal>Haskellでの名前</literal>は、指定された<literal>型</literal>を持つものとして定義される。定義は、指定された<literal>構築子</literal>(実際には式でも良いし、空でも良い)を、適当な整数値に適用したものである。一つの<literal>型</literal>に対して複数の<literal>#enum</literal>定義があっても良い。この構文要素は型定義自体を出力するわけではないからである。</para>
</listitem>
</varlistentry>
</variablelist>
</sect2>
<sect2>
<title>自分で構文要素を用意する</title>
<para><literal>#const</literal>、<literal>#type</literal>、<literal>#peek</literal>、<literal>#poke</literal>、<literal>#ptr</literal>は<command>hsc2hs</command>と結びつけられておらず、CプログラムにincludeされるCテンプレートである<filename>template-hsc.h</filename>で定義されている。自分で構文要素やテンプレートを用意し、それを使うこともできる。<literal>#</literal>要素で、キーワードが未知であるものは、全てCテンプレートが対応するものとみなされる。</para>
<para>Cテンプレートでは、名前に<literal>hsc_</literal>を前置したマクロまたは関数を定義する。この関数は、構文要素を処理し、展開結果を標準出力に書き出す。例として<filename>template-hsc.h</filename>を参照せよ。</para>
<para>このようなマクロはソース中で直接定義することもできる。これは、<literal>#let</literal>マクロを使ったものに展開される<literal>#let</literal>風マクロを作るのに便利である。通常の<literal>#let</literal>では、マクロ名に<literal>hsc_</literal>を前置し、定義を<literal>printf</literal>の呼び出しで包む。</para>
</sect2>
<sect2 id="hsc2hs_cross">
<title>クロスコンパイル</title>
<para><command>hsc2hs</command>は通常、Cプログラムを作成し、コンパイルし、実行することで動作する。しかし、この方策はクロスコンパイルでは機能しない。この場合、Cコンパイラはホスト機械ではなくターゲット機械で走るコードを生成するからである。この状況のために、<command>hsc2hs --cross-compile</command>という特殊なモードがある。これは、コンパイルのみ(細かく言うと、コンパイルの成否)によって情報を抽出して.hsを生成することができる。
</para>
<para><literal>--cross-compile</literal>は、<literal>.hsc</literal>構文の一部にしか対応していない。以下のものは未対応である。
<itemizedlist>
<listitem><literal>#{const_str}</literal></listitem>
<listitem><literal>#{let}</literal></listitem>
<listitem><literal>#{def}</literal></listitem>
<listitem>自分で定義した構文要素</listitem>
</itemizedlist>
</para>
</sect2>
</sect1>
</chapter>
<!-- Emacs stuff:
;;; Local Variables: ***
;;; sgml-parent-document: ("users_guide.xml" "book" "chapter") ***
;;; End: ***
-->