diff --git a/haskell98-bugs.html b/haskell98-bugs.html index 393f723da9c1a07915e42412f8d86ceb780f2756..25c92a9c8b5363c767a9a9e7ba912d9e3105de65 100644 --- a/haskell98-bugs.html +++ b/haskell98-bugs.html @@ -89,6 +89,24 @@ Add <em>dashes</em> to <em>reservedop</em> in the exclusion set of the production for <em>varsym</em>. (This ensures that "<tt>--</tt>" and "<tt>---</tt>" are not legal lexemes. +<p><li> [Nov 2001] <strong>Page 7, Section 2.4, Identifiers and operators; and Appendix B.2, p121.</strong> +<ul> +<li> Remove the productions for <em>specialid</em> and <em>specialop</em> +<li> Delete the paragraph about specialid and specialop near the bottom of page 7 +("A few identifiers and operators.."). +</ul> + +<p><li> [Nov 2001] <strong>Page 8, Section 2.5, Numeric literals; and Appendix B.2, p121.</strong> +Replace the production for "float" with: +<pre> + float -> decimal . decimal [exponent] + | decimal exponent + exponent -> (e | E) [+ | -] decimal +</pre> +(This change means that 20e3 is a floating-point literal. There is a corresponding change +to the lexer on p114.) + + <p><li> <strong>Page 9, Section 2.4, Identifiers and operators; and Page 68, Section 5.5.1, Qualified names.</strong> Move the first paragraph of 5.5.1, and the following table, and the paragraph starting "The qualifier does not change...", to the end of Section 2.4. (These paragraphs deal with lexical matters, which do not belong in Chapter 5.) @@ -145,6 +163,10 @@ comprehension is used." Remove Table 1, and the associated paragraph beginning "As an aid to understanding...". (The table causes more confusion than it clears up.) +<p><li> [Nov 2001] <strong>Page 13, Section 3 Expressions.</strong> +Replace the curly braces by angle brackets, in the subscript of "aexp" in the last production of "aexp". +Similarly, on Page 26, Section 3.15.3; and Page 128, Appendix B.4. + <p><li> [Apr 2001] <strong>Page 14, Section 3.1, Errors.</strong> In the first sentence of the section, after "indistinguishable" add "by a Haskell program". @@ -260,6 +282,13 @@ At the end of the subsection, add a new paragraph: "The pattern "<tt>F {}</tt>" matches any value built with constructor <tt>F</tt>, <em>whether or not <tt>F</tt> was declared with record syntax</em>." +<p><li> [Nov 2001] <strong>Page 41, Section 4.2.1, subsection Strictness Flags.</strong> +Add the following sentence at the end of the pargraph: +<p> +"Lexically, "<tt>!</tt>" is an ordinary varsym not a reservedop; +it has special significance only in the context of the argument types of +a data declaration." + <p><li> [Apr 2001] <strong>Page 42, Section 4.2.1, subsection Labelled Fields.</strong> Change "occurance" to "occurrence" in the translation box at the very end of the section. @@ -391,6 +420,14 @@ between <tt>C.g</tt> and <tt>g</tt>, and between <tt>module B</tt> and <tt>C.f</tt> (assuming <tt>B.f</tt> and <tt>C.f</tt> are different entities), even though there are no name clashes within module <tt>A</tt> itself. +<p><li> [Nov 2001] <strong>Page 65, Section 5.3, Import Declarations, last line.</strong> +Before "Exactly which entities are to be imported..." add a new paragraph: +<p> +"Lexically speaking, the terminal symbols "<tt>as</tt>", "<tt>qualified</tt>" and +"<tt>hiding</tt>" are each a "varid" rather than a "reservedid". They have +special significance only in the context of an <tt>import</tt> declaration; +they may also be used as variables." + <p><li> [July 2001] <strong>Page 65, Section 5.3, Import Declarations, last line.</strong> Start a new subsection "5.3.1 What is imported" before "Exactly which entities are to be imported...". @@ -453,6 +490,15 @@ However, the unqualified name "<tt>sin</tt>" in the type signature in the first line of <tt>F</tt> unambiguously refers to the local declaration for <tt>sin</tt>." +<p><li> [Nov 2001] <strong>Page 71, Section 5.6.1, The Prelude module.</strong> +Replace the entire first paragraph of the section with: +<p> +"The <tt>Prelude</tt> module is imported automatically into all modules as if +by the statement `<tt>import Prelude</tt>', if and only if it is not imported +with an explicit <tt>import</tt> declaration. This provision for explicit +import allows entities defined in the Prelude to be selectively imported, +just like those from any other module." + <p><li> <strong>Page 71, Section 5.6.2, Shadowing Prelude Names.</strong> Replace the example at the beginning of the section, and the entire following paragraph, with the following @@ -472,6 +518,16 @@ reference to <tt>null</tt> must also resolve the ambiguous use of <tt>null</tt> just as <tt>A</tt> does. Thus there is little danger of accidentally shadowing Prelude names." +<p><li> [Nov 2001] <strong>Page 73, Section 6.1.2, Characters and strings.</strong> +Replace the first sentence to read: +<p> +"The character type <tt>Char</tt> is an enumeration whose values represent +Unicode characters." +<p> +(This change withdraws the specification that Chars are 16 bits. According to the Unicode +experts, the rest of the Report is gloriously vague wrt to Unicode, and fixing to 16 bits +here is inappropriate precision.) + <p><li> [Aug 2001] <strong>Page 74, Section 6.1.3, Lists.</strong> In the last sentence, after "<tt>Monad</tt>" add ", <tt>Functor</tt>". (The list type is an instance of <tt>Functor</tt>.) @@ -658,6 +714,17 @@ Replace the definitions of <tt>take</tt>, <tt>drop</tt>, and <tt>splitAt</tt> wi The effect is that all three functions are defined on negative arguments. This is a semantic change. +<p><li> [Nov 2001] <strong>Page 114, definition of lex</strong>. +Change the line that currently reads +<pre> + lexFracExp s = [("",s)] +</pre> +to read instead +<pre> + lexFracExp s = lexExp s +</pre> +(This change allows 10e3 to be a single lexeme; c.f. the lexical change on page 7.) + <p><li> [May 2001; showsPrec corrected Sept 2001] <strong>Page 115, instances <tt>Show Int</tt> and <tt>Read Int</tt></strong>. Replace the instances for <tt>Show Int</tt> and <tt>Read Int</tt> with @@ -674,6 +741,21 @@ Replace the instances for <tt>Show Int</tt> and <tt>Read Int</tt> with </pre> The previous definitions (which are simply specifications, remember) failed on minInt. +<p><li> [Nov 2001] <strong>Page 122, Appendix B.3, Layout</strong>. +Replace the third dashed item in the first bullet item by: +<p> +"Where the start of a token does not follow any complete token on the + same line, this token is preceded by "<n>" where "n" + is the indentation of the token, provided that it is not, + as a consequence of the first two rules, preceded by "{n}". +<p> +(This addresses the question of empty lines (no layout token) and string-gap tokens +(no layout token in the middle of them). + +<p><li> [Nov 2001] <strong>Page 122, Appendix B.3, Layout</strong>. +In the paragraph following the bullets, add the sentence: +"The characters "newline", "return", "linefeed", and "formfeed", all start a new line." + <p><li> [Oct 2001] <strong>Page 123, Appendix B.3, Layout</strong>. In the first line of the definition of L, replace "if parse-error(t)" by "if m /= 0 and parse-error(t)". This checks that the implicitly-added close diff --git a/libraries/code/Numeric.hs b/libraries/code/Numeric.hs index 6c5f050399f08bf8e4a54310f935b27460748420..5b52c1967f35473981e36c887458ac891b349e89 100644 --- a/libraries/code/Numeric.hs +++ b/libraries/code/Numeric.hs @@ -170,7 +170,7 @@ formatRealFloat fmt decs x [] -> "0.0e0" [d] -> d : ".0e" ++ show (e-1) d:ds -> d : '.' : ds ++ 'e':show (e-1) - + Just dec -> let dec' = max dec 1 in case is of @@ -180,7 +180,7 @@ formatRealFloat fmt decs x d:ds = map intToDigit (if ei > 0 then init is' else is') in d:'.':ds ++ "e" ++ show (e-1+ei) - + FFFixed -> case decs of Nothing @@ -239,8 +239,8 @@ floatToDigits base x = -- Haskell requires that f be adjusted so denormalized numbers -- will have an impossibly low exponent. Adjust for this. - f :: Integer - e :: Int + f :: Integer + e :: Int (f, e) = let n = minExp - e0 in if n > 0 then (f0 `div` (b^n), e0+n) else (f0, e0) @@ -303,19 +303,20 @@ readFloat r = [(fromRational ((n%1)*10^^(k-d)),t) | (n,d,s) <- readFix r, (k,t) <- readExp s] ++ [ (0/0, t) | ("NaN",t) <- lex r] ++ [ (1/0, t) | ("Infinity",t) <- lex r] - where readFix r = [(read (ds++ds'), length ds', t) - | (ds,d) <- lexDigits r, - (ds',t) <- lexFrac d ] - - lexFrac ('.':ds) = lexDigits ds - lexFrac s = [("",s)] - - readExp (e:s) | e `elem` "eE" = readExp' s - readExp s = [(0,s)] - - readExp' ('-':s) = [(-k,t) | (k,t) <- readDec s] - readExp' ('+':s) = readDec s - readExp' s = readDec s + where + readFix r = [(read (ds++ds'), length ds', t) + | (ds,d) <- lexDigits r, + (ds',t) <- lexFrac d ] + + lexFrac ('.':ds) = lexDigits ds + lexFrac s = [("",s)] + + readExp (e:s) | e `elem` "eE" = readExp' s + readExp s = [(0,s)] + + readExp' ('-':s) = [(-k,t) | (k,t) <- readDec s] + readExp' ('+':s) = readDec s + readExp' s = readDec s lexDigits :: ReadS String lexDigits = nonnull isDigit diff --git a/libraries/directory.verb b/libraries/directory.verb index b9ee6d7d84161bac0d27e305ea3300674eb278ed..76a7c0246d1c5f1ab7b46500fd34d8df4ccf9511 100644 --- a/libraries/directory.verb +++ b/libraries/directory.verb @@ -1,4 +1,4 @@ -%**<title>The Haskell 98 Library Report: Directory functions</title> +`%**<title>The Haskell 98 Library Report: Directory functions</title> %**~header %% Other useful functions from SML 96 include modification time diff --git a/report/Prelude.hs b/report/Prelude.hs index 4b89fa639c0263d7968a64f013e4fa4b99bdedc6..94c748c15bcb5dc5549bbe64629067360c494eab 100644 --- a/report/Prelude.hs +++ b/report/Prelude.hs @@ -6,9 +6,9 @@ module Prelude ( Ordering(LT, EQ, GT), Char, String, Int, Integer, Float, Double, Rational, IO, --- These built-in types are defined in the Prelude, but --- are denoted by built-in syntax, and cannot legally --- appear in an export list. +-- These built-in types are defined in the Prelude, but +-- are denoted by built-in syntax, and cannot legally +-- appear in an export list. -- List type: []((:), []) -- Tuple types: (,), (,,), etc. -- Trivial type: () @@ -76,7 +76,7 @@ class Eq a where x == y = not (x /= y) class (Eq a) => Ord a where - compare :: a -> a -> Ordering + compare :: a -> a -> Ordering (<), (<=), (>=), (>) :: a -> a -> Bool max, min :: a -> a -> a @@ -178,7 +178,7 @@ class (Fractional a) => Floating a where -- Minimal complete definition: -- pi, exp, log, sin, cos, sinh, cosh - -- asin, acos, atan + -- asin, acos, atan -- asinh, acosh, atanh x ** y = exp (log x * y) logBase x y = log y / log x diff --git a/report/PreludeText.hs b/report/PreludeText.hs index b44b9f78680938ee8bbdbaff8b420e8a1171e572..944950db6a07ae786e0e0d48c529f03e87cd99bb 100644 --- a/report/PreludeText.hs +++ b/report/PreludeText.hs @@ -119,7 +119,7 @@ lex (c:s) | isSingle c = [([c],s)] lexFracExp ('.':c:cs) | isDigit c = [('.':ds++e,u) | (ds,t) <- lexDigits (c:cs), (e,u) <- lexExp t] - lexFracExp s = [("",s)] + lexFracExp s = lexExp s lexExp (e:s) | e `elem` "eE" = [(e:c:ds,u) | (c:t) <- [s], c `elem` "+-", diff --git a/report/decls.verb b/report/decls.verb index c8c6560b18115e9753ebb64f349f9b76c4c60e5a..0145b0f3a6ef8270c6b64959448b66b0b7776af7 100644 --- a/report/decls.verb +++ b/report/decls.verb @@ -1,5 +1,5 @@ % -% $Header: /home/cvs/root/haskell-report/report/decls.verb,v 1.12 2001/10/04 16:28:52 simonpj Exp $ +% $Header: /home/cvs/root/haskell-report/report/decls.verb,v 1.13 2001/11/01 13:43:43 simonpj Exp $ % %**<title>The Haskell 98 Report: Declarations</title> %*section 4 @@ -615,6 +615,10 @@ constructor is evaluated if and only if the corresponding type in the algebraic datatype declaration has a strictness flag, denoted by an exclamation point, ``@!@''. \indextt{!} +Lexically, ``@!@'' is an ordinary varsym not a "reservedop"; +it has special significance only in the context of the argument types of +a data declaration. + \outline{ \paragraph*{Translation:} diff --git a/report/exps.verb b/report/exps.verb index c2c096acf63d041bad4f20b040b8d996b9c34eff..57bce2f3488a030121462c9dfa55323acc44369f 100644 --- a/report/exps.verb +++ b/report/exps.verb @@ -1,5 +1,5 @@ % -% $Header: /home/cvs/root/haskell-report/report/exps.verb,v 1.11 2001/09/24 16:29:41 simonpj Exp $ +% $Header: /home/cvs/root/haskell-report/report/exps.verb,v 1.12 2001/11/01 13:43:43 simonpj Exp $ % %*section 3 %**<title>The Haskell 98 Report: Expressions</title> @@ -60,7 +60,7 @@ aexp -> qvar & (\tr{variable}) | @(@ exp^{i+1} qop^{(a,i)} @)@ & (\tr{left section}) | @(@ qop^{(a,i)} exp^{i+1} @)@ & (\tr{right section}) | qcon @{@ fbind_1 @,@ ... @,@ fbind_n @}@ & (\tr{labeled construction}, n>=0) - | aexp_{\{qcon\}} @{@ fbind_1 @,@ ... @,@ fbind_n @}@ & (\tr{labeled update}, n >= 1) + | aexp_{\langle{}qcon\rangle{}} @{@ fbind_1 @,@ ... @,@ fbind_n @}@ & (\tr{labeled update}, n >= 1) @@@ \indexsyn{exp}% @@ -1491,7 +1491,8 @@ $x_1$@ })@ $\ldots$ @(case @$v$@ of { @$p$@ -> @$x_n$@})@\\ &@ _ -> @$e'$@ }@\\[2pt] &{\rm at least one of $p_1, \ldots, p_n$ is not a variable; $x_1, \ldots, x_n$ are new variables}\\[4pt] %\\ -(h)&@case @$v$@ of { @$k$@ -> @$e$@; _ -> @$e'$@ } @$=$@ if (@$v$@==@$k$@) then @$e$@ else @$e'$\\[4pt] +(h)&@case @$v$@ of { @$k$@ -> @$e$@; _ -> @$e'$@ } @$=$@ if (@$v$@==@$k$@) then @$e$@ else @$e'$ \\ +&{\rm where $k$ is a character, string, or numeric literal.} \\[4pt] %\\ (i)&@case @$v$@ of { @$x$@ -> @$e$@; _ -> @$e'$@ } @$=$@ case @$v$@ of { @$x$@ -> @$e$@ }@\\[4pt] %\\ @@ -1533,7 +1534,8 @@ $e'$ @ }@ \\ %&$=$@ case @$e1$@ of { @$x_1$@ -> @$e$@ }@\\ %&{\rm where $A$ is constructor defined by @newtype@}\\ (r)&@case @$v$@ of { @$x$@+@$k$@ -> @$e$@; _ -> @$e'$@ }@\\ -&$=$@ if @$v$@ >= @$k$@ then let {@$x'$@ = @$v$@-@$k$@} in @$e[x'/x]$@ else @$e'$@ @($x'$ is a new variable)\\ +&$=$@ if @$v$@ >= @$k$@ then let {@$x'$@ = @$v$@-@$k$@} in @$e[x'/x]$@ else @$e'$\\ +&{\rm where $k$ is a numeric literal, and $x'$ is a new variable}\\ \end{tabular} } %**<div align=center> <h4>Figure 4</h4> </div> @@ -1547,9 +1549,7 @@ In Figures~\ref{simple-case-expr-1}--\ref{simple-case-expr-2}: "p" and "p_i" are patterns; "v", "x", and "x_i" are variables; "K" and "K'" are algebraic datatype (@data@) constructors (including -tuple constructors); "N" is a @newtype@ constructor; \index{newtype declaration@@{\tt newtype} declaration} -and "k" is a character, string, or numeric literal. - +tuple constructors); and "N" is a @newtype@ constructor\index{newtype declaration@@{\tt newtype} declaration}. % For clarity, several rules are expressed using % @let@ (used only in a non-recursive way); their usual purpose is to % prevent name capture diff --git a/report/lexemes.verb b/report/lexemes.verb index 2e008ddd2d1edff67e57e9b6e19d148ef525b696..6efe57a1ca266245726cd7db7bd266f081ab0388 100644 --- a/report/lexemes.verb +++ b/report/lexemes.verb @@ -1,5 +1,5 @@ % -% $Header: /home/cvs/root/haskell-report/report/lexemes.verb,v 1.8 2001/10/02 09:09:26 simonpj Exp $ +% $Header: /home/cvs/root/haskell-report/report/lexemes.verb,v 1.9 2001/11/01 13:43:43 simonpj Exp $ % %*section 2 %**<title>Haskell 98 Lexical Structure</title> @@ -146,13 +146,10 @@ conid -> large \{small | large | digit | @'@ \} reservedid -> @case@ | @class@ | @data@ | @default@ | @deriving@ | @do@ | @else@ | @if@ | @import@ | @in@ | @infix@ | @infixl@ | @infixr@ | @instance@ | @let@ | @module@ | @newtype@ | @of@ | @then@ | @type@ | @where@ | @_@ -specialid -> @as@ | @qualified@ | @hiding@ - @@@ \indexsyn{varid}% \indexsyn{conid}% \indexsyn{reservedid}% -\indexsyn{specialid}% An identifier consists of a letter followed by zero or more letters, digits, underscores, and single quotes. Identifiers are lexically @@ -173,11 +170,9 @@ identifiers beginning with underscore. This allows programmers to use varsym -> ( symbol \{symbol | @:@\} )_{\langle{}reservedop | dashes \rangle{}} consym -> (@:@ \{symbol | @:@\})_{\langle{}reservedop\rangle{}} reservedop -> @..@ | @:@ | @::@ | @=@ | @\@ | @|@ | @<-@ | @->@ | \verb+@@+ | @~@ | @=>@ -specialop -> @-@ | @!@ @@@ \indexsyn{varsym}% \indexsyn{consym}% -\indexsyn{specialop}% \indexsyn{reservedop}% {\em Operator symbols} \index{operator} @@ -199,13 +194,6 @@ Section~\ref{sections}). All of the standard infix operators are just predefined symbols and may be rebound. -A few identifiers and operators, here indicated by "specialid" and "specialop", -have special meanings in certain contexts, but can be used as ordinary -identifiers and operators. -These are indicated by the `special' productions in the lexical syntax. -Examples include @!@ (used only in @data@ declarations) and -@hiding@ (used in @import@ declarations). - In the remainder of the report six different kinds of names\index{namespaces} will be used: @@ -283,7 +271,12 @@ hexadecimal -> hexit\{hexit\} integer -> decimal | @0o@ octal | @0O@ octal | @0x@ hexadecimal | @0X@ hexadecimal -float -> decimal @.@ decimal[(@e@ | @E@)[@-@ | @+@]decimal] + + +float -> decimal @.@ decimal [exponent] + | decimal exponent + +exponent -> (@e@ | @E@) [@+@ | @-@] decimal @@@ \indexsyn{integer}% \indexsyn{float}% diff --git a/report/modules.verb b/report/modules.verb index f9ec6d5205f26c7b24d2ed858d9f15618ec11e80..de6487db169a72191c76cbf50955774829f2fb42 100644 --- a/report/modules.verb +++ b/report/modules.verb @@ -1,5 +1,5 @@ % -% $Header: /home/cvs/root/haskell-report/report/modules.verb,v 1.14 2001/10/04 16:28:52 simonpj Exp $ +% $Header: /home/cvs/root/haskell-report/report/modules.verb,v 1.15 2001/11/01 13:43:43 simonpj Exp $ % %**<title>The Haskell 98 Report: Modules</title> %*section 5 @@ -299,7 +299,7 @@ declarations in a module. The ordering of import declarations is irrelevant. Lexically speaking, the terminal symbols ``@as@'', ``@qualified@'' and ``@hiding@'' are each a "varid" rather than a "reservedid". They have special significance only in the context of an @import@ declaration; -they may be used as variables. +they may also be used as variables. \subsubsection{What is imported} \label{whatisimported} @@ -655,15 +655,11 @@ of the Prelude. \indexmodule{Prelude} \index{Prelude!implicit import of} -The @Prelude@ module is imported automatically into -all modules as if by the statement `@import Prelude@', if and -only if it is not imported with an explicit @import@ declaration. -This provision for explicit import allows values defined in the -Prelude to be hidden from the unqualified name space. The -@Prelude@ module is always available as a qualified import: an -implicit `@import qualified Prelude@' is part of every module and -names prefixed by `@Prelude.@' can always be used to refer to entities in the -Prelude. +The @Prelude@ module is imported automatically into all modules as if +by the statement `@import Prelude@', if and only if it is not imported +with an explicit @import@ declaration. This provision for explicit +import allows entities defined in the Prelude to be selectively imported, +just like those from any other module. The semantics of the entities in @Prelude@ is specified by a reference implementation of @Prelude@ written in \Haskell{}, given in diff --git a/report/preface-13.verb b/report/preface-13.verb index 1ed36e969f53f264e0a951e49a5e925128fdf01e..30a03dadbe61b428e650179d8729cad93a9b4b03 100644 --- a/report/preface-13.verb +++ b/report/preface-13.verb @@ -1,5 +1,5 @@ % -% $Header: /home/cvs/root/haskell-report/report/preface-13.verb,v 1.9 2001/10/04 16:28:52 simonpj Exp $ +% $Header: /home/cvs/root/haskell-report/report/preface-13.verb,v 1.10 2001/11/01 13:43:43 simonpj Exp $ % %**<title>The Haskell 98 Report: Preface</title> %*section @@ -334,6 +334,7 @@ Libor Skarvada, Jan Skibinski, Lauren Smith, Raman Sundaresh, +Ken Takusagawa, Satish Thatte, Simon Thompson, Tom Thomson, diff --git a/report/syntax-iso.verb b/report/syntax-iso.verb index 1d531fcd957d370d9ba1edfafb1ca2b0eb15ba62..92d1e5a1139bbc2b37cc73b432b45779e442db10 100644 --- a/report/syntax-iso.verb +++ b/report/syntax-iso.verb @@ -1,5 +1,5 @@ % -% $Header: /home/cvs/root/haskell-report/report/syntax-iso.verb,v 1.6 2001/10/04 16:28:52 simonpj Exp $ +% $Header: /home/cvs/root/haskell-report/report/syntax-iso.verb,v 1.7 2001/11/01 13:43:43 simonpj Exp $ % %**<title>Haskell 98 Syntax</title> %*section B @@ -65,12 +65,10 @@ conid -> large \{small | large | digit | @'@ \} reservedid -> @case@ | @class@ | @data@ | @default@ | @deriving@ | @do@ | @else@ | @if@ | @import@ | @in@ | @infix@ | @infixl@ | @infixr@ | @instance@ | @let@ | @module@ | @newtype@ | @of@ | @then@ | @type@ | @where@ | @_@ -specialid -> @as@ | @qualified@ | @hiding@ varsym -> ( symbol \{symbol | @:@\} )_{\langle{}reservedop | dashes\rangle{}} consym -> (@:@ \{symbol | @:@\})_{\langle{}reservedop\rangle{}} reservedop -> @..@ | @:@ | @::@ | @=@ | @\@ | @|@ | @<-@ | @->@ | {\tt @@} | @~@ | @=>@ -specialop -> @-@ | @!@ varid && (\tr{variables}) conid && (\tr{constructors}) @@ -93,7 +91,9 @@ hexadecimal -> hexit\{hexit\} integer -> decimal | @0o@ octal | @0O@ octal | @0x@ hexadecimal | @0X@ hexadecimal -float -> decimal @.@ decimal[(@e@ | @E@)[@-@ | @+@]decimal] +float -> decimal @.@ decimal [exponent] + | decimal exponent +exponent -> (@e@ | @E@) [@+@ | @-@] decimal char -> @'@ (graphic_{\langle{}@'@ | @\@\rangle{}} | space | escape_{\langle{}@\&@\rangle{}}) @'@ string -> @"@ \{graphic_{\langle{}@"@ | @\@\rangle{}} | space | escape | gap\} @"@ @@ -157,11 +157,13 @@ A stream of tokens as specified by the lexical syntax in the Haskell report, with the following additional tokens: \begin{itemize} \item If the first token after a @let@, @where@, @do@, or @of@ keyword is not @{@, -it will be preceded by "\{n\}" where "n" is the indentation of the token. +it is preceded by "\{n\}" where "n" is the indentation of the token. \item If the first token of a module is not @{@ or @module@, -then it will be preceded by "\{n\}" where "n" is the indentation of the token. -\item The first token on each line (not including tokens already -annotated) is preceded by "<n>" where "n" is the indentation of the token. +then it is preceded by "\{n\}" where "n" is the indentation of the token. +\item Where the start of a token does not follow any complete token on the + same line, this token is preceded by "<n>" where "n" + is the indentation of the token, provided that it is not, + as a consequence of the first two rules, preceded by "\{n\}". \end{itemize} \item A stack of ``layout contexts'', in which each element is either: @@ -177,13 +179,17 @@ until either the enclosing context ends or a new context is pushed. The ``indentation'' of a lexeme is the column number of the first character of that lexeme; the indentation of a line is the indentation of its leftmost lexeme. To determine the column number, -assume a fixed-width font with this tab convention: tab stops -are 8 characters apart, and a tab character causes the insertion of +assume a fixed-width font with the following conventions: +\begin{itemize} +\item The characters "newline", "return", "linefeed", and "formfeed", all start a new line. +\item The first column is designated column 1, not 0. +\item Tab stops are 8 characters apart. +\item A tab character causes the insertion of enough spaces to align the current position with the next tab stop. +\end{itemize} For the purposes of the layout rule, Unicode characters in a source program are considered to be of the same, fixed, width as an ASCII character. -The first column is designated column 1, not 0. - + The application \[ L~tokens~[0] @@ -490,7 +496,7 @@ aexp -> qvar & (\tr{variable}) | @(@ exp^{i+1} qop^{(a,i)} @)@ & (\tr{left section}) | @(@ qop^{(a,i)} exp^{i+1} @)@ & (\tr{right section}) | qcon @{@ fbind_1 @,@ ... @,@ fbind_n @}@ & (\tr{labeled construction}, n>=0) - | aexp_{\{qcon\}} @{@ fbind_1 @,@ ... @,@ fbind_n @}@ & (\tr{labeled update}, n >= 1) + | aexp_{\langle{}qcon\rangle{}} @{@ fbind_1 @,@ ... @,@ fbind_n @}@ & (\tr{labeled update}, n >= 1) @@@ \indexsyn{aexp}%