[project @ 1997-03-14 08:02:40 by simonpj]
[nofib.git] / real / mkhprog / Main.lhs
1 % Mkhprog.lhs - Haskell equivalent of mkprog
2
3 % @(#)Mkhprog.lhs       2.4 dated 92/06/23 at 15:37:01
4
5 % Crown Copyright 1992
6
7 \documentstyle[a4wide]{article}
8
9 \title{Mkhprog --- a Command line Parser Generator}
10 \author{N D North\\
11         National Physical Laboratory\\
12         Teddington, TW11 0LW, UK.\\
13         {\tt ndn\@seg.npl.co.uk}}
14
15 % Some macros lifted from elsewhere to make this more standalone.
16 \makeatletter
17 % INLINE PROGRAM CODE
18 %
19 % \prog{foo} sets its argument in typewriter font.
20 \def\prog#1{\ifmmode\mbox{\tt #1}\else{\tt #1}\fi}
21
22 % NEWVERBATIM (from iso.sty)
23 %
24 % \newverbatim{foo} creates a new environment, foo, which behaves exactly
25 % like the verbatim environment except that it is delimited by
26 % \begin{foo} ... \end{foo}.
27 % See the VERBATIM section of latex.tex for the inspiration behind this.
28 %
29 \def\newverbatim#1{\expandafter\def\csname #1\endcsname{%
30 \\@verbatim \frenchspacing\\@vobeyspaces \csname \@x#1verbatim\endcsname}
31 \expandafter\let\csname end#1\endcsname=\endtrivlist
32 \new\@xverbatim{#1}}
33
34 \begingroup \catcode `|=0 \catcode `[= 1
35 \catcode`]=2 \catcode `\{=12 \catcode `\}=12
36 \catcode`\\=12
37 |gdef|new\@xverbatim#1[
38 |expandafter|def|csname \@x#1verbatim|endcsname##1\end{#1}[##1|end[#1]]]
39 |endgroup
40 \makeatother
41
42 \newverbatim{haskell}
43
44 \begin{document}
45 \maketitle
46
47 \section*{Introduction}
48
49 This document is the source code for, and description of, \prog{mkhprog} ---
50 a Haskell program which generates the skeleton of other Haskell programs.
51 In particular, it generates the code needed to parse values passed to a
52 program from the command line.
53
54 Given the command line flags and associated values to be interpreted by
55 a program, \prog{mkhprog} produces a module containing a \prog{main}
56 function which acquires the command line, parses any flags and values
57 present, and passes the values to the main body of the Haskell program
58 for further processing.
59
60 \prog{mkhprog} can produce standard or ``literate'' Haskell, it can
61 generate a module with any desired name, and it can send its output
62 to the standard output or to a named file.
63
64 The body of this document describes how to use \prog{mkhprog} and then
65 gives the code which implements it.
66 Annexes describe auxiliary functions, the continuation style of programming
67 used, and give hints and tips on compilation and general matters.
68
69 \section{\prog{mkhprog} in use}
70
71 \subsection{Installation}
72 \prog{mkhprog} is distributed as a literate Haskell file, \prog{Mkhprog.lhs},
73 and a UNIX manual page, \prog{mkhprog.1}.
74 \prog{Mkhprog.lhs} is also a \LaTeX\ source file which documents the program
75 and its usage.
76
77 To install \prog{mkhprog}, compile \prog{Mkhprog.lhs} (converting it to
78 standard Haskell first if necessary, as described in Annex~\ref{convert})
79 and place the binary somewhere accessible.
80 You may also want to put the manual page in your local manual directory.
81
82 \subsection{Flags}
83 We will first describe the command line parameters interpreted by
84 \prog{mkhprog} itself, and then show how it treats the remainder of its
85 command line.
86 The program interprets the following flags:
87 \begin{description}
88 \item[\prog{-l}] produces a ``literate'' Haskell script in which all lines of
89     code begin with the characters \prog{"> "}.
90     This file is an example of a literate Haskell script.
91 \item[\prog{-m} {\em module\_name}] writes a module called {\em module\_name}
92     rather than the default name of \prog{Main}.
93 \item[\prog{-o} {\em file\_name}] writes output to {\em file\_name} rather than
94     the default of standard output.
95 \end{description}
96 The first command line flag which is not a member of the above set marks
97 the beginning of the flags to be interpreted by the generated program, which
98 we will now describe.
99
100 Programs generated by \prog{mkhprog} can interpret command line flags and
101 associated values of any Haskell type of class \prog{Text}.
102 To generate a program which interprets a flag \prog{-f} and a value of
103 type \prog{Foo}, we invoke \prog{mkhprog} as
104 \begin{verbatim}
105 mkhprog -f Foo
106 \end{verbatim}
107 We may then invoke the generated program as
108 \begin{verbatim}
109 prog -f "MkFoo 3 True"
110 \end{verbatim}
111 if \prog{MkFoo 3 True} is a valid item of type \prog{Foo} and \prog{Foo}
112 is an instance of the class \prog{Text}.
113
114 If the type associated with the flag is either \prog{Bool} or \prog{String}
115 then the generated program behaves in a special manner as follows:
116 \begin{description}
117 \item[\prog{Bool}] the program interprets the flag without any following
118 value, i.e. a program generated by
119 \begin{verbatim}
120 mkhprog -b Bool 
121 \end{verbatim}
122 is invoked simply as
123 \begin{verbatim}
124 prog -b 
125 \end{verbatim}
126 with no \prog{True} or \prog{False}.
127
128 You can produce programs which interpret a Boolean flag as a toggle
129 by invoking \prog{mkhprog} as:
130 \begin{verbatim}
131 mkhprog +b Bool 
132 \end{verbatim}
133 The generated program may then be called with either \prog{-b} or
134 \prog{+b} to set an internal value to \prog{False} or \prog{True}
135 respectively.
136
137 Boolean flags default to \prog{False}.
138
139 \item[\prog{String}] the program interprets the flag followed by an unquoted
140 string, i.e.
141 \begin{verbatim}
142 mkhprog -s String 
143 \end{verbatim}
144 generates a program which is invoked as
145 \begin{verbatim}
146 prog -s string 
147 \end{verbatim}
148 rather than
149 \begin{verbatim}
150 prog -s \"string\" 
151 \end{verbatim}
152 String flags default to \prog{""} (the empty string).
153 \end{description}
154
155 \subsection{Output}
156 This section shows the output from \prog{mkhprog} and the editing needed
157 to produce a compilable program from it.
158 If \prog{mkhprog} is invoked as
159 \begin{verbatim}
160 mkhprog -b Bool -s String -f Foo
161 \end{verbatim}
162 then the following output is produced:
163 \begin{verbatim}
164 module Main (main) where
165
166 import System (getArgs)
167
168 defaultArgs :: Args
169 defaultArgs  =  MkArgs False "" ??
170
171 usage :: IO ()
172 usage  =  print "Usage: prog [-b] [-s String] [-f Foo]"
173
174 data Args  =  MkArgs Bool String Foo deriving ()
175
176 parse_args :: Args -> String -> IO ()
177 parse_args (MkArgs x1 x2 x3) ('-':'b':rest)
178     =  readbool (parse_args (MkArgs True x2 x3)) rest
179 parse_args (MkArgs x1 x2 x3) ('-':'s':rest)
180     =  readstring (\str -> parse_args (MkArgs x1 str x3)) rest
181 parse_args (MkArgs x1 x2 x3) ('-':'f':rest)
182     =  readval reads (\val -> parse_args (MkArgs x1 x2 val)) rest
183 parse_args (MkArgs x1 x2 x3) ('-': _ :rest)
184     =  usage
185 parse_args (MkArgs x1 x2 x3)  rest  =  prog x1 x2 x3 (lines rest)
186
187 main :: IO ()
188 main  = do
189    argv <- getArgs
190    parse_args defaultArgs (unlines argv)
191
192 and auxiliary functions ...
193 \end{verbatim}
194 The first line simply gives the module header and says that \prog{main}
195 is being exported.
196 If \prog{mkhprog} had been invoked with the \prog{-m} flag, then the
197 module name would have been different.
198
199 Next comes the default value of the command line arguments.
200 This is near the beginning as the user will probably want to edit it.
201 Boolean flags default to \prog{False}, strings to the empty string and
202 anything else to \prog{??}.
203 The user will need to edit \prog{??} to a sensible value before
204 compilation.
205
206 The function \prog{usage} is also near the beginning as it too will
207 probably need editing.
208 This function is called in case of the command line flags being invalid
209 and writes to the standard error a template for how to call the generated
210 program.
211
212 The later parts of the program should not need editing and consist of:
213 \begin{itemize}
214 \item A declaration of the \prog{Args} data type, which is used to
215     carry information about command line flags.
216 \item The definition of \prog{parse\_args} which parses command line
217     flags and associated values, gives an error message on unrecognised
218     flags, and calls \prog{prog} when it hits a non-flag command line
219     argument.
220     \prog{prog} is then called with the values associated with the command
221     line flags (or the default if the flag was not present) and any
222     remaining command line arguments, split into a list of strings, one
223     per argument.
224 \item The definition of \prog{main}, which just acquires the command line,
225     puts it into a processable form,
226     and passes it to \prog{parse\_args}, with \prog{defaultArgs}.
227 \item Auxiliary functions for reading Booleans, strings and arbitrary
228     values from the command line arguments.
229     These are given in Annex~\ref{auxfns}.
230 \end{itemize}
231
232 \subsection{Compilation}
233 Before compilation, the user must perform a few tasks:
234 \begin{itemize}
235 \item Edit any instances of \prog{??} in the declaration of \prog{defaultArgs}
236     to sensible values.
237 \item Provide a definition of \prog{prog} to be called from
238     \prog{parse\_args}.
239 \item Ensure that any user-defined data types associated with flags are in
240     scope and are instances of the class \prog{Text}.
241 \end{itemize}
242 The user may also want to edit the definition of \prog{usage} to give a
243 more informative error message, though this is not essential.
244
245 After these changes, the program is ready for compilation.
246 The generated program is standard Haskell (version 1.1 or later)
247 and will compile on any
248 conforming implementation; some compilers have quirks which prevent
249 straightforward compilation, which are documented in Annex~\ref{quirks}.
250
251 \section{Command line parsing}
252
253 The functions which parse the command line are very similar to
254 those generated by \prog{mkhprog} itself.
255 Indeed they are edited from \prog{mkhprog} output.
256
257 The program starts with a module header which just exports \prog{main}.
258 \begin{haskell}
259
260 > module Main (main) where
261
262 > import System (getArgs)
263
264 \end{haskell}
265
266 The \prog{main} function acquires the command line arguments and passes
267 them to \prog{parse\_args}, together with their default values, encapsulated
268 in \prog{defaultEnv} (see Annex~\ref{env} for a description of the
269 environment).
270 \begin{haskell}
271
272 > main :: IO ()
273 > main  =  do
274 >  argv <- getArgs 
275 >  parse_args defaultEnv (unlines argv)
276
277 \end{haskell}
278
279 \prog{parse\_args e str} reads occurrences of \prog{-l}, \prog{-m} and
280 \prog{-o}, with any associated values, from \prog{str}, modifies the
281 environment \prog{e} appropriately and then passes the remainder of
282 the command line and the modified environment to \prog{next}.
283 \begin{haskell}
284
285 > parse_args :: Env -> String -> IO ()
286 > parse_args (MkEnv x1 x2 x3) ('-':'l':rest)
287 >     =  readbool (parse_args (MkEnv True x2 x3)) rest
288 > parse_args (MkEnv x1 x2 x3) ('-':'m':rest)
289 >     =  readstring (\str -> parse_args (MkEnv x1 str x3)) rest
290 > parse_args (MkEnv x1 x2 x3) ('-':'o':rest)
291 >     =  readstring (\str -> parse_args (MkEnv x1 x2 (File str))) rest
292 > parse_args e rest  =  next (pairs (lines rest)) e
293
294 \end{haskell}
295
296 \prog{pairs} splits a list of strings into a list of pairs of
297 strings.
298 If the length of its argument is odd, it adds a dummy empty string,
299 which will cause an error to be flagged by \prog{next}.
300 \begin{haskell}
301
302 > pairs :: [String] -> [(String, String)]
303 > pairs []         =  []
304 > pairs (s:s':ss)  =  (s,s') : pairs ss
305 > pairs [s]        =  [("",s)]
306
307 \end{haskell}
308
309 \prog{next sps} checks whether the list of pairs of strings, \prog{sps},
310 forms valid command line input to \prog{mkhprog}.
311 If not, a message is printed and the program halts; otherwise \prog{mkprog}
312 is called to generate the program.
313 \begin{haskell}
314
315 > next :: [(String, String)] -> Cont
316 > next sps e | check sps  =  mkprog sps e
317 >            | otherwise  =  usage
318
319 \end{haskell}
320
321 \prog{check sps} checks whether the list of pairs of strings, \prog{sps},
322 forms valid command line input to \prog{mkhprog}.
323 This consists of checking that
324 each flag is of the form \prog{-c}, or is of the form \prog{+c}
325 with associated type \prog{Bool}, where \prog{c} is a character
326 and that none of the characters are duplicated.
327 \begin{haskell}
328
329 > check :: [(String, String)] -> Bool
330 > check sps  =  flags_ok sps && no_dups [flag | (_:flag:_,_) <- sps]
331 >               where
332 >               flags_ok  =  and . map f
333 >               f (['-',_],_)       =  True
334 >               f (['+',_],"Bool")  =  True
335 >               f _                 =  False
336 >               no_dups []      =  True
337 >               no_dups (c:cs)  =  not (c `elem` cs) && no_dups cs
338
339 \end{haskell}
340
341 \prog{usage} prints a message saying how \prog{mkhprog} should be used.
342 \begin{haskell}
343
344 > usage :: IO ()
345 > usage = 
346 >     putStr
347 >      "Usage: mkhprog [-l] [-m module_name] [-o file_name] [[-flag type] ...]"
348
349 \end{haskell}
350
351 \prog{mkprog sps} generates and writes the program by calling a series of
352 functions, each generating one part.
353 \begin{haskell}
354
355 > mkprog :: [(String, String)] -> Cont
356 > mkprog sps
357 >     =  (do_header . nl . do_default types . nl . do_usage sps . nl
358 >         . do_datadecl types . nl . do_parse_args sps . nl . do_auxfns)
359 >        stop
360 >        where
361 >        types  =  map snd sps
362
363 \end{haskell}
364
365 \prog{do\_header} writes out the module header.
366 \begin{haskell}
367
368 > do_header :: Cont -> Cont
369 > do_header c
370 >     =  modname (\s -> writeln ("module " ++ s ++ " (main) where\n\nimport System (getArgs)") c)
371
372 \end{haskell}
373
374 \prog{do\_default ts} writes a declaration for the default value of the
375 command line argument types, \prog{ts}.
376 \prog{String}s default to the empty string; Booleans default to \prog{False};
377 all other types default to \prog{??}, which must be edited to a sensible
378 value by the user.
379 \begin{haskell}
380
381 > do_default :: [String] -> Cont -> Cont
382 > do_default ts
383 >     =  writeln "defaultArgs :: Args"
384 >        . writeln ("defaultArgs  =  MkArgs" ++ concat (map f ts))
385 >        where
386 >        f "String"  =  " \"\""
387 >        f "Bool"    =  " False"
388 >        f _         =  " ??"
389
390 \end{haskell}
391
392 \prog{do\_usage sps} writes a usage function, which is called if the
393 command line arguments are invalid.
394 \begin{haskell}
395
396 > do_usage :: [(String, String)] -> Cont -> Cont
397 > do_usage sps
398 >     =  writeln "usage :: IO ()"
399 >        . writeln ("usage  =  hPutStr stderr \"Usage: prog"
400 >                   ++ concat (map f sps) ++ "\"")
401 >        where
402 >        f (['-',c], "Bool")  =  " [-" ++ [c] ++ "]"
403 >        f (['+',c], "Bool")  =  " [(+|-)" ++ [c] ++ "]"
404 >        f (flag, typ)        =  " [" ++ flag ++ " " ++ typ ++ "]"
405
406 \end{haskell}
407
408 \prog{do\_datadecl ts} declares the type \prog{Args} to be made up of the
409 types \prog{ts}.
410 \begin{haskell}
411
412 > do_datadecl :: [String] -> Cont -> Cont
413 > do_datadecl ts
414 >     =  writeln ("data Args  =  MkArgs" ++ concat (map ((:) ' ') ts)
415 >                 ++ " deriving ()")
416
417 \end{haskell}
418
419 \prog{do\_parse\_args sps} writes the function which parses command line
420 arguments.
421 It applies \prog{do\_one\_flag} to each element of \prog{sps} and then
422 writes a final couple of clauses which catch invalid flags and call the
423 main program, \prog{prog}.
424 \begin{haskell}
425
426 > do_parse_args :: [(String, String)] -> Cont -> Cont
427 > do_parse_args sps
428 >     =  writeln "parse_args :: Args -> String -> IO ()"
429 >        . foldr (.) end
430 >        (zipWith3 do_one_flag (repeat n) [1..] sps)
431 >        where
432 >        n  =  length sps
433 >        end  =  writeln (phead n ++ wildmatch '-' ++ "usage")
434 >                . writeln (phead n ++ " rest  =  prog" ++ args 1 n
435 >                           ++ " (lines rest)")
436 >                
437
438 \end{haskell}
439
440 \prog{do\_one\_flag n r sp} writes one clause of the function which
441 parses command line arguments.
442 \prog{n} is the arity of \prog{MkArgs}, \prog{r} is the number of the current
443 argument, \prog{sp} is a pair of the flag and its type (as strings).
444 \begin{haskell}
445
446 > do_one_flag :: Int -> Int -> (String, String) -> Cont -> Cont
447 > do_one_flag n r (['+',flag], _)
448 >     =  writeln (phead n ++ match '-' flag ++ do_readbool n r False)
449 >        . writeln (phead n ++ match '+' flag ++ do_readbool n r True)
450 > do_one_flag n r (['-',flag], "Bool")
451 >     =  writeln (phead n ++ match '-' flag ++ do_readbool n r True)
452 > do_one_flag n r (['-',flag], "String")
453 >     =  writeln (phead n ++ match '-' flag ++ do_readstring n r)
454 > do_one_flag n r (['-',flag], _)
455 >     =  writeln (phead n ++ match '-' flag ++ do_readval n r)
456
457 \end{haskell}
458
459 \prog{do\_auxfns} writes out the functions used by \prog{mkhprog} which
460 do not change from program to program.
461 The functions are described in Annex~\ref{auxfns}
462 \begin{haskell}
463
464 > do_auxfns :: Cont -> Cont
465 > do_auxfns
466 >     =    writeln "main :: IO ()\n\
467 >                  \main  =  getArgs >>= (parse_args defaultArgs . unlines)"
468 >        . nl
469 >        . writeln "readbool :: (String -> IO ()) -> String -> IO ()\n\
470 >                  \readbool f \"\"         =  f \"\"\n\
471 >                  \readbool f ('\\n':cs)  =  f cs\n\
472 >                  \readbool f _          =  usage"
473 >        . nl
474 >        . writeln "readstring :: (String -> String -> IO ()) -> String \
475 >                                \-> IO ()\n\
476 >                  \readstring f \"\"  =  f \"\" \"\"\n\
477 >                  \readstring f cs@(c:cs')\n\
478 >                  \    =  f s t\n\
479 >                  \       where\n\
480 >                  \       st      =  if c == '\\n' then cs' else cs\n\
481 >                  \       (s,t1)  =  span ((/=) '\\n') st\n\
482 >                  \       t       =  if t1 == \"\" then t1 else (tail t1)"
483 >        . nl
484 >        . writeln "readval :: (Read a) => ReadS a \
485 >                             \-> (a -> String -> IO ()) -> String\n\
486 >                  \                       -> IO ()\n\
487 >                  \readval readsfn f str\n\
488 >                  \    =  case thing of\n\
489 >                  \           []    -> usage\n\
490 >                  \           (_:_) -> f val (if str' == \"\" \
491 >                                             \then str' else (tail str'))\n\
492 >                  \       where\n\
493 >                  \       thing        =  readsfn str\n\
494 >                  \       (val, str')  =  head thing"
495
496 \end{haskell}
497
498 \prog{phead n} returns the first part of the \prog{parse\_args} function,
499 where \prog{n} is the arity of \prog{MkArgs}.
500 \begin{haskell}
501
502 > phead :: Int -> String
503 > phead n  =  "parse_args (MkArgs" ++ args 1 n ++ ") "
504
505 \end{haskell}
506
507 \prog{args a b} gives a sequence of argument name strings,
508 \prog{xa}, $\ldots$, \prog{xb}, separated by spaces.
509 \begin{haskell}
510
511 > args :: Int -> Int -> String
512 > args a b  =  concat [" x" ++ show r | r <- [a..b]]
513
514 \end{haskell}
515
516 \prog{match mp c} returns a pattern which matches against \prog{-c}
517 or \prog{+c} as \prog{mp} is \prog{'-'} or \prog{'+'}.
518 \begin{haskell}
519
520 > match :: Char -> Char -> String
521 > match mp c  =  "('" ++ [mp] ++ "':'" ++ [c] ++ "':rest)\n    =  "
522
523 \end{haskell}
524
525 \prog{wildmatch mp} returns a pattern which matches against \prog{-c}
526 or \prog{+c}, where \prog{c} is any character at all, as \prog{mp} is
527 \prog{'-'} or \prog{'+'}.
528 \begin{haskell}
529
530 > wildmatch :: Char -> String
531 > wildmatch mp  =  "('" ++ [mp] ++ "': _ :rest)\n    =  "
532
533 \end{haskell}
534
535 \prog{do\_readval}, \prog{do\_readstring} and \prog{do\_readbool} produce
536 pieces of code for reading arbitrary values, strings and booleans
537 respectively.
538 \begin{haskell}
539
540 > do_readval, do_readstring :: Int -> Int -> String
541 > do_readbool   :: Int -> Int -> Bool -> String
542 > do_readval n r     =  "readval reads (\\val -> " ++ bits n r "val"
543 > do_readstring n r  =  "readstring (\\str -> " ++ bits n r "str"
544 > do_readbool n r b  =  "readbool (" ++ bits n r (show b)
545
546 \end{haskell}
547
548 \prog{bits n r str} produces a handy part of \prog{parse\_args}.
549 \begin{haskell}
550
551 > bits :: Int -> Int -> String -> String
552 > bits n r str
553 >     =  "parse_args (MkArgs" ++ args 1 (r-1) ++ " " ++ str ++ args (r+1) n
554 >        ++ ")) rest"
555
556 \end{haskell}
557
558 \prog{writeln str} writes the string \prog{str} to the chosen
559 output channel, in  literate format if appropriate,
560 and then executes its continuation, \prog{c}.
561 \prog{nl} gives a newline on the standard output.
562 \begin{haskell}
563
564 > writeln :: String -> Cont -> Cont
565 > writeln str c
566 >     =  islit (\b ->
567 >        output (\f env ->
568 >            let
569 >              str'   =  (if b then (lit str) else str) ++ "\n"
570 >              lit s  =  "> " ++ foldr ((++) . conv) "" s
571 >              conv '\n'  =  "\n> "
572 >              conv c     =  [c]
573 >            in
574 >               f str' >> c env))
575
576 > nl :: Cont -> Cont
577 > nl c = output (\f env -> f "\n" >> c env)
578
579 \end{haskell}
580
581 \section{Miscellaneous}
582
583 \subsection{Bugs, comments and suggestions}
584 \prog{mkhprog} was written to implement one person's view of what a
585 skeleton Haskell program should look like.
586 It is by no means obvious that this is the best solution and any
587 suggestions for improvements are welcome.
588 Please send your bug reports, comments and suggestions to
589 \prog{ndn\@seg.npl.co.uk}.
590
591 \subsection{Acknowledgements}
592 \prog{mkhprog}'s functionality and manual page are closely based on those
593 of the C program \prog{mkprog}, whose author is unknown to me so I cannot
594 thank him or her in person.
595
596 Thanks also to the various implementers of Haskell around the world who
597 have borne with my continual bug reports and naive questions.
598 Thanks in particular to Will Partain who supplied useful patches to keep
599 \prog{mkhprog} in line with the changing definition of Haskell.
600
601 \appendix
602 \newpage
603 \section{Auxiliary functions}
604 \label{auxfns}
605
606 These are the functions produced by \prog{do\_auxfns}, which are used
607 by all programs written by \prog{mkhprog}.
608
609 \prog{readbool f str} checks that a Boolean flag is followed by either
610 newline or nothing: if it is, then \prog{f} is applied to the rest of
611 the string \prog{str}; if not, \prog{usage} is called.
612 \begin{haskell}
613
614 > readbool :: (String -> IO ()) -> String -> IO ()
615 > readbool f ""         =  f ""
616 > readbool f ('\n':cs)  =  f cs
617 > readbool f _          =  usage
618
619 \end{haskell}
620
621 \prog{readstring f str} reads a string, \prog{s}, from \prog{str} as follows:
622 \begin{itemize}
623 \item[] If \prog{str} begins with \verb|'\n'|, then \prog{s} is the
624     sequence of characters following the newline, up to the next newline
625     or the end of \prog{str}, whichever occurs first.
626 \item[] Otherwise \prog{s} is the initial substring of \prog{str}, up to
627     the first newline or the end of \prog{str}, whichever occurs first.
628 \end{itemize}
629 \prog{f} is then applied to \prog{s} and \prog{t}, where \prog{t} is the
630 remainder of \prog{str} after removing \prog{s} and a newline character, if
631 \prog{s} is followed by one.
632 \begin{haskell}
633
634 > readstring :: (String -> String -> IO ()) -> String -> IO ()
635 > readstring f ""  =  f "" ""
636 > readstring f cs@(c:cs')
637 >       =  f s t
638 >          where
639 >          st      =  if c == '\n' then cs' else cs
640 >          (s,t1)  =  span ((/=) '\n') st
641 >          t       =  if t1 == "" then t1 else (tail t1)
642
643 \end{haskell}
644
645 \prog{readval readsfn f str} reads a value from \prog{str} in the same manner
646 as \prog{readstring}, but the value can be of any type of class \prog{Text}.
647 The parameter \prog{readsfn} is the appropriate overloading of \prog{reads}
648 --- this parameter is not essential but, without it, \prog{readval} is
649 reliant on the ``monomorphic restriction'', whose future presence in
650 Haskell is not guaranteed.
651 \prog{f} is applied to the value and the remainder of \prog{str} as in
652 \prog{readstring}, but if no value can be read, \prog{usage} is called.
653
654 Since \prog{mkhprog} does not itself use \prog{readval}, its code does
655 not form part of this literate Haskell script.
656 \begin{verbatim}
657
658 readval :: (Read a) => ReadS a -> (a -> String -> IO ()) -> String
659                        -> IO ()
660 readval readsfn f str
661     =  case thing of
662            []    -> usage
663            (_:_) -> f val (if str' == "" then str' else (tail str'))
664        where
665        thing        =  readsfn str
666        (val, str')  =  head thing
667
668 \end{verbatim}
669
670 \section{Continuations and environments}
671
672 \subsection{Continuations}
673 \prog{mkhprog} is written in the continuation style, in which functions take
674 a continuation argument which tells the program ``what to do next''.
675 A continuation is a function which takes an environment parameter and gives
676 the rest of the program's output.
677 Thus we may define a data type for continuations thus:
678 \begin{haskell}
679
680 > type Cont  =  Env -> IO ()
681
682 \end{haskell}
683
684 The null continuation, which does nothing, is
685 \begin{haskell}
686
687 > stop :: Cont
688 > stop e  =  return ()
689
690 \end{haskell}
691
692 \subsection{Environments}
693 \label{env}
694 An environment contains all the information needed to generate the output
695 program, viz.
696 \begin{enumerate}
697 \item Whether it is a literate program.
698 \item The name of the module to be generated.
699 \item Whether output is to \prog{stdout} or to a file and, if the latter,
700     the file's name.
701 \end{enumerate}
702 We may encompass this information in an environment data type:
703 \begin{haskell}
704
705 > data Env  =  MkEnv Bool String Output
706
707 \end{haskell}
708 Where the \prog{Bool} component is \prog{True} or \prog{False} as the
709 program is literate or not, the \prog{String} component is the module
710 name, and the \prog{Output} component gives details of the output stream
711 as follows:
712 \begin{haskell}
713
714 > data Output  =  Stdout | File String
715
716 \end{haskell}
717
718 The value of the environment is determined by the command line flags to
719 \prog{mkhprog}.
720 The default environment is
721 \begin{haskell}
722
723 > defaultEnv :: Env
724 > defaultEnv  =  MkEnv False "Main" Stdout
725
726 \end{haskell}
727
728 \subsection{Environment access}
729 Functions which need to access the environment use the
730 access functions in this section.
731
732 \prog{islit bc} applies \prog{bc} to the value of the Boolean
733 environment component.
734 \begin{haskell}
735
736 > islit :: (Bool -> Cont) -> Cont
737 > islit bc e@(MkEnv l _ _)  =  bc l e
738
739 \end{haskell}
740
741 \prog{modname sc} applies \prog{sc} to the string environment
742 component.
743 \begin{haskell}
744
745 > modname :: (String -> Cont) -> Cont
746 > modname sc e@(MkEnv _ m _)  =  sc m e
747
748 \end{haskell}
749
750 \prog{output oc} applies \prog{oc} to a function which writes its
751 argument to the output channel given by the \prog{Output} environment
752 component.
753 \begin{haskell}
754
755 > output :: ((String -> IO ()) -> Cont) -> Cont
756 > output oc e@(MkEnv _ _ Stdout)    =  oc (putStr) e
757 > output oc e@(MkEnv _ _ (File f))  =  oc (appendFile f) e
758
759 \end{haskell}
760
761 \section{Hints and tips}
762
763 \subsection{Compilation}
764 \label{quirks}
765 This section summarises the compilability of \prog{mkhprog} on the
766 compilers available at the time of writing (92/06/23).
767 \begin{description}
768 \item[Glasgow Prototype 0.41] Supports Haskell version 1.0, so
769     cannot compile this file.
770     Contact me if you want a version of \prog{mkhprog} that compiles under
771     Haskell version 1.0.
772 \item[Chalmers Haskell B 0.997.5] This file (\prog{Mkhprog.lhs}) compiles and
773     runs with no problems.
774     Command line parameters to \prog{mkhprog} and the programs it generates
775     must follow an isolated \prog{-},
776     as others are interpreted by the run-time system (see the documentation).
777 \item[Yale 1.0-0] The Yale system does not support \prog{getArgs} so
778     \prog{mkhprog} and the programs it generates are entirely useless on
779     this system.
780 \end{description}
781
782 \subsection{Extracting a standard Haskell program}
783 \label{convert}
784 \prog{mkhprog} is distributed as a literate Haskell script.
785 If your compiler is unable to compile such scripts, you should type
786 the following UNIX command line (assuming this file is called
787 \prog{Mkhprog.lhs}):
788 \begin{verbatim}
789 expand Mkhprog.lhs | sed -e "/^> /\!d" -e "s/^> //" > Mkhprog.hs
790 \end{verbatim}
791 The output file \prog{Mkhprog.hs} is then standard Haskell and can be
792 compiled in the normal way.
793
794 \subsection{Things with literate Haskell}
795 Those, like myself, who like their literate Haskell surrounded by a
796 \LaTeX\ environment may care to use something like this:
797 \begin{verbatim}
798 mkhprog -l <flags> | perl -pe 's/^$/\n\\end{haskell}\n\\begin{haskell}\n/' > Foo.hs
799 \end{verbatim}
800 The file \prog{Foo.hs} will then have its declarations placed within a
801 \LaTeX\ environment called \prog{haskell}.
802
803 \end{document}