Re: {-# LINE 100 "Foo.hs #-} vs. # 100 "Foo.hs"
Here is what is currently supported: {-# LINE 100 "Foo.hs #-} | # 100 "Foo.hs"
I recently discovered that some of the GHC toolset actually generates and recognises {-# LINE 100 "Foo.hs -} which is somewhere in between a comment and a pragma. Has this been fixed yet?
I would choose LINE pragma. In this case nhc98 should be taught about it.
The 1.00 release of nhc98 (incorrectly) rejects almost all pragmas. The 1.01 (CVS) version correctly accepts (but ignores) almost all pragmas. In time, it will learn to use the information from a small number of pragmas. When that happens, LINE can certainly be one of them. Regards, Malcolm
Tue, 16 Jan 2001 19:47:31 +0000, Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk> pisze:
I recently discovered that some of the GHC toolset actually generates and recognises {-# LINE 100 "Foo.hs -} which is somewhere in between a comment and a pragma. Has this been fixed yet?
I've heard about it... Oops, it appears that since the CVS version of ghc no longer translates cpp-style markers into LINE pragmas in a separate pass, but interprets them itself in the compiler proper, ghc -E does not perform that pass and now outputs cpp-style markers, which do get into happy's templates. So it's indeed "fixed": to cpp-style markers :-( It can be properly fixed either by postprocessing the templates during building of happy, or implementing that pass separately again for explicit invocation of ghc -E. Since ghc -E does not seem to be a widely used and very standard feature, perhaps it's enough to do the former. Moreover, there was one place internal to ghc which output {-# LINE 1 "File" -} and I will commit a fix in a minute.
The 1.00 release of nhc98 (incorrectly) rejects almost all pragmas. The 1.01 (CVS) version correctly accepts (but ignores) almost all pragmas. In time, it will learn to use the information from a small number of pragmas. When that happens, LINE can certainly be one of them.
ghc recognizes {-# together with the pragma's keyword during lexical analysis, emits e.g. '{-# SPECIALIZE' as a single token, and treats unrecognized pragmas as comments. nhc98 passes all pragmas to the parser. The difference is that ghc ignores pragmas with unknown keywords placed in unusual places (e.g. in the middle of an expression), where nhc98 flags them as errors. Of course LINE can appear anywhere without respect to layout so must be dealt with during the lexical analysis. Haskell 98 does not say anything about case sensitivity of pragmas' keywords but uses lowercase and mixedCase examples. ghc ignores the case. hbc understands both all-uppercase and all-lowercase forms but no mixing. I've seen only uppercase in practice. Perhaps something should be said about it more explicitly. Perhaps official support for uppercase only is enough (the rest of Haskell is case sensitive). -- __("< Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTÊPCZA QRCZAK
With all this talk of preprocessor generated information and whatnot, I am reminded of a paper I read not too long ago but can't seem to find anymore about a dedicated pre-processor for haskell based on the C preprocessor but made to deal with haskell constructs a bit more sanely. I was wondering whatever happened to that Idea as I find myself in need of a preprocessor every now and again... I imagine a small pure Haskell 98 implementation of the preprocessor would be very useful because then it can be included directly with programs that require it and compiled first as part of the make process until compilers have it integrated... any thoughts? anyone have a link to the original paper I am talking about? -- -------------------------------------------------------------- John Meacham http://www.ugcs.caltech.edu/~john/ California Institute of Technology, Alum. john@foo.net --------------------------------------------------------------
With all this talk of preprocessor generated information and whatnot, I am reminded of a paper I read not too long ago but can't seem to find anymore about a dedicated pre-processor for haskell based on the C preprocessor but made to deal with haskell constructs a bit more sanely.
This was me... http://www.cl.cam.ac.uk/~kw217/research/papers.html#Wansbrough99:Macros There wasn't sufficient interest, and no one has offered to implement it. I think people are mostly happy using CPP, and the hassle of writing a `decent' macro preprocessor isn't worth it. You may find some of the ideas in the paper useful, though. --KW 8-)
Mon, 22 Jan 2001 16:42:32 +0000, Keith Wansbrough <Keith.Wansbrough@cl.cam.ac.uk> pisze:
http://www.cl.cam.ac.uk/~kw217/research/papers.html#Wansbrough99:Macros
hsc2hs, although designed for embedding Haskell constructs depending on C headers, can be used as a Haskell preprocessor. It avoids lexing Haskell source using C rules. Among C-specific things it provides #if/#ifdef/etc., #define/#undef, #include, #error/#warning, and an ugly way to define macros with optional parameters, token pasting, stringification and controlled layout. The implementation delegates all hard work to a C compiler applied to a C program which outputs the Haskell program. {-# LINE #-} pragmas are understood and generated. #define and #include are also put into ghc's .hc files. The only part which differs much from cpp and is quite ugly is macros to be used in the Haskell program. They can be defined and used for example thus: ------------------------------------------------------------------------ #let assert e = "(if (%s) then id else " \ "const (error \"Assertion failed: %s, %s:%d\")) $", \ e, e, __FILE__, __LINE__ main = #assert "length [1,2,3] == 3" putStrLn "Hello world" ------------------------------------------------------------------------ and if you don't mind applying C lexical syntax to bits of Haskell code, you can replace uses of e above by #e and call #assert (length [1,2,3] == 3) where parens are necessary only because the expression contains commas outside parens. You can also embed e into the string constant thus: "(if (" e ") then id else " ... instead of using printf format, but this fails if the expression contains % characters. Macro expansion is not applied to all occurrences of an identifier in the source, but just to explicitly used new #-constructs as #assert above. A macro definition can be written in an equivalent, more low-level way thus: #define hsc_assert(e) printf ( \ "(if (%s) then id else " \ "const (error \"Assertion failed: %s, %s:%d\")) $", \ e, e, __FILE__, __LINE__); and can make use of arbitrary C statements which are a part of the C program created and run during preprocessing. I once made a file preprocessed twice. The first pass generates #ifdefs for each identifier passed as a macro argument, the second pass applies these #ifdefs. hsc2hs is in the CVS version of ghc and QForeign. -- __("< Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTÊPCZA QRCZAK
participants (4)
-
John Meacham -
Keith Wansbrough -
Malcolm Wallace -
qrczak@knm.org.pl