
I think the problem is that GHCi doesn't respect #ifdef conditional compilation.
I wasn't aware of any bugs in that area, can anyone provide some sample code? (and I'm surprised, because GHCi just runs cpp in the same way as GHC).
Ah, I think it is probably just a failure to use the -cpp option on the ghci commandline. The error message isn't terribly helpful in this regard, since it complains about being unable to find a module that wasn't wanted anyway. It might be more useful to complain that a cpp # directive was found?
Aha! GHCi (and ghc --make) has a pre-pass that looks through the file for import declarations so it can build the dependency tree, and it does this without using a proper Haskell parser. I'll bet it's ignoring the CPP directives. Probably it should flag an error, I'll look into it. Cheers, Simon

Aha! GHCi (and ghc --make) has a pre-pass that looks through the file for import declarations so it can build the dependency tree, and it does this without using a proper Haskell parser. I'll bet it's ignoring the CPP directives. Probably it should flag an error, I'll look into it.
Using an improper parser sounds a little delicate. Come the time you want to make this more robust, the way Hugs does this is with some semantic actions in the parser. grepping for 'chase' in hugs98/src/parser.y gives these lines in the moduleBody production: modBody : topDecls {$$ = $1;} | impDecls chase {$$ = gc2(NIL);} | impDecls ';' chase topDecls {$$ = gc4($4);} And this rule for chasing. chase : /* empty */ {if (chase(imps)) { clearStack(); onto(imps); done(); closeAnyInput(); return 0; } $$ = gc0(NIL); } ; The C function 'chase' returns True if there are dependencies on modules we haven't loaded yet. The body of the if causes Hugs to record the offending import list and abandon compiling the current module. -- Alastair Reid reid@cs.utah.edu http://www.cs.utah.edu/~reid/

Aha! GHCi (and ghc --make) has a pre-pass that looks through the file for import declarations so it can build the dependency tree, and it does this without using a proper Haskell parser. I'll bet it's ignoring the CPP directives. Probably it should flag an error, I'll look into it.
Using an improper parser sounds a little delicate.
I agree it can be delicate, but there is no real need for a full Haskell parser. For instance, hmake manages just fine with a simplified parser that understands only token streams introduced by the keyword 'import' at the beginning of a line, modified by respecting cpp directives and Haskell comments. Hmake takes the safer route of invoking cpp if any cpp directives were found, but if ghci takes the simpler option of simply flagging an error, it should be pretty easy to fix. Regards, Malcolm

I agree it can be delicate, but there is no real need for a full Haskell parser. For instance, hmake manages just fine with a simplified parser that understands only token streams introduced by the keyword 'import' at the beginning of a line, modified by respecting cpp directives and Haskell comments.
It's true that many people layout their code in such a way that this will work. I imagine it'd be a major burden to add (and, more significantly, maintain) a Haskell parser to hmake since it almost certainly has no other need for one but GHCi already contains a parser. (You don't need a full parser - just enough to parse module headers but still...) But ghci already contains a Haskell parser - so it should be much less work. A

Alastair Reid
For instance, hmake manages just fine with a simplified parser that understands only token streams introduced by the keyword 'import' at the beginning of a line ...
It's true that many people layout their code in such a way that this will work.
The hmake parser specifically doesn't depend on layout. A module doing crazy stuff like module M where import qualified {- " -} N is perfectly fine, and all it takes to implement is the addition of a `concatMap' over and above the version which expects the whole import on one line. (FWIW, the hmake parser is ~200 lines, of which ~150 lines deals with cpp, ~30 lines deals with comments, and ~20 lines actually reads the imports.)
But ghci already contains a Haskell parser - so it should be much less work.
Agreed, except that you don't want to fully-parse each module twice, nor in general do you want to report all parse errors on the import-gathering pass! Regards, Malcolm
participants (3)
-
Alastair Reid
-
Malcolm Wallace
-
Simon Marlow