summaryrefslogtreecommitdiff
path: root/ghc/compiler/parser
diff options
context:
space:
mode:
authorsimonpj <unknown>2000-10-03 08:43:05 +0000
committersimonpj <unknown>2000-10-03 08:43:05 +0000
commit710e207487929c4a5977b5ee3bc6e539091953db (patch)
treeb7426a2301bda799286128b3cdffdec90cc334f1 /ghc/compiler/parser
parentaf099cc124dcb1c5cbb1166aed1177848540c3ab (diff)
downloadhaskell-710e207487929c4a5977b5ee3bc6e539091953db.tar.gz
[project @ 2000-10-03 08:43:00 by simonpj]
-------------------------------------- Adding generics SLPJ Oct 2000 -------------------------------------- This big commit adds Hinze/PJ-style generic class definitions, based on work by Andrei Serjantov. For example: class Bin a where toBin :: a -> [Int] fromBin :: [Int] -> (a, [Int]) toBin {| Unit |} Unit = [] toBin {| a :+: b |} (Inl x) = 0 : toBin x toBin {| a :+: b |} (Inr y) = 1 : toBin y toBin {| a :*: b |} (x :*: y) = toBin x ++ toBin y fromBin {| Unit |} bs = (Unit, bs) fromBin {| a :+: b |} (0:bs) = (Inl x, bs') where (x,bs') = fromBin bs fromBin {| a :+: b |} (1:bs) = (Inr y, bs') where (y,bs') = fromBin bs fromBin {| a :*: b |} bs = (x :*: y, bs'') where (x,bs' ) = fromBin bs (y,bs'') = fromBin bs' Now we can say simply instance Bin a => Bin [a] and the compiler will derive the appropriate code automatically. (About 9k lines of diffs. Ha!) Generic related things ~~~~~~~~~~~~~~~~~~~~~~ * basicTypes/BasicTypes: The EP type (embedding-projection pairs) * types/TyCon: An extra field in an algebraic tycon (genInfo) * types/Class, and hsSyn/HsBinds: Each class op (or ClassOpSig) carries information about whether it a) has no default method b) has a polymorphic default method c) has a generic default method There's a new data type for this: Class.DefMeth * types/Generics: A new module containing good chunk of the generic-related code It has a .hi-boot file (alas). * typecheck/TcInstDcls, typecheck/TcClassDcl: Most of the rest of the generics-related code * hsSyn/HsTypes: New infix type form to allow types of the form data a :+: b = Inl a | Inr b * parser/Parser.y, Lex.lhs, rename/ParseIface.y: Deal with the new syntax * prelude/TysPrim, TysWiredIn: Need to generate generic stuff for the wired-in TyCons * rename/RnSource RnBinds: A rather gruesome hack to deal with scoping of type variables from a generic patterns. Details commented in the ClassDecl case of RnSource.rnDecl. Of course, there are many minor renamer consequences of the other changes above. * lib/std/PrelBase.lhs Data type declarations for Unit, :+:, :*: Slightly unrelated housekeeping ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * hsSyn/HsDecls: ClassDecls now carry the Names for their implied declarations (superclass selectors, tycon, etc) in a list, rather than laid out one by one. This simplifies code between the parser and the type checker. * prelude/PrelNames, TysWiredIn: All the RdrNames are now together in PrelNames. * utils/ListSetOps: Add finite mappings based on equality and association lists (Assoc a b) Move stuff from List.lhs that is related
Diffstat (limited to 'ghc/compiler/parser')
-rw-r--r--ghc/compiler/parser/Lex.lhs40
-rw-r--r--ghc/compiler/parser/ParseUtil.lhs31
-rw-r--r--ghc/compiler/parser/Parser.y82
-rw-r--r--ghc/compiler/parser/RdrHsSyn.lhs47
4 files changed, 144 insertions, 56 deletions
diff --git a/ghc/compiler/parser/Lex.lhs b/ghc/compiler/parser/Lex.lhs
index 88667c4330..d182ce1cc6 100644
--- a/ghc/compiler/parser/Lex.lhs
+++ b/ghc/compiler/parser/Lex.lhs
@@ -184,6 +184,8 @@ data Token
| ITocurly -- special symbols
| ITccurly
+ | ITocurlybar -- {|, for type applications
+ | ITccurlybar -- |}, for type applications
| ITvccurly
| ITobrack
| ITcbrack
@@ -381,7 +383,7 @@ lexer cont buf s@(PState{
where
line = srcLocLine loc
- tab y bol atbol buf = --trace ("tab: " ++ show (I# y) ++ " : " ++ show (currentChar buf)) $
+ tab y bol atbol buf = -- trace ("tab: " ++ show (I# y) ++ " : " ++ show (currentChar buf)) $
case currentChar# buf of
'\NUL'# ->
@@ -407,8 +409,7 @@ lexer cont buf s@(PState{
-- and throw out any unrecognised pragmas as comments. Any
-- pragmas we know about are dealt with later (after any layout
-- processing if necessary).
-
- '{'# | lookAhead# buf 1# `eqChar#` '-'# ->
+ '{'# | lookAhead# buf 1# `eqChar#` '-'# ->
if lookAhead# buf 2# `eqChar#` '#'# then
if lookAhead# buf 3# `eqChar#` '#'# then is_a_token else
case expandWhile# is_space (setCurrentPos# buf 3#) of { buf1->
@@ -472,8 +473,7 @@ nested_comment cont buf = loop buf
loop buf =
case currentChar# buf of
'\NUL'# | bufferExhausted (stepOn buf) ->
- lexError "unterminated `{-'" buf
-
+ lexError "unterminated `{-'" buf -- -}
'-'# | lookAhead# buf 1# `eqChar#` '}'# ->
cont (stepOnBy# buf 2#)
@@ -526,7 +526,7 @@ lexBOL cont buf s@(PState{
lexToken :: (Token -> P a) -> Int# -> P a
lexToken cont glaexts buf =
- --trace "lexToken" $
+ -- trace "lexToken" $
case currentChar# buf of
-- special symbols ----------------------------------------------------
@@ -540,12 +540,16 @@ lexToken cont glaexts buf =
']'# -> cont ITcbrack (incLexeme buf)
','# -> cont ITcomma (incLexeme buf)
';'# -> cont ITsemi (incLexeme buf)
-
'}'# -> \ s@PState{context = ctx} ->
case ctx of
(_:ctx') -> cont ITccurly (incLexeme buf) s{context=ctx'}
_ -> lexError "too many '}'s" buf s
+ '|'# -> case lookAhead# buf 1# of
+ '}'# | flag glaexts -> cont ITccurlybar
+ (setCurrentPos# buf 2#)
+ _ -> lex_sym cont (incLexeme buf)
+
'#'# -> case lookAhead# buf 1# of
')'# | flag glaexts -> cont ITcubxparen (setCurrentPos# buf 2#)
'-'# -> case lookAhead# buf 2# of
@@ -559,16 +563,18 @@ lexToken cont glaexts buf =
-> cont ITbackquote (incLexeme buf)
'{'# -> -- look for "{-##" special iface pragma
- case lookAhead# buf 1# of
+ case lookAhead# buf 1# of
+ '|'# | flag glaexts
+ -> cont ITocurlybar (setCurrentPos# buf 2#)
'-'# -> case lookAhead# buf 2# of
'#'# -> case lookAhead# buf 3# of
- '#'# ->
+ '#'# ->
let (lexeme, buf')
= doDiscard False (stepOnBy# (stepOverLexeme buf) 4#) in
- cont (ITpragma lexeme) buf'
+ cont (ITpragma lexeme) buf'
_ -> lex_prag cont (setCurrentPos# buf 3#)
- _ -> cont ITocurly (incLexeme buf)
- _ -> (layoutOff `thenP_` cont ITocurly) (incLexeme buf)
+ _ -> cont ITocurly (incLexeme buf)
+ _ -> (layoutOff `thenP_` cont ITocurly) (incLexeme buf)
-- strings/characters -------------------------------------------------
'\"'#{-"-} -> lex_string cont glaexts [] (incLexeme buf)
@@ -908,6 +914,7 @@ lex_id cont glaexts buf =
}}}
lex_sym cont buf =
+ -- trace "lex_sym" $
case expandWhile# is_symbol buf of
buf' -> case lookupUFM haskellKeySymsFM lexeme of {
Just kwd_token -> --trace ("keysym: "++unpackFS lexeme) $
@@ -919,6 +926,7 @@ lex_sym cont buf =
lex_con cont glaexts buf =
+ -- trace ("con: "{-++unpackFS lexeme-}) $
case expandWhile# is_ident buf of { buf1 ->
case slurp_trailing_hashes buf1 glaexts of { buf' ->
@@ -927,13 +935,13 @@ lex_con cont glaexts buf =
_ -> just_a_conid
where
- just_a_conid = --trace ("con: "++unpackFS lexeme) $
- cont (ITconid lexeme) buf'
+ just_a_conid = cont (ITconid lexeme) buf'
lexeme = lexemeToFastString buf'
munch = lex_qid cont glaexts lexeme (incLexeme buf') just_a_conid
}}
lex_qid cont glaexts mod buf just_a_conid =
+ -- trace ("quid: "{-++unpackFS lexeme-}) $
case currentChar# buf of
'['# -> -- Special case for []
case lookAhead# buf 1# of
@@ -961,6 +969,7 @@ lex_id3 cont glaexts mod buf just_a_conid
let
start_new_lexeme = stepOverLexeme buf
in
+ -- trace ("lex_id31 "{-++unpackFS lexeme-}) $
case expandWhile# is_symbol start_new_lexeme of { buf' ->
let
lexeme = lexemeToFastString buf'
@@ -975,6 +984,7 @@ lex_id3 cont glaexts mod buf just_a_conid
let
start_new_lexeme = stepOverLexeme buf
in
+ -- trace ("lex_id32 "{-++unpackFS lexeme-}) $
case expandWhile# is_ident start_new_lexeme of { buf1 ->
if emptyLexeme buf1
then just_a_conid
@@ -1007,8 +1017,10 @@ mk_var_token pk_str
| otherwise = ITvarsym pk_str
where
(C# f) = _HEAD_ pk_str
+ -- tl = _TAIL_ pk_str
mk_qvar_token m token =
+-- trace ("mk_qvar ") $
case mk_var_token token of
ITconid n -> ITqconid (m,n)
ITvarid n -> ITqvarid (m,n)
diff --git a/ghc/compiler/parser/ParseUtil.lhs b/ghc/compiler/parser/ParseUtil.lhs
index 49c0376a7f..2a733a7d06 100644
--- a/ghc/compiler/parser/ParseUtil.lhs
+++ b/ghc/compiler/parser/ParseUtil.lhs
@@ -70,7 +70,16 @@ splitForConApp :: RdrNameHsType -> [RdrNameBangType]
splitForConApp t ts = split t ts
where
split (HsAppTy t u) ts = split t (Unbanged u : ts)
-
+{- split (HsOpTy t1 t ty2) ts =
+ -- check that we've got a type constructor at the head
+ if occNameSpace t_occ /= tcClsName
+ then parseError
+ (showSDoc (text "not a constructor: (type pattern)`" <>
+ ppr t <> char '\''))
+ else returnP (con, ts)
+ where t_occ = rdrNameOcc t
+ con = setRdrNameOcc t (setOccNameSpace t_occ dataName)
+-}
split (HsTyVar t) ts =
-- check that we've got a type constructor at the head
if occNameSpace t_occ /= tcClsName
@@ -136,8 +145,12 @@ checkDictTy (HsTyVar t) args@(_:_) | not (isRdrTyVar t)
checkDictTy (HsAppTy l r) args = checkDictTy l (r:args)
checkDictTy _ _ = parseError "Illegal class assertion"
+-- Put more comments!
+-- Checks that the lhs of a datatype declaration
+-- is of the form Context => T a b ... z
checkDataHeader :: RdrNameHsType
-> P (RdrNameContext, RdrName, [RdrNameHsTyVar])
+
checkDataHeader (HsForAllTy Nothing cs t) =
checkSimple t [] `thenP` \(c,ts) ->
returnP (cs,c,map UserTyVar ts)
@@ -145,17 +158,23 @@ checkDataHeader t =
checkSimple t [] `thenP` \(c,ts) ->
returnP ([],c,map UserTyVar ts)
+-- Checks the type part of the lhs of a datatype declaration
checkSimple :: RdrNameHsType -> [RdrName] -> P ((RdrName,[RdrName]))
checkSimple (HsAppTy l (HsTyVar a)) xs | isRdrTyVar a
= checkSimple l (a:xs)
-checkSimple (HsTyVar t) xs | not (isRdrTyVar t) = returnP (t,xs)
-checkSimple t _ = trace (showSDoc (ppr t)) $ parseError "Illegal data/newtype declaration"
+checkSimple (HsTyVar tycon) xs | not (isRdrTyVar tycon) = returnP (tycon,xs)
+
+checkSimple (HsOpTy (HsTyVar t1) tycon (HsTyVar t2)) []
+ | not (isRdrTyVar tycon) && isRdrTyVar t1 && isRdrTyVar t2
+ = returnP (tycon,[t1,t2])
+
+checkSimple t _ = parseError "Illegal left hand side in data/newtype declaration"
---------------------------------------------------------------------------
-- Checking Patterns.
-- We parse patterns as expressions and check for valid patterns below,
--- nverting the expression into a pattern at the same time.
+-- converting the expression into a pattern at the same time.
checkPattern :: RdrNameHsExpr -> P RdrNamePat
checkPattern e = checkPat e []
@@ -204,6 +223,8 @@ checkPat e [] = case e of
RecordCon c fs -> mapP checkPatField fs `thenP` \fs ->
returnP (RecPatIn c fs)
+-- Generics
+ HsType ty -> returnP (TypePatIn ty)
_ -> patFail
checkPat _ _ = patFail
@@ -249,6 +270,7 @@ checkValSig other ty loc = parseError "Type signature given for an expressio
-- A variable binding is parsed as an RdrNameFunMonoBind.
-- See comments with HsBinds.MonoBinds
+isFunLhs :: RdrNameHsExpr -> [RdrNameHsExpr] -> Maybe (RdrName, Bool, [RdrNameHsExpr])
isFunLhs (OpApp l (HsVar op) fix r) es | not (isRdrDataCon op)
= Just (op, True, (l:r:es))
isFunLhs (HsVar f) es | not (isRdrDataCon f)
@@ -282,6 +304,7 @@ mkRecConstrOrUpdate _ _
-- it's external name will be "++". Too bad; it's important because we don't
-- want z-encoding (e.g. names with z's in them shouldn't be doubled)
-- (This is why we use occNameUserString.)
+
mkExtName :: Maybe ExtName -> RdrName -> ExtName
mkExtName Nothing rdrNm = ExtName (_PK_ (occNameUserString (rdrNameOcc rdrNm)))
Nothing
diff --git a/ghc/compiler/parser/Parser.y b/ghc/compiler/parser/Parser.y
index 122ab9ad19..9f7ef43463 100644
--- a/ghc/compiler/parser/Parser.y
+++ b/ghc/compiler/parser/Parser.y
@@ -1,6 +1,6 @@
{-
-----------------------------------------------------------------------------
-$Id: Parser.y,v 1.36 2000/09/22 15:56:13 simonpj Exp $
+$Id: Parser.y,v 1.37 2000/10/03 08:43:02 simonpj Exp $
Haskell grammar.
@@ -14,6 +14,7 @@ module Parser ( parse ) where
import HsSyn
import HsPragmas
import HsTypes ( mkHsTupCon )
+import HsPat ( InPat(..) )
import RdrHsSyn
import Lex
@@ -30,6 +31,7 @@ import Panic
import GlaExts
import FastString ( tailFS )
+import Outputable
#include "HsVersions.h"
}
@@ -158,6 +160,8 @@ Conflicts: 14 shift/reduce
'{' { ITocurly } -- special symbols
'}' { ITccurly }
+ '{|' { ITocurlybar }
+ '|}' { ITccurlybar }
vccurly { ITvccurly } -- virtual close curly (from layout)
'[' { ITobrack }
']' { ITcbrack }
@@ -328,13 +332,13 @@ topdecl :: { RdrBinding }
| srcloc 'data' ctype '=' constrs deriving
{% checkDataHeader $3 `thenP` \(cs,c,ts) ->
returnP (RdrHsDecl (TyClD
- (TyData DataType cs c ts (reverse $5) (length $5) $6
+ (mkTyData DataType cs c ts (reverse $5) (length $5) $6
NoDataPragmas $1))) }
| srcloc 'newtype' ctype '=' newconstr deriving
{% checkDataHeader $3 `thenP` \(cs,c,ts) ->
returnP (RdrHsDecl (TyClD
- (TyData NewType cs c ts [$5] 1 $6
+ (mkTyData NewType cs c ts [$5] 1 $6
NoDataPragmas $1))) }
| srcloc 'class' ctype fds where
@@ -486,7 +490,7 @@ sigtypes :: { [RdrNameHsType] }
| sigtypes ',' sigtype { $3 : $1 }
sigtype :: { RdrNameHsType }
- : ctype { mkHsForAllTy Nothing [] $1 }
+ : ctype { (mkHsForAllTy Nothing [] $1) }
sig_vars :: { [RdrName] }
: sig_vars ',' var { $3 : $1 }
@@ -499,16 +503,21 @@ sig_vars :: { [RdrName] }
ctype :: { RdrNameHsType }
: 'forall' tyvars '.' ctype { mkHsForAllTy (Just $2) [] $4 }
| context type { mkHsForAllTy Nothing $1 $2 }
- -- A type of form (context => type) is an *implicit* HsForAllTy
+ -- A type of form (context => type) is an *implicit* HsForAllTy
| type { $1 }
type :: { RdrNameHsType }
- : btype '->' type { HsFunTy $1 $3 }
+ : gentype '->' type { HsFunTy $1 $3 }
| ipvar '::' type { mkHsIParamTy $1 $3 }
- | btype { $1 }
+ | gentype { $1 }
+
+gentype :: { RdrNameHsType }
+ : btype { $1 }
+-- Generics
+ | atype tyconop atype { HsOpTy $1 $2 $3 }
btype :: { RdrNameHsType }
- : btype atype { HsAppTy $1 $2 }
+ : btype atype { (HsAppTy $1 $2) }
| atype { $1 }
atype :: { RdrNameHsType }
@@ -517,7 +526,9 @@ atype :: { RdrNameHsType }
| '(' type ',' types ')' { HsTupleTy (mkHsTupCon tcName Boxed ($2:$4)) ($2 : reverse $4) }
| '(#' types '#)' { HsTupleTy (mkHsTupCon tcName Unboxed $2) (reverse $2) }
| '[' type ']' { HsListTy $2 }
- | '(' ctype ')' { $2 }
+ | '(' ctype ')' { $2 }
+-- Generics
+ | INTEGER { HsNumTy $1 }
-- An inst_type is what occurs in the head of an instance decl
-- e.g. (Foo a, Gaz b) => Wibble a b
@@ -648,15 +659,16 @@ dclasses :: { [RdrName] }
-}
valdef :: { RdrBinding }
- : infixexp srcloc opt_sig rhs {% checkValDef $1 $3 $4 $2 }
- | infixexp srcloc '::' sigtype {% checkValSig $1 $4 $2 }
+ : infixexp srcloc opt_sig rhs {% (checkValDef $1 $3 $4 $2) }
+ | infixexp srcloc '::' sigtype {% (checkValSig $1 $4 $2) }
| var ',' sig_vars srcloc '::' sigtype { foldr1 RdrAndBindings
[ RdrSig (Sig n $6 $4) | n <- $1:$3 ]
- }
+ }
+
rhs :: { RdrNameGRHSs }
- : '=' srcloc exp wherebinds { GRHSs (unguardedRHS $3 $2)
- $4 Nothing}
+ : '=' srcloc exp wherebinds { (GRHSs (unguardedRHS $3 $2)
+ $4 Nothing)}
| gdrhs wherebinds { GRHSs (reverse $1) $2 Nothing }
gdrhs :: { [RdrNameGRHS] }
@@ -670,13 +682,14 @@ gdrh :: { RdrNameGRHS }
-- Expressions
exp :: { RdrNameHsExpr }
- : infixexp '::' sigtype { ExprWithTySig $1 $3 }
+ : infixexp '::' sigtype { (ExprWithTySig $1 $3) }
| infixexp 'with' dbinding { HsWith $1 $3 }
| infixexp { $1 }
infixexp :: { RdrNameHsExpr }
: exp10 { $1 }
- | infixexp qop exp10 { OpApp $1 $2 (panic "fixity") $3 }
+ | infixexp qop exp10 { (OpApp $1 (HsVar $2)
+ (panic "fixity") $3 )}
exp10 :: { RdrNameHsExpr }
: '\\' aexp aexps opt_asig '->' srcloc exp
@@ -706,24 +719,29 @@ ccallid :: { FAST_STRING }
| CONID { $1 }
fexp :: { RdrNameHsExpr }
- : fexp aexp { HsApp $1 $2 }
+ : fexp aexp { (HsApp $1 $2) }
| aexp { $1 }
aexps0 :: { [RdrNameHsExpr] }
- : aexps { reverse $1 }
+ : aexps { (reverse $1) }
aexps :: { [RdrNameHsExpr] }
: aexps aexp { $2 : $1 }
| {- empty -} { [] }
aexp :: { RdrNameHsExpr }
- : aexp '{' fbinds '}' {% mkRecConstrOrUpdate $1 (reverse $3) }
- | aexp1 { $1 }
+ : var_or_con '{|' gentype '|}' { (HsApp $1 (HsType $3)) }
+ | aexp '{' fbinds '}' {% (mkRecConstrOrUpdate $1
+ (reverse $3)) }
+ | aexp1 { $1 }
+
+var_or_con :: { RdrNameHsExpr }
+ : qvar { HsVar $1 }
+ | gcon { HsVar $1 }
aexp1 :: { RdrNameHsExpr }
- : qvar { HsVar $1 }
- | ipvar { HsIPVar $1 }
- | gcon { HsVar $1 }
+ : ipvar { HsIPVar $1 }
+ | var_or_con { $1 }
| literal { HsLit $1 }
| INTEGER { HsOverLit (mkHsIntegralLit $1) }
| RATIONAL { HsOverLit (mkHsFractionalLit $1) }
@@ -731,8 +749,8 @@ aexp1 :: { RdrNameHsExpr }
| '(' exp ',' texps ')' { ExplicitTuple ($2 : reverse $4) Boxed}
| '(#' texps '#)' { ExplicitTuple (reverse $2) Unboxed }
| '[' list ']' { $2 }
- | '(' infixexp qop ')' { SectionL $2 $3 }
- | '(' qopm infixexp ')' { SectionR $2 $3 }
+ | '(' infixexp qop ')' { (SectionL $2 (HsVar $3)) }
+ | '(' qopm infixexp ')' { (SectionR $2 $3) }
| qvar '@' aexp { EAsPat $1 $3 }
| '_' { EWildPat }
| '~' aexp1 { ELazyPat $2 }
@@ -741,6 +759,7 @@ texps :: { [RdrNameHsExpr] }
: texps ',' exp { $3 : $1 }
| exp { [$1] }
+
-----------------------------------------------------------------------------
-- List expressions
@@ -792,9 +811,9 @@ alts1 :: { [RdrNameMatch] }
alt :: { RdrNameMatch }
: infixexp opt_sig ralt wherebinds
- {% checkPattern $1 `thenP` \p ->
+ {% (checkPattern $1 `thenP` \p ->
returnP (Match [] [p] $2
- (GRHSs $3 $4 Nothing)) }
+ (GRHSs $3 $4 Nothing)) )}
ralt :: { [RdrNameGRHS] }
: '->' srcloc exp { [GRHS [ExprStmt $3 $2] $2] }
@@ -927,9 +946,9 @@ op :: { RdrName } -- used in infix decls
: varop { $1 }
| conop { $1 }
-qop :: { RdrNameHsExpr } -- used in sections
- : qvarop { HsVar $1 }
- | qconop { HsVar $1 }
+qop :: { RdrName {-HsExpr-} } -- used in sections
+ : qvarop { $1 }
+ | qconop { $1 }
qopm :: { RdrNameHsExpr } -- used in sections
: qvaropm { HsVar $1 }
@@ -1052,6 +1071,9 @@ modid :: { ModuleName }
tycon :: { RdrName }
: CONID { mkSrcUnqual tcClsName $1 }
+tyconop :: { RdrName }
+ : CONSYM { mkSrcUnqual tcClsName $1 }
+
qtycon :: { RdrName }
: tycon { $1 }
| QCONID { mkSrcQual tcClsName $1 }
diff --git a/ghc/compiler/parser/RdrHsSyn.lhs b/ghc/compiler/parser/RdrHsSyn.lhs
index 75fa2934ef..5af43d63d3 100644
--- a/ghc/compiler/parser/RdrHsSyn.lhs
+++ b/ghc/compiler/parser/RdrHsSyn.lhs
@@ -53,7 +53,7 @@ module RdrHsSyn (
extractHsTyRdrTyVars, extractHsTysRdrTyVars,
extractPatsTyVars,
extractRuleBndrsTyVars,
- extractHsCtxtRdrTyVars,
+ extractHsCtxtRdrTyVars, extractGenericPatTyVars,
mkHsOpApp, mkClassDecl, mkClassOpSig, mkConDecl,
mkHsNegApp, mkHsIntegralLit, mkHsFractionalLit, mkNPlusKPatIn,
@@ -67,7 +67,8 @@ module RdrHsSyn (
cvBinds,
cvMonoBindsAndSigs,
cvTopDecls,
- cvValSig, cvClassOpSig, cvInstDeclSig
+ cvValSig, cvClassOpSig, cvInstDeclSig,
+ mkTyData
) where
#include "HsVersions.h"
@@ -76,8 +77,8 @@ import HsSyn -- Lots of it
import CmdLineOpts ( opt_NoImplicitPrelude )
import HsPat ( collectSigTysFromPats )
import OccName ( mkClassTyConOcc, mkClassDataConOcc, mkWorkerOcc,
- mkSuperDictSelOcc, mkDefaultMethodOcc,
- varName, dataName, tcName
+ mkSuperDictSelOcc, mkDefaultMethodOcc, mkGenOcc1,
+ mkGenOcc2, varName, dataName, tcName
)
import PrelNames ( pRELUDE_Name, mkTupNameStr )
import RdrName ( RdrName, isRdrTyVar, mkRdrUnqual, rdrNameOcc,
@@ -86,6 +87,8 @@ import RdrName ( RdrName, isRdrTyVar, mkRdrUnqual, rdrNameOcc,
import HsPragmas
import List ( nub )
import BasicTypes ( Boxity(..), RecFlag(..) )
+import Class ( DefMeth (..) )
+import Outputable
\end{code}
@@ -183,6 +186,10 @@ extract_ty (HsUsgTy usg ty) acc = extract_ty ty acc
extract_ty (HsUsgForAllTy uv ty) acc = extract_ty ty acc
extract_ty (HsTyVar tv) acc = tv : acc
extract_ty (HsForAllTy Nothing ctxt ty) acc = extract_ctxt ctxt (extract_ty ty acc)
+-- Generics
+extract_ty (HsOpTy ty1 nam ty2) acc = extract_ty ty1 (extract_ty ty2 acc)
+extract_ty (HsNumTy num) acc = acc
+-- Generics
extract_ty (HsForAllTy (Just tvs) ctxt ty)
acc = acc ++
(filter (`notElem` locals) $
@@ -196,6 +203,19 @@ extractPatsTyVars = filter isRdrTyVar .
nub .
extract_tys .
collectSigTysFromPats
+
+extractGenericPatTyVars :: RdrNameMonoBinds -> [RdrName]
+-- Get the type variables out of the type patterns in a bunch of
+-- possibly-generic bindings in a class declaration
+extractGenericPatTyVars binds
+ = filter isRdrTyVar (nub (get binds []))
+ where
+ get (AndMonoBinds b1 b2) acc = get b1 (get b2 acc)
+ get (FunMonoBind _ _ ms _) acc = foldr get_m acc ms
+ get other acc = acc
+
+ get_m (Match _ (TypePatIn ty : _) _ _) acc = extract_ty ty acc
+ get_m other acc = acc
\end{code}
@@ -215,7 +235,7 @@ Similarly for mkConDecl, mkClassOpSig and default-method names.
\begin{code}
mkClassDecl cxt cname tyvars fds sigs mbinds prags loc
- = ClassDecl cxt cname tyvars fds sigs mbinds prags tname dname dwname sc_sel_names loc
+ = ClassDecl cxt cname tyvars fds sigs mbinds prags new_names loc
where
cls_occ = rdrNameOcc cname
data_occ = mkClassDataConOcc cls_occ
@@ -231,11 +251,22 @@ mkClassDecl cxt cname tyvars fds sigs mbinds prags loc
-- D_sc1, D_sc2
-- (We used to call them D_C, but now we can have two different
-- superclasses both called C!)
-
-mkClassOpSig has_default_method op ty loc
- = ClassOpSig op (Just (dm_rn, has_default_method)) ty loc
+ new_names = toClassDeclNameList (tname, dname, dwname, sc_sel_names)
+
+-- mkTyData :: ??
+mkTyData new_or_data context tname list_var list_con i maybe pragmas src =
+ let t_occ = rdrNameOcc tname
+ name1 = mkRdrUnqual (mkGenOcc1 t_occ)
+ name2 = mkRdrUnqual (mkGenOcc2 t_occ)
+ in TyData new_or_data context
+ tname list_var list_con i maybe pragmas src name1 name2
+
+mkClassOpSig (DefMeth x) op ty loc
+ = ClassOpSig op (Just (DefMeth dm_rn)) ty loc
where
dm_rn = mkRdrUnqual (mkDefaultMethodOcc (rdrNameOcc op))
+mkClassOpSig x op ty loc =
+ ClassOpSig op (Just x) ty loc
mkConDecl cname ex_vars cxt details loc
= ConDecl cname wkr_name ex_vars cxt details loc