[get rid of special reserved ops for foreign parameters, make the ffi only available when using the -fffi flag. allow parsing of more advanced kinds.
John Meacham <john@repetae.net>**20061119011925] hunk ./FlagOpts.flags 5
+ffi support foreign function declarations
hunk ./FrontEnd/HsParser.y 93
+      '??'    { QuestQuest }
+      '*!'    { StarBang }
hunk ./FrontEnd/HsParser.y 109
-      'export'        { KW_Export }
hunk ./FrontEnd/HsParser.y 126
-      'safe'          { KW_Safe }
-      'unsafe'        { KW_Unsafe }
-      'ccall'         { KW_CCall }
-      'stdcall'       { KW_Stdcall }
-      'primitive'     { KW_Primitive }
hunk ./FrontEnd/HsParser.y 128
+      'kind'          { KW_Kind }
hunk ./FrontEnd/HsParser.y 292
-      | 'foreign' srcloc 'export' mcconv mstring var '::' ctype
-                      {% parseExport $5 $6 >>= \x ->
-                         return (HsForeignExport $2 (FfiExport x Safe $4) $6 $8) }
-      | 'foreign' srcloc 'import' 'primitive' mstring var '::' ctype
-                      { let i = Import (if null $5 then show $6 else $5) nullRequires
-                        in HsForeignDecl $2 (FfiSpec i Safe Primitive) $6 $8 }
-      | 'foreign' srcloc 'import' mcconv msafety mstring var '::' ctype
-                      {% parseImport $6 $7 >>= \x ->
-                         return (HsForeignDecl $2 (FfiSpec x $5 $4) $7 $9) }
+      | 'foreign' srcloc 'import' varids mstring '::' ctype
+                      {% doForeign $2 (UnQual (HsIdent "import"):reverse $4) $5 $7  }
+      | 'foreign' srcloc varids mstring '::' ctype
+                      {% doForeign $2 (reverse $3) $4 $6  }
+      | 'foreign' srcloc varids mstring '::' ctype '=' exp
+                      {% doForeignEq $2 (reverse $3) $4 $6 $8 }
+--      | 'foreign' srcloc 'export' mcconv mstring var '::' ctype
+--                      {% parseExport $5 $6 >>= \x ->
+--                         return (HsForeignExport $2 (FfiExport x Safe $4) $6 $8) }
+--      | 'foreign' srcloc 'import' 'primitive' mstring var '::' ctype
+--                      { let i = Import (if null $5 then show $6 else $5) nullRequires
+--                        in HsForeignDecl $2 (FfiSpec i Safe Primitive) $6 $8 }
+--      | 'foreign' srcloc 'import' mcconv msafety mstring var '::' ctype
+--                      {% parseImport $6 $7 >>= \x ->
+--                         return (HsForeignDecl $2 (FfiSpec x $5 $4) $7 $9) }
hunk ./FrontEnd/HsParser.y 374
-
+{-
hunk ./FrontEnd/HsParser.y 384
-
-mstring :: { String }
-mstring : STRING         { $1 }
-        | {- empty -}    { "" }
+-}
+mstring :: { Maybe (String,HsName) }
+mstring : STRING var        { Just ($1,$2) }
+        | {- empty -}    { Nothing }
hunk ./FrontEnd/HsParser.y 414
+       |  '!'                   { hsKindBang }
+       |  '*!'                  { hsKindStarBang }
+       |  '??'                  { hsKindQuestQuest }
hunk ./FrontEnd/HsParser.y 557
-      | varids tyvar                          { ($2:$1) }
+      | varids varid                          { ($2:$1) }
hunk ./FrontEnd/HsParser.y 819
+      | 'kind'                { UnQual (HsIdent "kind") }
hunk ./FrontEnd/HsParser.y 849
+      | '??'                  { UnQual (hsSymbol "??") }
+      | '*!'                  { UnQual (hsSymbol "*!") }
hunk ./FrontEnd/HsSyn.hs 392
+hsKindBang = HsKind (Qual (Module "Jhc@") (HsIdent "!"))
+hsKindQuestQuest = HsKind (Qual (Module "Jhc@") (HsIdent "??"))
+hsKindStarBang   = HsKind (Qual (Module "Jhc@") (HsIdent "*!"))
hunk ./FrontEnd/Lexer.hs 78
+	| QuestQuest
+	| StarBang
hunk ./FrontEnd/Lexer.hs 95
-        | KW_Export
hunk ./FrontEnd/Lexer.hs 112
-        | KW_Safe
-        | KW_Unsafe
-        | KW_CCall
-        | KW_Stdcall
-        | KW_Primitive
hunk ./FrontEnd/Lexer.hs 114
+        | KW_Kind
hunk ./FrontEnd/Lexer.hs 142
+ ( "??",  QuestQuest ),--ditto
+ ( "*!",  StarBang ),--ditto
hunk ./FrontEnd/Lexer.hs 160
- ( "export",    KW_Export ),
hunk ./FrontEnd/Lexer.hs 174
- ( "safe",      KW_Safe ),
- ( "unsafe",    KW_Unsafe ),
- ( "ccall",     KW_CCall ),
- ( "stdcall",   KW_Stdcall ),
- ( "primitive", KW_Primitive ),
hunk ./FrontEnd/Lexer.hs 182
+ ( "kind", 	KW_Kind ),
hunk ./FrontEnd/Lexer.hs 295
-    ParseMode { parseUnboxedTuples = utup } <- lexParseMode
+    ParseMode { parseUnboxedTuples = utup, parseFFI = doFFI } <- lexParseMode
hunk ./FrontEnd/Lexer.hs 331
+                        Just KW_Foreign
+                            | doFFI -> KW_Foreign
+                            | otherwise -> VarId ident
hunk ./FrontEnd/ParseMonad.hs 66
+                parseFFI :: Bool,
hunk ./FrontEnd/ParseMonad.hs 76
+                parseFFI = False,
hunk ./FrontEnd/ParseMonad.hs 80
-parseModeOptions options = defaultParseMode { parseUnboxedTuples = FO.UnboxedTuples `Set.member` optFOptsSet options }
+parseModeOptions options = defaultParseMode {
+    parseUnboxedTuples = FO.UnboxedTuples `Set.member` optFOptsSet options,
+    parseFFI = FO.Ffi `Set.member` optFOptsSet options
+    }
hunk ./FrontEnd/ParseUtils.hs 38
+        , doForeign
+        , doForeignEq
hunk ./FrontEnd/ParseUtils.hs 374
+doForeign :: Monad m => SrcLoc -> [HsName] -> Maybe (String,HsName) -> HsQualType -> m HsDecl
+doForeign srcLoc names ms qt = ans where
+    ans = do
+        (mstring,vname@(UnQual (HsIdent cname)),names') <- case ms of
+            Just (s,n) -> return (Just s,n,names)
+            Nothing -> do
+                (n:ns) <- return $ reverse names
+                return (Nothing,n,reverse ns)
+        let f ["import","primitive"] cname = return $ HsForeignDecl srcLoc (FfiSpec (Import cname nullRequires) Safe Primitive) vname qt
+            f ("import":rs) cname = do
+                let (safe,conv) = pconv rs
+                im <- parseImport mstring vname
+                return $ HsForeignDecl srcLoc (FfiSpec im safe conv) vname qt
+            f ("export":rs) cname = do
+                let (safe,conv) = pconv rs
+                return $ HsForeignExport srcLoc (FfiExport cname safe conv) vname qt
+        f (map show names') (maybe cname id mstring) where
+    pconv rs = case rs of
+                ("safe":rs) -> g Safe rs
+                ("unsafe":rs) -> g Unsafe rs
+                rs -> g Safe rs
+            where
+            g safe [] = (safe,CCall)
+            g safe ["ccall"] = (safe,CCall)
+            g safe ["stdcall"] = (safe,StdCall)
+
+
+doForeignEq :: Monad m => SrcLoc -> [HsName] -> Maybe (String,HsName) -> HsQualType -> HsExp -> m HsDecl
+doForeignEq = undefined
+
hunk ./FrontEnd/ParseUtils.hs 413
-parseImport :: Monad m => String -> HsName -> m FfiType
-parseImport cn hn =
+parseImport :: Monad m => Maybe String -> HsName -> m FfiType
+parseImport Nothing hn = return $ Import (show hn) nullRequires
+parseImport (Just cn) hn =