diff --git a/curry-frontend.cabal b/curry-frontend.cabal
--- a/curry-frontend.cabal
+++ b/curry-frontend.cabal
@@ -1,5 +1,5 @@
 Name:          curry-frontend
-Version:       0.2
+Version:       0.2.1
 Cabal-Version: >= 1.6
 Synopsis:      Compile the functional logic language Curry to several intermediate formats
 Description:   The Curry Frontend consists of the executable program "cymake".
@@ -26,20 +26,34 @@
   hs-source-dirs:   src
   Main-is:          cymake.hs
   Build-Depends:    base >= 3 && < 4, mtl, old-time, directory, filepath, containers
-  Other-Modules:    AbstractCurry, CurryBuilder, Env, IL, Message
-                    CurryCompilerOpts, Error, Modules, Subst, Arity
-                    CurryDeps, Eval, ILPP, NestEnv, SyntaxCheck, Base
-                    Exports, ILScope, SyntaxColoring, CurryEnv
-                    ExtendedFlat, ILTrans, OldScopeEnv, CurryHtml
-                    ILxml, PatchPrelude, TopEnv, CaseCompletion
-                    CurryLexer, Imports, PathUtils, TypeCheck
-                    CurryParser, InterfaceCheck, Position
-                    Types, CurryPP, Frontend, PrecCheck
+  ghc-options:      -fwarn-unused-binds -fwarn-unused-imports
+-- -fwarn-incomplete-patterns
+  Other-Modules:    Curry.Base.Position, Curry.Base.Ident, Curry.Base.MessageMonad
+                    Curry.Syntax.Lexer, Curry.Syntax.LexComb
+                    Curry.Syntax.Parser, Curry.Syntax.LLParseComb
+                    Curry.Syntax.ShowModule, Curry.Syntax.Pretty
+                    Curry.Syntax, Curry.Syntax.Type
+                    Curry.Syntax.Unlit, Curry.Syntax.Utils
+                    Curry.AbstractCurry, Curry.ExtendedFlat
+                    CurryBuilder, IL.Type 
+                    CurryCompilerOpts, Modules, Subst, Arity
+                    CurryDeps, Eval, IL.Pretty, NestEnv, SyntaxCheck, Base
+                    Exports, IL.Scope, SyntaxColoring, CurryEnv
+                    IL.CurryToIL, OldScopeEnv, CurryHtml
+                    IL.XML, PatchPrelude, TopEnv, CaseCompletion
+                    Imports, PathUtils, TypeCheck
+                    InterfaceCheck, 
+                    Types, Frontend, PrecCheck
                     TypeSubst, GenAbstractCurry
-                    Pretty, Typing, Combined, CurrySyntax
-                    GenFlatCurry, KindCheck, Qual, Unlit, CompilerResults
-                    LexComb, SCC, Utils, GetOpt
+                    PrettyCombinators, Typing
+                    GenFlatCurry, KindCheck, Qual
+                    SCC, Utils, GetOpt
                     Lift, ScopeEnv, WarnCheck
-                    LLParseComb, Desugar, Ident, ShowCurrySyntax
+                    Desugar, Curry.Base.Ident, 
                     Simplify
+
+-- Executable pretty-ecy
+--   hs-source-dirs:   src
+--   Main-is:          pretty-ecy.hs
+--   Build-Depends:    base >= 3 && < 4
 
diff --git a/src/AbstractCurry.hs b/src/AbstractCurry.hs
deleted file mode 100644
--- a/src/AbstractCurry.hs
+++ /dev/null
@@ -1,282 +0,0 @@
-------------------------------------------------------------------------------
---- Library to support meta-programming in Curry.
----
---- This library contains a definition for representing Curry programs
---- in Curry (type "CurryProg") and an I/O action to read Curry programs and
---- transform them into this abstract representation (function "readCurry").
----
---- Note this defines a slightly new format for AbstractCurry
---- in comparison to the first proposal of 2003.
----
---- Assumption: an abstract Curry program is stored in file prog.acy
----             and translated with the parser by "parsecurry -acy prog".
----
---- @author Michael Hanus
---- @version April 2004
----
---- Version for Haskell (slightly modified):
---- July 2005, Martin Engelke (men@informatik.uni-kiel.de)
----
-------------------------------------------------------------------------------
-
-module AbstractCurry (CurryProg(..), QName, CLabel, CVisibility(..),
-		      CTVarIName, CTypeDecl(..), CConsDecl(..), CTypeExpr(..),
-                      COpDecl(..), CFixity(..), CVarIName,
-                      CFuncDecl(..), CRules(..), CEvalAnnot(..),
-                      CRule(..), CLocalDecl(..), CExpr(..), CStatement(..),
-                      CPattern(..), CBranchExpr(..), CLiteral(..),
-		      CField,
-                      readCurry, writeCurry) where
-
-import Data.List(intersperse)
-
-import PathUtils (writeModule,readModule)
-
-
-------------------------------------------------------------------------------
--- Definition of data types for representing abstract Curry programs:
--- ==================================================================
-
---- Data type for representing a Curry module in the intermediate form.
---- A value of this data type has the form
---- <CODE>
----  (CProg modname imports typedecls functions opdecls)
---- </CODE>
---- where modname: name of this module,
----       imports: list of modules names that are imported,
----       typedecls, opdecls, functions: see below
-
-data CurryProg = CurryProg String [String] [CTypeDecl] [CFuncDecl] [COpDecl]
-	         deriving (Read, Show)
-
---- The data type for representing qualified names.
---- In AbstractCurry all names are qualified to avoid name clashes.
---- The first component is the module name and the second component the
---- unqualified name as it occurs in the source program.
-type QName = (String,String)
-
---- Type for representing label identifiers
-type CLabel = String
-
--- Data type to specify the visibility of various entities.
-
-data CVisibility = Public    -- exported entity
-                 | Private   -- private entity
-		   deriving (Read, Show, Eq)
-
-
---- The data type for representing type variables.
---- They are represented by (i,n) where i is a type variable index
---- which is unique inside a function and n is a name (if possible,
---- the name written in the source program).
-type CTVarIName = (Int,String)
-
---- Data type for representing definitions of algebraic data types
---- and type synonyms.
---- <PRE>
---- A data type definition of the form
----
---- data t x1...xn = ...| c t1....tkc |...
----
---- is represented by the Curry term
----
---- (CType t v [i1,...,in] [...(CCons c kc v [t1,...,tkc])...])
----
---- where each ij is the index of the type variable xj
----
---- Note: the type variable indices are unique inside each type declaration
----       and are usually numbered from 0
----
---- Thus, a data type declaration consists of the name of the data type,
---- a list of type parameters and a list of constructor declarations.
---- </PRE>
-
-data CTypeDecl = CType    QName CVisibility [CTVarIName] [CConsDecl]
-               | CTypeSyn QName CVisibility [CTVarIName] CTypeExpr
-		 deriving (Read, Show)
-
-
---- A constructor declaration consists of the name and arity of the
---- constructor and a list of the argument types of the constructor.
-
-data CConsDecl = CCons QName Int CVisibility [CTypeExpr]
-		 deriving (Read, Show)
-
-
---- Data type for type expressions.
---- A type expression is either a type variable, a function type,
---- or a type constructor application.
----
---- Note: the names of the predefined type constructors are
----       "Int", "Float", "Bool", "Char", "IO", "Success",
----       "()" (unit type), "(,...,)" (tuple types), "[]" (list type)
-
-data CTypeExpr =
-    CTVar CTVarIName               -- type variable
-  | CFuncType CTypeExpr CTypeExpr  -- function type t1->t2
-  | CTCons QName [CTypeExpr]       -- type constructor application
-  | CRecordType [CField CTypeExpr] -- record type (extended Curry)
-                (Maybe CTVarIName)
-    deriving (Read, Show) 
-
-
---- Data type for operator declarations.
---- An operator declaration "fix p n" in Curry corresponds to the
---- AbstractCurry term (COp n fix p).
-
-data COpDecl = COp QName CFixity Integer deriving (Read, Show)
-
-data CFixity = CInfixOp   -- non-associative infix operator
-             | CInfixlOp  -- left-associative infix operator
-             | CInfixrOp  -- right-associative infix operator
-	       deriving (Read, Show, Eq)
-
-
---- Data types for representing object variables.
---- Object variables occurring in expressions are represented by (Var i)
---- where i is a variable index.
-
-type CVarIName = (Int,String)
-
-
---- Data type for representing function declarations.
---- <PRE>
---- A function declaration in FlatCurry is a term of the form
----
----  (CFunc name arity visibility type (CRules eval [CRule rule1,...,rulek]))
----
---- and represents the function "name" with definition
----
----   name :: type
----   rule1
----   ...
----   rulek
----
---- Note: the variable indices are unique inside each rule
----
---- External functions are represented as (CFunc name arity type (CExternal s))
---- where s is the external name associated to this function.
----
---- Thus, a function declaration consists of the name, arity, type, and
---- a list of rules.
---- </PRE>
-
-data CFuncDecl = CFunc QName Int CVisibility CTypeExpr CRules
-	         deriving (Read, Show)
-
-
---- A rule is either a list of formal parameters together with an expression
---- (i.e., a rule in flat form), a list of general program rules with
---- an evaluation annotation, or it is externally defined
-
-data CRules = CRules CEvalAnnot [CRule]
-            | CExternal String
-	      deriving (Read, Show)
-
---- Data type for classifying evaluation annotations for functions.
---- They can be either flexible (default), rigid, or choice.
-
-data CEvalAnnot = CFlex | CRigid | CChoice deriving (Read, Show, Eq)
-
---- The most general form of a rule. It consists of a list of patterns
---- (left-hand side), a list of guards ("success" if not present in the
---- source text) with their corresponding right-hand sides, and
---- a list of local declarations.
-data CRule = CRule [CPattern] [(CExpr,CExpr)] [CLocalDecl]
-	     deriving (Read, Show)
-
---- Data type for representing local (let/where) declarations
-data CLocalDecl =
-     CLocalFunc CFuncDecl                   -- local function declaration
-   | CLocalPat  CPattern CExpr [CLocalDecl] -- local pattern declaration
-   | CLocalVar  CVarIName                   -- local free variable declaration
-     deriving (Read, Show)
-
---- Data type for representing Curry expressions.
-
-data CExpr =
-   CVar       CVarIName             -- variable (unique index / name)
- | CLit       CLiteral              -- literal (Integer/Float/Char constant)
- | CSymbol    QName                 -- a defined symbol with module and name
- | CApply     CExpr CExpr           -- application (e1 e2)
- | CLambda    [CPattern] CExpr      -- lambda abstraction
- | CLetDecl   [CLocalDecl] CExpr    -- local let declarations
- | CDoExpr    [CStatement]          -- do expression
- | CListComp  CExpr [CStatement]    -- list comprehension
- | CCase      CExpr [CBranchExpr]   -- case expression
- | CRecConstr [CField CExpr]        -- record construction (extended Curry)
- | CRecSelect CExpr CLabel          -- field selection (extended Curry)
- | CRecUpdate [CField CExpr] CExpr  -- record update (extended Curry)
-   deriving (Read, Show)
-
---- Data type for representing statements in do expressions and
---- list comprehensions.
-
-data CStatement = CSExpr CExpr         -- an expression (I/O action or boolean)
-                | CSPat CPattern CExpr -- a pattern definition
-                | CSLet [CLocalDecl]   -- a local let declaration
-		  deriving (Read, Show)
-
---- Data type for representing pattern expressions.
-
-data CPattern =
-   CPVar CVarIName             -- pattern variable (unique index / name)
- | CPLit CLiteral              -- literal (Integer/Float/Char constant)
- | CPComb QName [CPattern]     -- application (m.c e1 ... en) of n-ary
-                               -- constructor m.c (CPComb (m,c) [e1,...,en])
- | CPAs CVarIName CPattern     -- as-pattern (extended Curry)
- | CPFuncComb QName [CPattern] -- function pattern (extended Curry)
- | CPLazy CPattern             -- lazy pattern (extended Curry) 
- | CPRecord [CField CPattern]  -- record pattern (extended curry)
-            (Maybe CPattern)
-   deriving (Read, Show)  
-
---- Data type for representing branches in case expressions.
-
-data CBranchExpr = CBranch CPattern CExpr deriving (Read, Show)
-
---- Data type for representing literals occurring in an expression.
---- It is either an integer, a float, or a character constant.
---- Note: the constructor definition of 'CIntc' differs from the original
---- PAKCS definition. It uses Haskell type 'Integer' instead of 'Int'
---- to provide an unlimited range of integer numbers. Furthermore
---- float values are represented with Haskell type 'Double' instead of
---- 'Float'.
-
-data CLiteral = CIntc   Integer
-              | CFloatc Double
-              | CCharc  Char
-		deriving (Read, Show, Eq)
-
---- Type for representing labeled fields
-
-type CField a = (CLabel,a)
-
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-
--- Reads an AbstractCurry file and returns the corresponding AbstractCurry
--- program term (type 'CurryProg')
-readCurry :: String -> IO CurryProg
-readCurry filename
-   = do file <- readModule filename
-	let prog = (read file) :: CurryProg
-	return prog
-
--- Writes an AbstractCurry program term into a file
-writeCurry :: String -> CurryProg -> IO ()
-writeCurry filename prog 
-   = catch (writeModule filename (showCurry prog)) (\e -> ioError e)
-
--- Shows an AbstractCurry program in a more nicely way.
-showCurry :: CurryProg -> String
-showCurry (CurryProg mname imps types funcs ops) =
-  "CurryProg "++show mname++"\n "++
-  show imps ++"\n ["++
-  concat (intersperse ",\n  " (map (\t->show t) types)) ++"]\n ["++
-  concat (intersperse ",\n  " (map (\f->show f) funcs)) ++"]\n "++
-  show ops ++"\n"
-  
-
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
diff --git a/src/Arity.hs b/src/Arity.hs
--- a/src/Arity.hs
+++ b/src/Arity.hs
@@ -9,9 +9,10 @@
 --
 module Arity (bindArities) where
 
-import Base
-import CurrySyntax
-import Ident
+import Curry.Base.Ident
+import Curry.Syntax
+
+import Base(ArityEnv, bindArity)
 
 
 -------------------------------------------------------------------------------
diff --git a/src/Base.lhs b/src/Base.lhs
--- a/src/Base.lhs
+++ b/src/Base.lhs
@@ -7,34 +7,30 @@
 %
 \nwfilename{Base.lhs}
 \section{Common Definitions for the Compiler}
-The module \texttt{Base} provides common definitions for the various 
-phases of the compiler.
+
+The module \texttt{Base} implements the anti-pattern 'God-object'.
+By providing common definitions for the various phases of the
+compiler, it irrevocably turns the module structure into spaghetti.
+(hsi)
+
 \begin{verbatim}
 
-> module Base(module Base,module Ident,module Position,module Types,
->             module CurrySyntax) where
+> module Base where
 
 > import Data.List
 > import Control.Monad
 > import Data.Maybe
-> import qualified Data.Set as Set
 > import qualified Data.Map as Map
 
-> import Ident 
-> import Position
+> import Curry.Base.Ident 
+> import Curry.Base.Position
 > import Types
-> import CurrySyntax
-> import CurryPP
-> import Pretty
-> import ExtendedFlat hiding (SrcRef, Fixity(..), TypeExpr, Expr(..))
-> import Env
+> import Curry.Syntax
+> import Curry.Syntax.Utils
 > import TopEnv
-
-
 > import Utils
 
 
-> import qualified ExtendedFlat as EF 
 
 \end{verbatim}
 \paragraph{Types}
@@ -52,10 +48,10 @@
 \begin{verbatim}
 
 > toQualType :: ModuleIdent -> [Ident] -> TypeExpr -> Type
-> toQualType m tvs ty = qualifyType m (toType tvs ty)
+> toQualType m tvs = qualifyType m . toType tvs
 
 > toQualTypes :: ModuleIdent -> [Ident] -> [TypeExpr] -> [Type]
-> toQualTypes m tvs tys = map (qualifyType m) (toTypes tvs tys)
+> toQualTypes m tvs = map (qualifyType m) . toTypes tvs
 
 > toType :: [Ident] -> TypeExpr -> Type
 > toType tvs ty = toType' (Map.fromList (zip (tvs ++ tvs') [0..])) ty
@@ -85,26 +81,8 @@
 >	                        _ -> internalError ("toType " ++ show ty))
 >	              rty)
 
-> qualifyType :: ModuleIdent -> Type -> Type
-> qualifyType m (TypeConstructor tc tys)
->   | isTupleId tc' = tupleType tys'
->   | tc' == unitId && n == 0 = unitType
->   | tc' == listId && n == 1 = listType (head tys')
->   | otherwise = TypeConstructor (qualQualify m tc) tys'
->   where n = length tys'
->         tc' = unqualify tc
->         tys' = map (qualifyType m) tys
-> qualifyType _ (TypeVariable tv) = TypeVariable tv
-> qualifyType m (TypeConstrained tys tv) =
->   TypeConstrained (map (qualifyType m) tys) tv
-> qualifyType m (TypeArrow ty1 ty2) =
->   TypeArrow (qualifyType m ty1) (qualifyType m ty2)
-> qualifyType _ (TypeSkolem k) = TypeSkolem k
-> qualifyType m (TypeRecord fs rty) =
->   TypeRecord (map (\ (l,ty) -> (l, qualifyType m ty)) fs) rty
-
 > fromQualType :: ModuleIdent -> Type -> TypeExpr
-> fromQualType m ty = fromType (unqualifyType m ty)
+> fromQualType m = fromType . unqualifyType m
 
 > fromType :: Type -> TypeExpr
 > fromType (TypeConstructor tc tys)
@@ -113,7 +91,7 @@
 >   | c == unitId && null tys = TupleType []
 >   | otherwise = ConstructorType tc tys'
 >   where c = unqualify tc
->         tys' = map (fromType) tys
+>         tys' = map fromType tys
 > fromType (TypeVariable tv) =
 >   VariableType (if tv >= 0 then nameSupply !! tv
 >                            else mkIdent ('_' : show (-tv)))
@@ -124,28 +102,8 @@
 >   RecordType (map (\ (l,ty) -> ([l], fromType ty)) fs)
 >              (maybe Nothing (Just . fromType . TypeVariable) rty)
 
-> unqualifyType :: ModuleIdent -> Type -> Type
-> unqualifyType m (TypeConstructor tc tys) =
->   TypeConstructor (qualUnqualify m tc) (map (unqualifyType m) tys)
-> unqualifyType _ (TypeVariable tv) = TypeVariable tv
-> unqualifyType m (TypeConstrained tys tv) =
->   TypeConstrained (map (unqualifyType m) tys) tv
-> unqualifyType m (TypeArrow ty1 ty2) =
->   TypeArrow (unqualifyType m ty1) (unqualifyType m ty2)
-> unqualifyType m (TypeSkolem k) = TypeSkolem k
-> unqualifyType m (TypeRecord fs rty) =
->   TypeRecord (map (\ (l,ty) -> (l, unqualifyType m ty)) fs) rty
 
-\end{verbatim}
-The following functions implement pretty-printing for types.
-\begin{verbatim}
 
-> ppType :: ModuleIdent -> Type -> Doc
-> ppType m = ppTypeExpr 0 . fromQualType m
-
-> ppTypeScheme :: ModuleIdent -> TypeScheme -> Doc
-> ppTypeScheme m (ForAll _ ty) = ppType m ty
-
 \end{verbatim}
 \paragraph{Interfaces}
 The compiler maintains a global environment holding all (directly or
@@ -158,85 +116,10 @@
 for PAKCS.
 \begin{verbatim}
 
-> type ModuleEnv = Env ModuleIdent [IDecl]
-
-> bindModule :: Interface -> ModuleEnv -> ModuleEnv
-> bindModule (Interface m ds) = bindEnv m ds
-
-> bindFlatInterface :: Prog -> ModuleEnv -> ModuleEnv
-> bindFlatInterface (Prog m imps ts fs os)
->    = bindModule (Interface (mkMIdent [m])
->	                     ((map genIImportDecl imps)
->		              ++ (map genITypeDecl ts')
->		              ++ (map genIFuncDecl fs)
->		              ++ (map genIOpDecl os)))
->  where
->  genIImportDecl :: String -> IDecl
->  genIImportDecl imp = IImportDecl pos (mkMIdent [imp])
->
->  genITypeDecl :: TypeDecl -> IDecl
->  genITypeDecl (Type qn _ is cs)
->     | recordExt `isPrefixOf` localName qn
->       = ITypeDecl pos
->                   (genQualIdent qn)
->	            (map (genVarIndexIdent "a") is)
->	            (RecordType (map genLabeledType cs) Nothing)
->     | otherwise
->       = IDataDecl pos 
->                   (genQualIdent qn) 
->                   (map (genVarIndexIdent "a") is) 
->                   (map (Just . genConstrDecl) cs)
->  genITypeDecl (TypeSyn qn _ is t)
->     = ITypeDecl pos
->                 (genQualIdent qn)
->                 (map (genVarIndexIdent "a") is)
->                 (genTypeExpr t)
->
->  genIFuncDecl :: FuncDecl -> IDecl
->  genIFuncDecl (Func qn a _ t _) 
->     = IFunctionDecl pos (genQualIdent qn) a (genTypeExpr t)
->
->  genIOpDecl :: OpDecl -> IDecl
->  genIOpDecl (Op qn f p) = IInfixDecl pos (genInfix f) p  (genQualIdent qn)
->
->  genConstrDecl :: ConsDecl -> ConstrDecl
->  genConstrDecl (Cons qn _ _ ts)
->     = ConstrDecl pos [] (mkIdent (localName qn)) (map genTypeExpr ts)
->
->  genLabeledType :: EF.ConsDecl -> ([Ident],CurrySyntax.TypeExpr)
->  genLabeledType (Cons qn _ _ [t])
->     = ([renameLabel (fromLabelExtId (mkIdent $ localName qn))], genTypeExpr t)
->
->  genTypeExpr :: EF.TypeExpr -> CurrySyntax.TypeExpr
->  genTypeExpr (TVar i)
->     = VariableType (genVarIndexIdent "a" i)
->  genTypeExpr (FuncType t1 t2) 
->     = ArrowType (genTypeExpr t1) (genTypeExpr t2)
->  genTypeExpr (TCons qn ts) 
->     = ConstructorType (genQualIdent qn) (map genTypeExpr ts)
->
->  genInfix :: EF.Fixity -> Infix
->  genInfix EF.InfixOp  = Infix
->  genInfix EF.InfixlOp = InfixL
->  genInfix EF.InfixrOp = InfixR
->
->  genQualIdent :: QName -> QualIdent
->  genQualIdent QName{modName=mod,localName=name} = 
->    qualifyWith (mkMIdent [mod]) (mkIdent name)
->
->  genVarIndexIdent :: String -> Int -> Ident
->  genVarIndexIdent v i = mkIdent (v ++ show i)
->
->  isSpecialPreludeType :: TypeDecl -> Bool
->  isSpecialPreludeType (Type QName{modName=mod,localName=name} _ _ _) 
->     = (name == "[]" || name == "()") && mod == "Prelude"
->  isSpecialPreludeType _ = False
->
->  pos = first m
->  ts' = filter (not . isSpecialPreludeType) ts
+> type ModuleEnv = Map.Map ModuleIdent [IDecl]
 
 > lookupModule :: ModuleIdent -> ModuleEnv -> Maybe [IDecl]
-> lookupModule = lookupEnv
+> lookupModule = Map.lookup
 
 \end{verbatim}
 The label environment is used to store information of labels.
@@ -249,19 +132,19 @@
 
 > data LabelInfo = LabelType Ident QualIdent Type deriving Show
 
-> type LabelEnv = Env Ident [LabelInfo]
+> type LabelEnv = Map.Map Ident [LabelInfo]
 
 > bindLabelType :: Ident -> QualIdent -> Type -> LabelEnv -> LabelEnv
 > bindLabelType l r ty lEnv =
->   maybe (bindEnv l [LabelType l r ty] lEnv)
->         (\ls -> bindEnv l ((LabelType l r ty):ls) lEnv)
->         (lookupEnv l lEnv)
+>   maybe (Map.insert l [LabelType l r ty] lEnv)
+>         (\ls -> Map.insert l (LabelType l r ty:ls) lEnv)
+>         (Map.lookup l lEnv)
 
 > lookupLabelType :: Ident -> LabelEnv -> [LabelInfo]
-> lookupLabelType l lEnv = fromMaybe [] (lookupEnv l lEnv)
+> lookupLabelType = Map.findWithDefault []
 
 > initLabelEnv :: LabelEnv
-> initLabelEnv = emptyEnv
+> initLabelEnv = Map.empty
 
 
 \end{verbatim}
@@ -448,10 +331,10 @@
 
 > qualLookupCons :: QualIdent -> ValueEnv -> [ValueInfo]
 > qualLookupCons x tyEnv
->    | (maybe False ((==) preludeMIdent) mmid) && (id == consId)
+>    | maybe False ((==) preludeMIdent) mmid && id == consId
 >       = qualLookupTopEnv (qualify id) tyEnv
 >    | otherwise = []
->  where (mmid, id) = splitQualIdent x
+>  where (mmid, id) = (qualidMod x, qualidId x)
 
 > lookupTuple :: Ident -> [ValueInfo]
 > lookupTuple c
@@ -502,11 +385,11 @@
 
 > qualLookupConsArity :: QualIdent -> ArityEnv -> [ArityInfo]
 > qualLookupConsArity qid aEnv
->    | (maybe False ((==) preludeMIdent) mmid) && (id == consId)
+>    | maybe False ((==) preludeMIdent) mmid && id == consId
 >      = qualLookupTopEnv (qualify id) aEnv
 >    | otherwise
 >      = []
->  where (mmid, id) = splitQualIdent qid
+>  where (mmid, id) = (qualidMod qid, qualidId qid)
 
 > lookupTupleArity :: Ident -> [ArityInfo]
 > lookupTupleArity id 
@@ -519,17 +402,17 @@
 \paragraph{Module alias}
 \begin{verbatim}
 
-> type ImportEnv = Env ModuleIdent ModuleIdent
+> type ImportEnv = Map.Map ModuleIdent ModuleIdent
 
 > bindAlias :: Decl -> ImportEnv -> ImportEnv
-> bindAlias (ImportDecl _ mid _ mmid _) iEnv
->    = bindEnv mid (fromMaybe mid mmid) iEnv
+> bindAlias (ImportDecl _ mid _ mmid _)
+>    = Map.insert mid (fromMaybe mid mmid)
 
 > lookupAlias :: ModuleIdent -> ImportEnv -> Maybe ModuleIdent
-> lookupAlias = lookupEnv
+> lookupAlias = Map.lookup
 
 > sureLookupAlias :: ModuleIdent -> ImportEnv -> ModuleIdent
-> sureLookupAlias m iEnv = fromMaybe m (lookupAlias m iEnv)
+> sureLookupAlias m = fromMaybe m . lookupAlias m
 
 
 \end{verbatim}
@@ -595,14 +478,9 @@
 sufficient.
 \begin{verbatim}
 
-> type EvalEnv = Env Ident EvalAnnotation
+> type EvalEnv = Map.Map Ident EvalAnnotation
 
-> bindEval :: Ident -> EvalAnnotation -> EvalEnv -> EvalEnv
-> bindEval = bindEnv
 
-> lookupEval :: Ident -> EvalEnv -> Maybe EvalAnnotation
-> lookupEval f evEnv = lookupEnv f evEnv
-
 \end{verbatim}
 \paragraph{Predefined types}
 The list and unit data types must be predefined because their
@@ -627,18 +505,16 @@
 
 > initTCEnv :: TCEnv
 > initTCEnv = foldr (uncurry predefTC) emptyTopEnv predefTypes
->   where a = typeVar 0
->         predefTC (TypeConstructor tc tys) cs =
->           predefTopEnv (qualify (unqualify tc))
->                        (DataType tc (length tys) (map Just cs))
+>   where predefTC (TypeConstructor tc tys) =
+>           predefTopEnv (qualify (unqualify tc)) .
+>             DataType tc (length tys) . map Just
 
 > initDCEnv :: ValueEnv
 > initDCEnv =
 >   foldr (uncurry predefDC) emptyTopEnv
 >         [(c,constrType (polyType ty) n' tys)
 >         | (ty,cs) <- predefTypes, Data c n' tys <- cs]
->   where primTypes = map snd (moduleImports preludeMIdent initTCEnv)
->         predefDC c ty = predefTopEnv c' (DataConstructor c' ty)
+>   where predefDC c ty = predefTopEnv c' (DataConstructor c' ty)
 >           where c' = qualify c
 >         constrType (ForAll n ty) n' = ForAllExist n n' . foldr TypeArrow ty
 
@@ -646,11 +522,11 @@
 > initAEnv
 >    = foldr bindPredefArity emptyTopEnv (concatMap snd predefTypes)
 >  where
->  bindPredefArity (Data id _ ts) aEnv
->     = bindArity preludeMIdent id (length ts) aEnv
+>  bindPredefArity (Data id _ ts)
+>     = bindArity preludeMIdent id (length ts)
 
 > initIEnv :: ImportEnv
-> initIEnv = emptyEnv
+> initIEnv = Map.empty
 
 > predefTypes :: [(Type,[Data [Type]])]
 > predefTypes =
@@ -661,200 +537,7 @@
 
 
 \end{verbatim}
-\paragraph{Free and bound variables}
-The compiler needs to compute the sets of free and bound variables for
-various different entities. We will devote three type classes to that
-purpose. The \texttt{QualExpr} class is expected to take into account
-that it is possible to use a qualified name to refer to a function
-defined in the current module and therefore \emph{M.x} and $x$, where
-$M$ is the current module name, should be considered the same name.
-However note that this is correct only after renaming all local
-definitions as \emph{M.x} always denotes an entity defined at the
-top-level.
 
-The \texttt{Decl} instance of \texttt{QualExpr} returns all free
-variables on the right hand side, regardless of whether they are bound
-on the left hand side. This is more convenient as declarations are
-usually processed in a declaration group where the set of free
-variables cannot be computed independently for each declaration. Also
-note that the operator in a unary minus expression is not a free
-variable. This operator always refers to a global function from the
-prelude.
-\begin{verbatim}
-
-> class Expr e where
->   fv :: e -> [Ident]
-> class QualExpr e where
->   qfv :: ModuleIdent -> e -> [Ident]
-> class QuantExpr e where
->   bv :: e -> [Ident]
-
-> instance Expr e => Expr [e] where
->   fv = concat . map fv
-> instance QualExpr e => QualExpr [e] where
->   qfv m = concat . map (qfv m)
-> instance QuantExpr e => QuantExpr [e] where
->   bv = concat . map bv
-
-> instance QualExpr Decl where
->   qfv m (FunctionDecl _ _ eqs) = qfv m eqs
->   qfv m (PatternDecl _ _ rhs) = qfv m rhs
->   qfv _ _ = []
-
-> instance QuantExpr Decl where
->   bv (TypeSig _ vs _) = vs
->   bv (EvalAnnot _ fs _) = fs
->   bv (FunctionDecl _ f _) = [f]
->   bv (ExternalDecl _ _ _ f _) = [f]
->   bv (FlatExternalDecl _ fs) = fs
->   bv (PatternDecl _ t _) = bv t
->   bv (ExtraVariables _ vs) = vs
->   bv _ = []
-
-> instance QualExpr Equation where
->   qfv m (Equation _ lhs rhs) = filterBv lhs (qfv m lhs ++ qfv m rhs)
-
-> instance QuantExpr Lhs where
->   bv = bv . snd . flatLhs
-
-> instance QualExpr Lhs where
->   qfv m lhs = qfv m (snd (flatLhs lhs))
-
-> instance QualExpr Rhs where
->   qfv m (SimpleRhs _ e ds) = filterBv ds (qfv m e ++ qfv m ds)
->   qfv m (GuardedRhs es ds) = filterBv ds (qfv m es ++ qfv m ds)
-
-> instance QualExpr CondExpr where
->   qfv m (CondExpr _ g e) = qfv m g ++ qfv m e
-
-> instance QualExpr Expression where
->   qfv _ (Literal _) = []
->   qfv m (Variable v) = maybe [] return (localIdent m v)
->   qfv _ (Constructor _) = []
->   qfv m (Paren e) = qfv m e
->   qfv m (Typed e _) = qfv m e
->   qfv m (Tuple _ es) = qfv m es
->   qfv m (List _ es) = qfv m es
->   qfv m (ListCompr _ e qs) = foldr (qfvStmt m) (qfv m e) qs
->   qfv m (EnumFrom e) = qfv m e
->   qfv m (EnumFromThen e1 e2) = qfv m e1 ++ qfv m e2
->   qfv m (EnumFromTo e1 e2) = qfv m e1 ++ qfv m e2
->   qfv m (EnumFromThenTo e1 e2 e3) = qfv m e1 ++ qfv m e2 ++ qfv m e3
->   qfv m (UnaryMinus _ e) = qfv m e
->   qfv m (Apply e1 e2) = qfv m e1 ++ qfv m e2
->   qfv m (InfixApply e1 op e2) = qfv m op ++ qfv m e1 ++ qfv m e2
->   qfv m (LeftSection e op) = qfv m op ++ qfv m e
->   qfv m (RightSection op e) = qfv m op ++ qfv m e
->   qfv m (Lambda _ ts e) = filterBv ts (qfv m e)
->   qfv m (Let ds e) = filterBv ds (qfv m ds ++ qfv m e)
->   qfv m (Do sts e) = foldr (qfvStmt m) (qfv m e) sts
->   qfv m (IfThenElse _ e1 e2 e3) = qfv m e1 ++ qfv m e2 ++ qfv m e3
->   qfv m (Case _ e alts) = qfv m e ++ qfv m alts
->   qfv m (RecordConstr fs) = qfv m fs
->   qfv m (RecordSelection e _) = qfv m e
->   qfv m (RecordUpdate fs e) = qfv m e ++ qfv m fs
-
-> qfvStmt :: ModuleIdent -> Statement -> [Ident] -> [Ident]
-> qfvStmt m st fvs = qfv m st ++ filterBv st fvs
-
-> instance QualExpr Statement where
->   qfv m (StmtExpr _ e) = qfv m e
->   qfv m (StmtDecl ds) = filterBv ds (qfv m ds)
->   qfv m (StmtBind _ t e) = qfv m e
-
-> instance QualExpr Alt where
->   qfv m (Alt _ t rhs) = filterBv t (qfv m rhs)
-
-> instance QuantExpr a => QuantExpr (Field a) where
->   bv (Field _ _ t) = bv t
-
-> instance QualExpr a => QualExpr (Field a) where
->   qfv m (Field _ _ t) = qfv m t
-
-> instance QuantExpr Statement where
->   bv (StmtExpr _ e) = []
->   bv (StmtBind _ t e) = bv t
->   bv (StmtDecl ds) = bv ds
-
-> instance QualExpr InfixOp where
->   qfv m (InfixOp op) = qfv m (Variable op)
->   qfv _ (InfixConstr _) = []
-
-> instance QuantExpr ConstrTerm where
->   bv (LiteralPattern _) = []
->   bv (NegativePattern _ _) = []
->   bv (VariablePattern v) = [v]
->   bv (ConstructorPattern c ts) = bv ts
->   bv (InfixPattern t1 op t2) = bv t1 ++ bv t2
->   bv (ParenPattern t) = bv t
->   bv (TuplePattern _ ts) = bv ts
->   bv (ListPattern _ ts) = bv ts
->   bv (AsPattern v t) = v : bv t
->   bv (LazyPattern _ t) = bv t
->   bv (FunctionPattern f ts) = bvFuncPatt (FunctionPattern f ts)
->   bv (InfixFuncPattern t1 op t2) = bvFuncPatt (InfixFuncPattern t1 op t2)
->   bv (RecordPattern fs r) = (maybe [] bv r) ++ bv fs
-
-> instance QualExpr ConstrTerm where
->   qfv _ (LiteralPattern _) = []
->   qfv _ (NegativePattern _ _) = []
->   qfv _ (VariablePattern _) = []
->   qfv m (ConstructorPattern _ ts) = qfv m ts
->   qfv m (InfixPattern t1 _ t2) = qfv m [t1,t2]
->   qfv m (ParenPattern t) = qfv m t
->   qfv m (TuplePattern _ ts) = qfv m ts
->   qfv m (ListPattern _ ts) = qfv m ts
->   qfv m (AsPattern _ ts) = qfv m ts
->   qfv m (LazyPattern _ t) = qfv m t
->   qfv m (FunctionPattern f ts) 
->     = (maybe [] return (localIdent m f)) ++ qfv m ts
->   qfv m (InfixFuncPattern t1 op t2) 
->     = (maybe [] return (localIdent m op)) ++ qfv m [t1,t2]
->   qfv m (RecordPattern fs r) = (maybe [] (qfv m) r) ++ qfv m fs
-
-> instance Expr TypeExpr where
->   fv (ConstructorType _ tys) = fv tys
->   fv (VariableType tv)
->     | tv == anonId = []
->     | otherwise = [tv]
->   fv (TupleType tys) = fv tys
->   fv (ListType ty) = fv ty
->   fv (ArrowType ty1 ty2) = fv ty1 ++ fv ty2
->   fv (RecordType fs rty) = (maybe [] fv rty) ++ fv (map snd fs)
-
-> filterBv :: QuantExpr e => e -> [Ident] -> [Ident]
-> filterBv e = filter (`Set.notMember` Set.fromList (bv e))
-
-\end{verbatim}
-Since multiple variable occurrences are allowed in function patterns,
-it is necessary to compute the list of bound variables in a different way:
-Each variable occuring in the function pattern will be unique in the result
-list.
-\begin{verbatim}
-
-> bvFuncPatt :: ConstrTerm -> [Ident]
-> bvFuncPatt = bvfp []
->  where
->  bvfp bvs (LiteralPattern _) = bvs
->  bvfp bvs (NegativePattern _ _) = bvs
->  bvfp bvs (VariablePattern v)
->     | elem v bvs = bvs
->     | otherwise  = v:bvs
->  bvfp bvs (ConstructorPattern c ts) = foldl bvfp bvs ts
->  bvfp bvs (InfixPattern t1 op t2) = foldl bvfp bvs [t1,t2]
->  bvfp bvs (ParenPattern t) = bvfp bvs t
->  bvfp bvs (TuplePattern _ ts) = foldl bvfp bvs ts
->  bvfp bvs (ListPattern _ ts) = foldl bvfp bvs ts
->  bvfp bvs (AsPattern v t)
->     | elem v bvs = bvfp bvs t
->     | otherwise  = bvfp (v:bvs) t
->  bvfp bvs (LazyPattern _ t) = bvfp bvs t
->  bvfp bvs (FunctionPattern f ts) = foldl bvfp bvs ts
->  bvfp bvs (InfixFuncPattern t1 op t2) = foldl bvfp bvs [t1, t2]
->  bvfp bvs (RecordPattern fs r)
->     = foldl bvfp (maybe bvs (bvfp bvs) r) (map fieldTerm fs)
-
-\end{verbatim}
 \paragraph{Miscellany}
 Error handling
 \begin{verbatim}
@@ -937,18 +620,6 @@
 >   | x `elem` xs = NonLinear x
 >   | otherwise = linear xs
 > linear [] = Linear
-
-\end{verbatim}
-In order to give precise error messages on duplicate definitions of
-identifiers, the compiler pairs identifiers with their position in the
-source file when passing them to the function above. However, the
-position must be ignored when comparing two such pairs.
-\begin{verbatim}
-
-> data PIdent = PIdent Position Ident
-
-> instance Eq PIdent where
->   PIdent _ x == PIdent _ y = x == y
 
 \end{verbatim}
 
diff --git a/src/CaseCompletion.hs b/src/CaseCompletion.hs
--- a/src/CaseCompletion.hs
+++ b/src/CaseCompletion.hs
@@ -15,13 +15,14 @@
 
 import Data.Maybe
 
-import qualified CurrySyntax
+import Curry.Base.Position (SrcRef)
+import Curry.Base.Ident
+import qualified Curry.Syntax
+
 import Base (ModuleEnv, lookupModule)
-import IL
-import Ident
-import Position (SrcRef)
-import OldScopeEnv as ScopeEnv
-import ILScope
+import IL.Type
+import OldScopeEnv -- as ScopeEnv
+import IL.Scope
 
 
 
@@ -66,7 +67,7 @@
 visitDecl mod menv msgs senv (FunctionDecl qident params typeexpr expr)
    = ((FunctionDecl qident params typeexpr expr'), msgs)
  where
-   (expr', msgs',_) = visitExpr mod menv msgs (insertExprScope senv expr) expr
+   (expr', _, _) = visitExpr mod menv msgs (insertExprScope senv expr) expr
 
 visitDecl mod menv msgs senv (ExternalDecl qident cconv name typeexpr)
    = ((ExternalDecl qident cconv name typeexpr), msgs)
@@ -108,8 +109,8 @@
      = intError "visitExpr" "illegal alternative list"
  where
    altR           = head altsR
-   (expr', msgs1, senv1) = visitExpr mod menv msgs (insertExprScope senv expr) expr
-   (alts', msgs2, senv2) = visitListWithEnv (visitAlt mod menv) insertAltScope msgs senv1 alts
+   (expr', _, senv1) = visitExpr mod menv msgs (insertExprScope senv expr) expr
+   (alts', _, senv2) = visitListWithEnv (visitAlt mod menv) insertAltScope msgs senv1 alts
    (altsR, msgs3) = removeRedundantAlts msgs alts'
    (expr2, senv3) = completeConsAlts r mod menv senv2 evalannot expr' altsR
 
@@ -127,7 +128,7 @@
 visitExpr mod menv msgs senv (Let bind expr)
    = ((Let bind' expr'), msgs2, senv3)
  where
-   (expr', msgs1, senv2) = visitExpr mod menv msgs (insertExprScope senv expr) expr
+   (expr', _, senv2) = visitExpr mod menv msgs (insertExprScope senv expr) expr
    (bind', msgs2, senv3) = visitBinding mod menv msgs (insertBindingScope senv2 bind) bind
 
 visitExpr mod menv msgs senv (Letrec binds expr)
@@ -224,8 +225,8 @@
    p_getConsAltIdent (Alt (ConstructorPattern qident _) _) = qident
 
    p_genConstrTerm (qident, arity) (cconstrs,senv3) =
-       let args = ScopeEnv.genIdentList arity "x" senv3
-           senv4 = foldr ScopeEnv.insertIdent senv3 args
+       let args = OldScopeEnv.genIdentList arity "x" senv3
+           senv4 = foldr OldScopeEnv.insertIdent senv3 args
        in (ConstructorPattern qident args : cconstrs, senv4)
 
 
@@ -537,10 +538,10 @@
 	     (lookupModule mid' menv)
  where
    cons = head constrs
-   (mmid', _) = splitQualIdent cons
-   mid' = maybe mid id mmid'
 
+   mid' = fromMaybe mid (qualidMod cons)
 
+
 -- Find complementary constructors within the declarations of the
 -- current module
 getCCFromDecls :: ModuleIdent -> [QualIdent] -> [Decl] -> [(QualIdent, Int)]
@@ -570,7 +571,7 @@
 
 
 -- Find complementary constructors within the module environment
-getCCFromIDecls :: ModuleIdent -> [QualIdent] -> [CurrySyntax.IDecl] 
+getCCFromIDecls :: ModuleIdent -> [QualIdent] -> [Curry.Syntax.IDecl] 
 		   -> [(QualIdent, Int)]
 getCCFromIDecls mident constrs idecls
    = let
@@ -583,30 +584,30 @@
  where
    p_declaresIConstr qident idecl
       = case idecl of
-	  CurrySyntax.IDataDecl _ _ _ cdecls
+	  Curry.Syntax.IDataDecl _ _ _ cdecls
 	      -> any (p_isIConstrDecl qident) 
 		     (map fromJust (filter isJust cdecls))
-	  CurrySyntax.INewtypeDecl _ _ _ ncdecl 
+	  Curry.Syntax.INewtypeDecl _ _ _ ncdecl 
 	      -> p_isINewConstrDecl qident ncdecl
 	  _   -> False
 
-   p_isIConstrDecl qident (CurrySyntax.ConstrDecl _ _ ident _)
+   p_isIConstrDecl qident (Curry.Syntax.ConstrDecl _ _ ident _)
       = (unqualify qident) == ident
-   p_isIConstrDecl qident (CurrySyntax.ConOpDecl _ _ _ ident _)
+   p_isIConstrDecl qident (Curry.Syntax.ConOpDecl _ _ _ ident _)
       = (unqualify qident) == ident
 
-   p_isINewConstrDecl qident (CurrySyntax.NewConstrDecl _ _ ident _)
+   p_isINewConstrDecl qident (Curry.Syntax.NewConstrDecl _ _ ident _)
       = (unqualify qident) == ident
 
    p_extractIConstrDecls idecl
       = case idecl of
-	  CurrySyntax.IDataDecl _ _ _ cdecls 
+	  Curry.Syntax.IDataDecl _ _ _ cdecls 
 	      -> map fromJust (filter isJust cdecls)
 	  _   -> []
 
-   p_getIConstrDeclInfo mid (CurrySyntax.ConstrDecl _ _ ident types)
+   p_getIConstrDeclInfo mid (Curry.Syntax.ConstrDecl _ _ ident types)
       = (qualifyWith mid ident, length types)
-   p_getIConstrDeclInfo mid (CurrySyntax.ConOpDecl _ _ _ ident _)
+   p_getIConstrDeclInfo mid (Curry.Syntax.ConOpDecl _ _ _ ident _)
       = (qualifyWith mid ident, 2)
 
 
diff --git a/src/Combined.lhs b/src/Combined.lhs
deleted file mode 100644
--- a/src/Combined.lhs
+++ /dev/null
@@ -1,166 +0,0 @@
-% -*- LaTeX -*-
-% $Id: Combined.lhs,v 1.16 2003/05/07 22:38:37 wlux Exp $
-%
-% Copyright (c) 1998-2003, Wolfgang Lux
-% See LICENSE for the full license.
-%
-\nwfilename{Combined.lhs}
-\section{Combined monads}\label{sec:combined-monads}
-In this section we introduce combined monads which are parameterized
-by another monads. This technique has been explored
-in~\cite{KingWadler93:Combining} and very extensively
-in~\cite{LiangHudakJones95:ModInterp}. The monad transformers used in
-this report are mostly copied from the latter. Some restrictions were
-necessary because Haskell~98 does not support multi-parameter type
-classes. Especially, we cannot define generic lift operations because
-they have to be parameterized over two monad classes. In addition, we
-cannot define generic state and environment monad classes.
-\begin{verbatim}
-
-> module Combined where
-
-> import Control.Monad
-> import Control.Monad.Identity
-
-\end{verbatim}
-
-\subsection{State transformers}
-The state transformer monad is defined as usual, except that the
-result of the state transformer function is itself a monad. The
-unparameterized version is defined by using the identity monad
-\texttt{Id} for the base monad.
-\begin{verbatim}
-
-> newtype StateT s m a = StateT (s -> m (a,s))
-> type St s = StateT s Identity
-
-> unStateT :: StateT s m a -> (s -> m (a,s))
-> unStateT (StateT st) = st
-
-> instance Functor f => Functor (StateT s f) where
->   fmap f (StateT st) = StateT (fmap (\(x,s') -> (f x,s')) . st)
-
-> instance Monad m => Monad (StateT s m) where
->   return x = StateT (\s -> return (x,s))
->   StateT st >>= f = StateT (\s -> st s >>= \(x,s') -> unStateT (f x) s')
->   fail msg = StateT (const (fail msg))
-
-> instance MonadPlus m => MonadPlus (StateT s m) where
->   mzero = StateT (const mzero)
->   StateT st `mplus` StateT st' = StateT (\s -> st s `mplus` st' s)
-
-> liftSt :: Monad m => m a -> StateT s m a
-> liftSt m = StateT (\s -> m >>= \x -> return (x,s))
-
-> callSt :: Monad m => StateT s m a -> s -> m a
-> callSt (StateT st) s = st s >>= return . fst
-
-> runSt :: St s a -> s -> a
-> runSt st = runIdentity . callSt st
-
-\end{verbatim}
-In addition to the standard monad functions, state monads should
-provide means to fetch and change the state. With multi-parameter type
-classes, one could use the following class:
-\begin{verbatim}
-
-class Monad m => StateMonad s m where
-  update :: (s -> s) -> m s
-  fetch :: m s
-  change :: s -> m s
-
-  fetch = update id
-  change = update . const
-
-instance Monad m => StateMonad s (StateT s m) where
-  update f = StateT (\s -> return (s,f s))
-
-\end{verbatim}
-Unfortunately multi-parameter type classes are not available in
-Haskell~98. Therefore we define the corresponding instance functions
-for each state monad class separately. Here are the functions for the
-state transformers.
-\begin{verbatim}
-
-> updateSt :: Monad m => (s -> s) -> StateT s m s
-> updateSt f = StateT (\s -> return (s,f s))
-
-> updateSt_ :: Monad m => (s -> s) -> StateT s m ()
-> updateSt_ f = StateT (\s -> return ((),f s))
-
-> fetchSt :: Monad m => StateT s m s
-> fetchSt = updateSt id
-
-> changeSt :: Monad m => s -> StateT s m s
-> changeSt = updateSt . const
-
-\end{verbatim}
-Currying and uncurrying for state monads has been implemented
-in~\cite{Fokker95:JPEG}. Here we extend this implementation to the
-parametric monad classes.
-\begin{verbatim}
-
-> stCurry :: Monad m => StateT (s,t) m a -> t -> StateT s m (t,a)
-> stCurry (StateT st) t =
->   StateT (\s -> st (s,t) >>= \(x,(s',t')) -> return ((t',x),s'))
-
-> stUncurry :: Monad m => (t -> StateT s m (t,a)) -> StateT (s,t) m a
-> stUncurry f =
->   StateT (\(s,t) -> let (StateT st) = f t
->                     in st s >>= \((t',x),s') -> return (x,(s',t')))
-
-\end{verbatim}
-\subsection{Environment monad}
-A variant of the state transformer monad is the environment monad
-which is also known as (state) reader monad.
-\begin{verbatim}
-
-> data ReaderT r m a = ReaderT (r -> m a)
-> type Rt r a = ReaderT r Identity a
-
-> unReaderT :: ReaderT r m a -> (r -> m a)
-> unReaderT (ReaderT rt) = rt
-
-> instance Functor f => Functor (ReaderT r f) where
->   fmap f (ReaderT rt) = ReaderT (fmap f . rt)
-
-> instance Monad m => Monad (ReaderT r m) where
->   return x = ReaderT (\_ -> return x)
->   ReaderT rt >>= f = ReaderT (\r -> rt r >>= \x -> unReaderT (f x) r)
->   fail msg = ReaderT (const (fail msg))
-
-> instance MonadPlus m => MonadPlus (ReaderT r m) where
->   mzero = ReaderT (\_ -> mzero)
->   ReaderT rt `mplus` ReaderT rt' = ReaderT (\r -> rt r `mplus` rt' r)
-
-> liftRt :: Monad m => m a -> ReaderT r m a
-> liftRt m = ReaderT (\_ -> m)
-
-> callRt :: ReaderT r m a -> r -> m a
-> callRt (ReaderT rt) r = rt r
-
-> runRt :: Rt r a -> r -> a
-> runRt rt = runIdentity . callRt rt
-
-> envRt :: Monad m => ReaderT r m r
-> envRt = ReaderT return 
-
-\end{verbatim}
-Currying can also be applied to state reader monads.
-\begin{verbatim}
-
-> rtCurry :: Monad m => ReaderT (r,t) m a -> t -> ReaderT r m a
-> rtCurry (ReaderT rt) t = ReaderT (\r -> rt (r,t))
-
-> rtUncurry :: Monad m => (t -> ReaderT r m a) -> ReaderT (r,t) m a
-> rtUncurry f = ReaderT (\(r,t) -> let (ReaderT rt) = f t in rt r)
-
-\end{verbatim}
-A state reader transformer can be transformed trivially into a state
-transformer monad. This is handled by the combinator \texttt{ro}.
-\begin{verbatim}
-
-ro :: Monad m => ReaderT r m a -> StateT r m a
-ro (ReaderT rt) = StateT (\s -> rt s >>= \x -> return (x,s))
-
-\end{verbatim}
diff --git a/src/CompilerResults.hs b/src/CompilerResults.hs
deleted file mode 100644
--- a/src/CompilerResults.hs
+++ /dev/null
@@ -1,24 +0,0 @@
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
---
--- CompilerResult - Provides a record for dealing with compiler results.
---                
--- January 2006,
--- Martin Engelke (men@informatik.uni-kiel.de)
---
-module CompilerResults where
-
-
--------------------------------------------------------------------------------
-
---
-data CompilerResults
-   = CompilerResults{ unchangedIntf :: Maybe FilePath }
-
---
-defaultResults :: CompilerResults
-defaultResults = CompilerResults{ unchangedIntf = Nothing }
-
-
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
diff --git a/src/Curry/AbstractCurry.hs b/src/Curry/AbstractCurry.hs
new file mode 100644
--- /dev/null
+++ b/src/Curry/AbstractCurry.hs
@@ -0,0 +1,282 @@
+------------------------------------------------------------------------------
+--- Library to support meta-programming in Curry.
+---
+--- This library contains a definition for representing Curry programs
+--- in Curry (type "CurryProg") and an I/O action to read Curry programs and
+--- transform them into this abstract representation (function "readCurry").
+---
+--- Note this defines a slightly new format for AbstractCurry
+--- in comparison to the first proposal of 2003.
+---
+--- Assumption: an abstract Curry program is stored in file prog.acy
+---             and translated with the parser by "parsecurry -acy prog".
+---
+--- @author Michael Hanus
+--- @version April 2004
+---
+--- Version for Haskell (slightly modified):
+--- July 2005, Martin Engelke (men@informatik.uni-kiel.de)
+---
+------------------------------------------------------------------------------
+
+module Curry.AbstractCurry (CurryProg(..), QName, CLabel, CVisibility(..),
+		      CTVarIName, CTypeDecl(..), CConsDecl(..), CTypeExpr(..),
+                      COpDecl(..), CFixity(..), CVarIName,
+                      CFuncDecl(..), CRules(..), CEvalAnnot(..),
+                      CRule(..), CLocalDecl(..), CExpr(..), CStatement(..),
+                      CPattern(..), CBranchExpr(..), CLiteral(..),
+		      CField,
+                      readCurry, writeCurry) where
+
+import Data.List(intersperse)
+
+import PathUtils (writeModule,readModule)
+
+
+------------------------------------------------------------------------------
+-- Definition of data types for representing abstract Curry programs:
+-- ==================================================================
+
+--- Data type for representing a Curry module in the intermediate form.
+--- A value of this data type has the form
+--- <CODE>
+---  (CProg modname imports typedecls functions opdecls)
+--- </CODE>
+--- where modname: name of this module,
+---       imports: list of modules names that are imported,
+---       typedecls, opdecls, functions: see below
+
+data CurryProg = CurryProg String [String] [CTypeDecl] [CFuncDecl] [COpDecl]
+	         deriving (Read, Show)
+
+--- The data type for representing qualified names.
+--- In AbstractCurry all names are qualified to avoid name clashes.
+--- The first component is the module name and the second component the
+--- unqualified name as it occurs in the source program.
+type QName = (String,String)
+
+--- Type for representing label identifiers
+type CLabel = String
+
+-- Data type to specify the visibility of various entities.
+
+data CVisibility = Public    -- exported entity
+                 | Private   -- private entity
+		   deriving (Read, Show, Eq)
+
+
+--- The data type for representing type variables.
+--- They are represented by (i,n) where i is a type variable index
+--- which is unique inside a function and n is a name (if possible,
+--- the name written in the source program).
+type CTVarIName = (Int,String)
+
+--- Data type for representing definitions of algebraic data types
+--- and type synonyms.
+--- <PRE>
+--- A data type definition of the form
+---
+--- data t x1...xn = ...| c t1....tkc |...
+---
+--- is represented by the Curry term
+---
+--- (CType t v [i1,...,in] [...(CCons c kc v [t1,...,tkc])...])
+---
+--- where each ij is the index of the type variable xj
+---
+--- Note: the type variable indices are unique inside each type declaration
+---       and are usually numbered from 0
+---
+--- Thus, a data type declaration consists of the name of the data type,
+--- a list of type parameters and a list of constructor declarations.
+--- </PRE>
+
+data CTypeDecl = CType    QName CVisibility [CTVarIName] [CConsDecl]
+               | CTypeSyn QName CVisibility [CTVarIName] CTypeExpr
+		 deriving (Read, Show)
+
+
+--- A constructor declaration consists of the name and arity of the
+--- constructor and a list of the argument types of the constructor.
+
+data CConsDecl = CCons QName Int CVisibility [CTypeExpr]
+		 deriving (Read, Show)
+
+
+--- Data type for type expressions.
+--- A type expression is either a type variable, a function type,
+--- or a type constructor application.
+---
+--- Note: the names of the predefined type constructors are
+---       "Int", "Float", "Bool", "Char", "IO", "Success",
+---       "()" (unit type), "(,...,)" (tuple types), "[]" (list type)
+
+data CTypeExpr =
+    CTVar CTVarIName               -- type variable
+  | CFuncType CTypeExpr CTypeExpr  -- function type t1->t2
+  | CTCons QName [CTypeExpr]       -- type constructor application
+  | CRecordType [CField CTypeExpr] -- record type (extended Curry)
+                (Maybe CTVarIName)
+    deriving (Read, Show) 
+
+
+--- Data type for operator declarations.
+--- An operator declaration "fix p n" in Curry corresponds to the
+--- AbstractCurry term (COp n fix p).
+
+data COpDecl = COp QName CFixity Integer deriving (Read, Show)
+
+data CFixity = CInfixOp   -- non-associative infix operator
+             | CInfixlOp  -- left-associative infix operator
+             | CInfixrOp  -- right-associative infix operator
+	       deriving (Read, Show, Eq)
+
+
+--- Data types for representing object variables.
+--- Object variables occurring in expressions are represented by (Var i)
+--- where i is a variable index.
+
+type CVarIName = (Int,String)
+
+
+--- Data type for representing function declarations.
+--- <PRE>
+--- A function declaration in FlatCurry is a term of the form
+---
+---  (CFunc name arity visibility type (CRules eval [CRule rule1,...,rulek]))
+---
+--- and represents the function "name" with definition
+---
+---   name :: type
+---   rule1
+---   ...
+---   rulek
+---
+--- Note: the variable indices are unique inside each rule
+---
+--- External functions are represented as (CFunc name arity type (CExternal s))
+--- where s is the external name associated to this function.
+---
+--- Thus, a function declaration consists of the name, arity, type, and
+--- a list of rules.
+--- </PRE>
+
+data CFuncDecl = CFunc QName Int CVisibility CTypeExpr CRules
+	         deriving (Read, Show)
+
+
+--- A rule is either a list of formal parameters together with an expression
+--- (i.e., a rule in flat form), a list of general program rules with
+--- an evaluation annotation, or it is externally defined
+
+data CRules = CRules CEvalAnnot [CRule]
+            | CExternal String
+	      deriving (Read, Show)
+
+--- Data type for classifying evaluation annotations for functions.
+--- They can be either flexible (default), rigid, or choice.
+
+data CEvalAnnot = CFlex | CRigid | CChoice deriving (Read, Show, Eq)
+
+--- The most general form of a rule. It consists of a list of patterns
+--- (left-hand side), a list of guards ("success" if not present in the
+--- source text) with their corresponding right-hand sides, and
+--- a list of local declarations.
+data CRule = CRule [CPattern] [(CExpr,CExpr)] [CLocalDecl]
+	     deriving (Read, Show)
+
+--- Data type for representing local (let/where) declarations
+data CLocalDecl =
+     CLocalFunc CFuncDecl                   -- local function declaration
+   | CLocalPat  CPattern CExpr [CLocalDecl] -- local pattern declaration
+   | CLocalVar  CVarIName                   -- local free variable declaration
+     deriving (Read, Show)
+
+--- Data type for representing Curry expressions.
+
+data CExpr =
+   CVar       CVarIName             -- variable (unique index / name)
+ | CLit       CLiteral              -- literal (Integer/Float/Char constant)
+ | CSymbol    QName                 -- a defined symbol with module and name
+ | CApply     CExpr CExpr           -- application (e1 e2)
+ | CLambda    [CPattern] CExpr      -- lambda abstraction
+ | CLetDecl   [CLocalDecl] CExpr    -- local let declarations
+ | CDoExpr    [CStatement]          -- do expression
+ | CListComp  CExpr [CStatement]    -- list comprehension
+ | CCase      CExpr [CBranchExpr]   -- case expression
+ | CRecConstr [CField CExpr]        -- record construction (extended Curry)
+ | CRecSelect CExpr CLabel          -- field selection (extended Curry)
+ | CRecUpdate [CField CExpr] CExpr  -- record update (extended Curry)
+   deriving (Read, Show)
+
+--- Data type for representing statements in do expressions and
+--- list comprehensions.
+
+data CStatement = CSExpr CExpr         -- an expression (I/O action or boolean)
+                | CSPat CPattern CExpr -- a pattern definition
+                | CSLet [CLocalDecl]   -- a local let declaration
+		  deriving (Read, Show)
+
+--- Data type for representing pattern expressions.
+
+data CPattern =
+   CPVar CVarIName             -- pattern variable (unique index / name)
+ | CPLit CLiteral              -- literal (Integer/Float/Char constant)
+ | CPComb QName [CPattern]     -- application (m.c e1 ... en) of n-ary
+                               -- constructor m.c (CPComb (m,c) [e1,...,en])
+ | CPAs CVarIName CPattern     -- as-pattern (extended Curry)
+ | CPFuncComb QName [CPattern] -- function pattern (extended Curry)
+ | CPLazy CPattern             -- lazy pattern (extended Curry) 
+ | CPRecord [CField CPattern]  -- record pattern (extended curry)
+            (Maybe CPattern)
+   deriving (Read, Show)  
+
+--- Data type for representing branches in case expressions.
+
+data CBranchExpr = CBranch CPattern CExpr deriving (Read, Show)
+
+--- Data type for representing literals occurring in an expression.
+--- It is either an integer, a float, or a character constant.
+--- Note: the constructor definition of 'CIntc' differs from the original
+--- PAKCS definition. It uses Haskell type 'Integer' instead of 'Int'
+--- to provide an unlimited range of integer numbers. Furthermore
+--- float values are represented with Haskell type 'Double' instead of
+--- 'Float'.
+
+data CLiteral = CIntc   Integer
+              | CFloatc Double
+              | CCharc  Char
+		deriving (Read, Show, Eq)
+
+--- Type for representing labeled fields
+
+type CField a = (CLabel,a)
+
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+
+-- Reads an AbstractCurry file and returns the corresponding AbstractCurry
+-- program term (type 'CurryProg')
+readCurry :: String -> IO CurryProg
+readCurry filename
+   = do file <- readModule filename
+	let prog = (read file) :: CurryProg
+	return prog
+
+-- Writes an AbstractCurry program term into a file
+writeCurry :: String -> CurryProg -> IO ()
+writeCurry filename prog 
+   = catch (writeModule filename (showCurry prog)) (\e -> ioError e)
+
+-- Shows an AbstractCurry program in a more nicely way.
+showCurry :: CurryProg -> String
+showCurry (CurryProg mname imps types funcs ops) =
+  "CurryProg "++show mname++"\n "++
+  show imps ++"\n ["++
+  concat (intersperse ",\n  " (map (\t->show t) types)) ++"]\n ["++
+  concat (intersperse ",\n  " (map (\f->show f) funcs)) ++"]\n "++
+  show ops ++"\n"
+  
+
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
diff --git a/src/Curry/Base/Ident.lhs b/src/Curry/Base/Ident.lhs
new file mode 100644
--- /dev/null
+++ b/src/Curry/Base/Ident.lhs
@@ -0,0 +1,352 @@
+> {-# LANGUAGE DeriveDataTypeable #-}
+
+% $Id: Ident.lhs,v 1.21 2004/10/29 13:08:09 wlux Exp $
+%
+% Copyright (c) 1999-2004, Wolfgang Lux
+% See LICENSE for the full license.
+%
+\nwfilename{Ident.lhs}
+\section{Identifiers}
+This module provides the implementation of identifiers and some
+utility functions for identifiers, which are used at various places in
+the compiler.
+
+Identifiers comprise the name of the denoted entity and an \emph{id},
+which can be used for renaming identifiers, e.g., in order to resolve
+name conflicts between identifiers from different scopes. An
+identifier with an \emph{id} $0$ is considered as not being renamed
+and, hence, its \emph{id} will not be shown.
+
+\ToDo{Probably we should use \texttt{Integer} for the \emph{id}s.}
+
+Qualified identifiers may optionally be prefixed by a module
+name. \textbf{The order of the cases \texttt{UnqualIdent} and
+\texttt{QualIdent} is important. Some parts of the compiler rely on
+the fact that all qualified identifiers are greater than any
+unqualified identifier.}
+\begin{verbatim}
+
+> module Curry.Base.Ident(Ident(..), showIdent,
+>                         QualIdent(..),ModuleIdent(..),SrcRefOf(..),
+>                         mkIdent, qualName,
+>                         renameIdent, unRenameIdent,
+>                         mkMIdent, moduleName,
+>                         isInfixOp, isQInfixOp,
+>                         qualify, qualifyWith, qualQualify,
+>                         isQualified, unqualify, qualUnqualify,
+>                         localIdent, -- splitQualIdent,
+>                         emptyMIdent, mainMIdent,preludeMIdent,
+>                         anonId,unitId,boolId,charId,intId,floatId,listId,ioId,
+>                         successId,trueId,falseId,nilId,consId,mainId,
+>                         tupleId,isTupleId,tupleArity,
+>                         minusId,fminusId,updIdentName,
+>                         qUnitId,qBoolId,qCharId,qIntId,qFloatId,qListId,qIOId,
+>                         qSuccessId,qTrueId,qFalseId,qNilId,qConsId,
+>                         qTupleId,isQTupleId,qTupleArity,
+>                         fpSelectorId,isFpSelectorId,isQualFpSelectorId,
+>                         recSelectorId,qualRecSelectorId,
+>                         recUpdateId, qualRecUpdateId, recordExtId, labelExtId,
+>                         isRecordExtId, isLabelExtId, fromRecordExtId, fromLabelExtId,
+>                         renameLabel,
+>                         recordExt, labelExt, mkLabelIdent,-- hasPositionIdent,
+>                         addPositionIdent, 
+>                         addPositionModuleIdent,addRef,addRefId,
+>                         positionOfQualIdent,updQualIdent ) where
+
+> import Control.Monad(liftM)
+> import Data.Char
+> import Data.List
+> import Data.Maybe
+> import Data.Generics
+> import Data.Function(on)
+
+> import Curry.Base.Position
+
+
+Simple identifiers
+
+> data Ident = Ident { positionOfIdent :: Position,
+>                      name :: String,
+>                      uniqueId :: Int }
+>              deriving (Read, Data, Typeable)
+>
+> instance Eq Ident where
+>     Ident _ m i == Ident _ n j = (m,i) == (n, j)
+>
+> instance Ord Ident where
+>     Ident _ m i `compare` Ident _ n j = (m,i) `compare` (n, j)
+>
+> instance Show Ident where
+>     show = showIdent
+>
+> showIdent :: Ident -> String
+> showIdent  (Ident _ x 0) = x
+> showIdent  (Ident _ x n) = x ++ '.' : show n
+
+
+Qualified identifiers
+
+> data QualIdent = QualIdent { qualidMod :: Maybe ModuleIdent,
+>                              qualidId:: Ident }
+>                  deriving (Eq, Ord, Read, Data,Typeable)
+
+> qualName :: QualIdent -> String
+> qualName (QualIdent Nothing x) = name x
+> qualName (QualIdent (Just m) x) = moduleName m ++ "." ++ name x
+
+> instance Show QualIdent where
+>     show = qualName
+
+Module names
+
+> data ModuleIdent = ModuleIdent { positionOfModuleIdent :: Position,
+>                                  moduleQualifiers :: [String] }
+>                    deriving (Read, Data,Typeable)
+
+> instance Eq ModuleIdent where
+>    (==) = (==) `on` moduleQualifiers
+
+> instance Ord ModuleIdent where
+>    compare = compare `on` moduleQualifiers
+
+> moduleName :: ModuleIdent -> String
+> moduleName = concat . intersperse "." . moduleQualifiers
+
+> instance Show ModuleIdent where
+>     show = moduleName
+
+-- -----------------------------------------
+
+> addPositionIdent :: Position -> Ident -> Ident
+> addPositionIdent pos (Ident NoPos x n) = Ident pos x n
+> addPositionIdent AST{ast=sr} (Ident pos x n)
+>     =  Ident pos{ast=sr} x n
+> addPositionIdent pos (Ident _ x n) = Ident pos x n
+
+> addPositionModuleIdent :: Position -> ModuleIdent -> ModuleIdent
+> addPositionModuleIdent pos (ModuleIdent _ x) = ModuleIdent pos x 
+
+> positionOfQualIdent :: QualIdent -> Position
+> positionOfQualIdent = positionOfIdent . qualidId
+
+> mkIdent :: String -> Ident
+> mkIdent x = Ident NoPos x 0
+
+> renameIdent :: Ident -> Int -> Ident
+> renameIdent (Ident p x _) n = Ident p x n
+
+
+> unRenameIdent :: Ident -> Ident
+> unRenameIdent (Ident p x _) = Ident p x 0
+
+> mkMIdent :: [String] -> ModuleIdent
+> mkMIdent = ModuleIdent NoPos
+
+> isInfixOp :: Ident -> Bool
+> isInfixOp (Ident _ ('<':c:cs) _)=
+>   last (c:cs) /= '>' || not (isAlphaNum c) && c `notElem` "_(["
+> isInfixOp (Ident _ (c:_) _) = not (isAlphaNum c) && c `notElem` "_(["
+> isInfixOp (Ident _ _ _) = False -- error "Zero-length identifier"
+
+> isQInfixOp :: QualIdent -> Bool
+> isQInfixOp (QualIdent _ x) = isInfixOp x
+
+\end{verbatim}
+The functions \texttt{qualify} and \texttt{qualifyWith} convert an
+unqualified identifier into a qualified identifier (without and with a
+given module prefix, respectively).
+\begin{verbatim}
+
+> qualify :: Ident -> QualIdent
+> qualify = QualIdent Nothing
+
+> qualifyWith :: ModuleIdent -> Ident -> QualIdent
+> qualifyWith = QualIdent . Just
+
+> qualQualify :: ModuleIdent -> QualIdent -> QualIdent
+> qualQualify m (QualIdent Nothing x) = QualIdent (Just m) x
+> qualQualify _ x = x
+
+> isQualified :: QualIdent -> Bool
+> isQualified (QualIdent m _) = isJust m
+
+> unqualify :: QualIdent -> Ident
+> unqualify (QualIdent _ x) = x
+
+> qualUnqualify :: ModuleIdent -> QualIdent -> QualIdent
+> qualUnqualify m qid@(QualIdent Nothing x) = qid
+> qualUnqualify m (QualIdent (Just m') x) = QualIdent m'' x
+>     where m'' | m == m' = Nothing
+>               | otherwise    = Just m'
+
+> localIdent :: ModuleIdent -> QualIdent -> Maybe Ident
+> localIdent _ (QualIdent Nothing x) = Just x
+> localIdent m (QualIdent (Just m') x)
+>   | m == m' = Just x
+>   | otherwise = Nothing
+
+> splitQualIdent :: QualIdent -> (Maybe ModuleIdent,Ident)
+> splitQualIdent (QualIdent m x) = (m,x)
+
+> updQualIdent :: (ModuleIdent -> ModuleIdent) -> (Ident -> Ident) -> QualIdent -> QualIdent
+> updQualIdent f g (QualIdent m x) = QualIdent (liftM f m) (g x)
+
+> addRef :: SrcRef -> QualIdent -> QualIdent
+> addRef r = updQualIdent id (addRefId r)
+
+> addRefId :: SrcRef -> Ident -> Ident
+> addRefId = addPositionIdent . AST
+
+\end{verbatim}
+A few identifiers a predefined here.
+\begin{verbatim}
+
+> emptyMIdent, mainMIdent, preludeMIdent :: ModuleIdent
+> emptyMIdent   = ModuleIdent NoPos []
+> mainMIdent    = ModuleIdent NoPos ["main"]
+> preludeMIdent = ModuleIdent NoPos ["Prelude"]
+
+> anonId :: Ident
+> anonId = Ident NoPos "_" 0
+
+> unitId, boolId, charId, intId, floatId, listId, ioId, successId :: Ident
+> unitId    = Ident NoPos "()" 0
+> boolId    = Ident NoPos "Bool" 0
+> charId    = Ident NoPos "Char" 0
+> intId     = Ident NoPos "Int" 0
+> floatId   = Ident NoPos "Float" 0
+> listId    = Ident NoPos "[]" 0
+> ioId      = Ident NoPos "IO" 0
+> successId = Ident NoPos "Success" 0
+
+> trueId, falseId, nilId, consId :: Ident
+> trueId  = Ident NoPos "True" 0
+> falseId = Ident NoPos "False" 0
+> nilId   = Ident NoPos "[]" 0
+> consId  = Ident NoPos ":" 0
+
+> tupleId :: Int -> Ident
+> tupleId n
+>   | n >= 2 = Ident NoPos ("(" ++ replicate (n - 1) ',' ++ ")") 0
+>   | otherwise = error "internal error: tupleId"
+
+> isTupleId :: Ident -> Bool
+> isTupleId x = n > 1 && x == tupleId n
+>   where n = length (name x) - 1
+
+> tupleArity :: Ident -> Int
+> tupleArity x
+>   | n > 1 && x == tupleId n = n
+>   | otherwise = error "internal error: tupleArity"
+>   where n = length (name x) - 1
+
+> mainId, minusId, fminusId :: Ident
+> mainId = Ident NoPos "main" 0
+> minusId = Ident NoPos "-" 0
+> fminusId = Ident NoPos "-." 0
+
+> qUnitId, qNilId, qConsId, qListId :: QualIdent
+> qUnitId = QualIdent Nothing unitId
+> qListId = QualIdent Nothing listId
+> qNilId  = QualIdent Nothing nilId
+> qConsId = QualIdent Nothing consId
+
+> qBoolId, qCharId, qIntId, qFloatId, qSuccessId, qIOId :: QualIdent
+> qBoolId = QualIdent (Just preludeMIdent) boolId
+> qCharId = QualIdent (Just preludeMIdent) charId
+> qIntId = QualIdent (Just preludeMIdent) intId
+> qFloatId = QualIdent (Just preludeMIdent) floatId
+> qSuccessId = QualIdent (Just preludeMIdent) successId
+> qIOId = QualIdent (Just preludeMIdent) ioId
+
+> qTrueId, qFalseId :: QualIdent
+> qTrueId = QualIdent (Just preludeMIdent) trueId
+> qFalseId = QualIdent (Just preludeMIdent) falseId
+
+> qTupleId :: Int -> QualIdent
+> qTupleId = QualIdent Nothing . tupleId
+
+> isQTupleId :: QualIdent -> Bool
+> isQTupleId = isTupleId . unqualify
+
+> qTupleArity :: QualIdent -> Int
+> qTupleArity = tupleArity . unqualify
+
+\end{verbatim}
+Micellaneous function for generating and testing extended identifiers.
+\begin{verbatim}
+
+> fpSelectorId :: Int -> Ident
+> fpSelectorId n = Ident NoPos (fpSelExt ++ show n) 0
+
+> isFpSelectorId :: Ident -> Bool
+> isFpSelectorId f = any (fpSelExt `isPrefixOf`) (tails (name f))
+
+> isQualFpSelectorId :: QualIdent -> Bool
+> isQualFpSelectorId = isFpSelectorId . unqualify
+
+> recSelectorId :: QualIdent -> Ident -> Ident
+> recSelectorId r l =
+>   mkIdent (recSelExt ++ name (unqualify r) ++ "." ++ name l)
+
+> qualRecSelectorId :: ModuleIdent -> QualIdent -> Ident -> QualIdent
+> qualRecSelectorId m r l = qualifyWith m' (recSelectorId r l)
+>   where m' = (fromMaybe m (fst (splitQualIdent r)))
+
+> recUpdateId :: QualIdent -> Ident -> Ident
+> recUpdateId r l = 
+>   mkIdent (recUpdExt ++ name (unqualify r) ++ "." ++ name l)
+
+> qualRecUpdateId :: ModuleIdent -> QualIdent -> Ident -> QualIdent
+> qualRecUpdateId m r l = qualifyWith m' (recUpdateId r l)
+>   where m' = (fromMaybe m (fst (splitQualIdent r)))
+
+> recordExtId :: Ident -> Ident
+> recordExtId r = mkIdent (recordExt ++ name r)
+
+> labelExtId :: Ident -> Ident
+> labelExtId l = mkIdent (labelExt ++ name l)
+
+> fromRecordExtId :: Ident -> Ident
+> fromRecordExtId r 
+>   | p == recordExt = mkIdent r'
+>   | otherwise = r
+>  where (p,r') = splitAt (length recordExt) (name r)
+
+> fromLabelExtId :: Ident -> Ident
+> fromLabelExtId l 
+>   | p == labelExt = mkIdent l'
+>   | otherwise = l
+>  where (p,l') = splitAt (length labelExt) (name l)
+
+> isRecordExtId :: Ident -> Bool
+> isRecordExtId r = recordExt `isPrefixOf` name r
+
+> isLabelExtId :: Ident -> Bool
+> isLabelExtId l = labelExt `isPrefixOf` name l
+
+> mkLabelIdent :: String -> Ident
+> mkLabelIdent c = renameIdent (mkIdent c) (-1)
+
+> renameLabel :: Ident -> Ident
+> renameLabel l = renameIdent l (-1)
+
+
+> fpSelExt = "_#selFP"
+> recSelExt = "_#selR@"
+> recUpdExt = "_#updR@"
+> recordExt = "_#Rec:"
+> labelExt = "_#Lab:"
+
+
+> instance SrcRefOf Ident where
+>     srcRefOf = srcRefOf . positionOfIdent
+
+> instance SrcRefOf QualIdent where
+>     srcRefOf = srcRefOf . unqualify
+
+> updIdentName :: (String -> String) -> Ident -> Ident
+> updIdentName f ident = let p=positionOfIdent ident
+>                            i=uniqueId ident
+>                            n=name ident in
+>   addPositionIdent p $ flip renameIdent i $ mkIdent (f n)
diff --git a/src/Curry/Base/MessageMonad.hs b/src/Curry/Base/MessageMonad.hs
new file mode 100644
--- /dev/null
+++ b/src/Curry/Base/MessageMonad.hs
@@ -0,0 +1,83 @@
+{-# LANGUAGE FlexibleContexts #-}
+{-
+  The \texttt{MsgMonad} type is used for describing the result of a
+  computation that can fail. In contrast to the standard \texttt{Maybe}
+  type, its \texttt{Error} case provides for an error message that
+  describes the failure.
+-}
+
+module Curry.Base.MessageMonad where
+
+import Control.Monad.Error
+import Control.Monad.Writer
+import Control.Monad.Identity
+
+import Curry.Base.Position
+
+
+type MsgMonadT m = ErrorT WarnMsg (WriterT [WarnMsg] m)
+
+type MsgMonad = MsgMonadT Identity
+
+type MsgMonadIO = MsgMonadT IO
+
+data WarnMsg = WarnMsg { warnPos :: Maybe Position,
+                         warnTxt :: String
+                       }
+instance Error WarnMsg where
+    noMsg = WarnMsg Nothing "Failure!"
+    strMsg = WarnMsg Nothing
+
+instance Show WarnMsg where
+    show = showWarning
+
+-- tell w = Control.Monad.Writer.tell w
+
+showWarning w = "Warning: " ++ pos ++ warnTxt w
+    where pos = case warnPos w of
+                  Nothing -> ""
+                  Just p -> show p ++": "
+
+showError w = "Error: " ++ pos ++ warnTxt w
+    where pos = case warnPos w of
+                  Nothing -> ""
+                  Just p -> show p ++": "
+
+ok :: MsgMonad a -> a
+ok = either (error . showError) id . fst . runMsg
+
+
+failWith :: (MonadError a m, Error a) => String -> m a1
+failWith = throwError . strMsg
+
+
+failWithAt :: (MonadError WarnMsg m) => Position -> String -> m a
+failWithAt p s  = throwError (WarnMsg (Just p) s)
+
+
+warnMessage :: (MonadWriter [WarnMsg] m) => String -> m ()
+warnMessage s = tell [WarnMsg Nothing s]
+
+
+warnMessageAt :: (MonadWriter [WarnMsg] m) => Position -> String -> m ()
+warnMessageAt p s  = tell [WarnMsg (Just p) s]
+
+runMsg :: MsgMonad a -> (Either WarnMsg a, [WarnMsg])
+runMsg = runIdentity . runWriterT . runErrorT
+
+-- returnIO :: MsgMonad a -> MsgMonadIO a
+-- returnIO x = return$ (runIdentity . runWriterT . runErrorT) x
+
+runMsgIO :: MsgMonad a -> (a -> IO (MsgMonad b)) -> IO (MsgMonad b)
+runMsgIO m f
+    = case runMsg m of
+        (Left e, msgs) -> return (tell msgs >> throwError e)
+        (Right x, msgs) -> do m' <- f x
+                              case runMsg m' of
+                                (Left _,_) -> return m'
+                                (Right x', msgs') -> return (tell (msgs ++ msgs') >> return x')
+
+dropIO :: MsgMonad a -> MsgMonadIO a
+dropIO x = case runMsg x of
+             (Left e, m) -> tell m >> throwError e
+             (Right x, m) -> tell m >> return x
diff --git a/src/Curry/Base/Position.lhs b/src/Curry/Base/Position.lhs
new file mode 100644
--- /dev/null
+++ b/src/Curry/Base/Position.lhs
@@ -0,0 +1,96 @@
+> {-# LANGUAGE DeriveDataTypeable #-}
+
+% -*- LaTeX -*-
+% $Id: Position.lhs,v 1.2 2000/10/08 09:55:43 lux Exp $
+%
+% $Log: Position.lhs,v $
+% Revision 1.2  2000/10/08 09:55:43  lux
+% Column numbers now start at 1. If the column number is less than 1 it
+% will not be shown.
+%
+% Revision 1.1  2000/07/23 11:03:37  lux
+% Positions now implemented in a separate module.
+%
+%
+\nwfilename{Position.lhs}
+\section{Positions}
+A source file position consists of a filename, a line number, and a
+column number. A tab stop is assumed at every eighth column.
+\begin{verbatim}
+
+> module Curry.Base.Position where
+> import Data.Generics
+
+> newtype SrcRef = SrcRef [Int] deriving (Typeable,Data) -- a pointer to the origin
+
+-- the instances for standard classes or such that SrcRefs are invisible
+
+> instance Show SrcRef where show _ = ""
+> instance Read SrcRef where readsPrec _ s = [(noRef,s)]
+> instance Eq SrcRef   where _ == _ = True
+> instance Ord SrcRef  where compare _ _ = EQ
+
+> noRef :: SrcRef
+> noRef = SrcRef []
+>
+> incSrcRef :: SrcRef -> Int -> SrcRef
+> incSrcRef (SrcRef [i]) j = SrcRef [i+j]
+> incSrcRef is  _ = error $ "internal error; increment source ref: " ++ show is
+
+> data Position 
+>   = Position{ file :: FilePath, line :: Int, column :: Int, ast :: SrcRef }
+>   | AST { ast :: SrcRef }
+>   | NoPos
+>     deriving (Eq, Ord,Data,Typeable)
+
+> incPosition :: Position -> Int -> Position
+> incPosition p j = p{ast=incSrcRef (ast p) j}
+
+> instance Read Position where
+>   readsPrec p s = 
+>     [ (Position{file="",line=i,column=j,ast=noRef},s')  | ((i,j),s') <- readsPrec p s]
+
+> instance Show Position where
+>   showsPrec _ Position{file=fn,line=l,column=c} =
+>     (if null fn then id else shows fn . showString ", ") .
+>     showString "line " . shows l .
+>     (if c > 0 then showChar '.' . shows c else id)
+>   showsPrec _ AST{} = id
+>   showsPrec _ NoPos = id
+
+> tabWidth :: Int
+> tabWidth = 8
+
+> first :: FilePath -> Position
+> first fn = Position fn 1 1 noRef
+
+> incr :: Position -> Int -> Position
+> incr p@Position{column=c} n = p{column=c + n}
+> incr p _ = p
+
+> next :: Position -> Position
+> next = flip incr 1
+
+> tab :: Position -> Position
+> tab p@Position{column=c} = p{column=c + tabWidth - (c - 1) `mod` tabWidth}
+> tab p = p
+
+> nl :: Position -> Position
+> nl p@Position{line=l} = p{line=l + 1, column=1}
+> nl p = p
+
+> showLine :: Position -> String
+> showLine NoPos = ""
+> showLine AST{} = ""
+> showLine Position{line=l,column=c} 
+>     = "(line " ++ show l ++ "." ++ show c ++ ") "
+
+\end{verbatim}
+
+> class SrcRefOf a where
+>   srcRefsOf :: a -> [SrcRef]
+>   srcRefsOf = (:[]) . srcRefOf
+>   srcRefOf :: a -> SrcRef
+>   srcRefOf = head . srcRefsOf
+
+> instance SrcRefOf Position where srcRefOf = ast
diff --git a/src/Curry/ExtendedFlat.hs b/src/Curry/ExtendedFlat.hs
new file mode 100644
--- /dev/null
+++ b/src/Curry/ExtendedFlat.hs
@@ -0,0 +1,475 @@
+------------------------------------------------------------------------------
+--- Library to support meta-programming in Curry.
+---
+--- This library contains a definition for representing FlatCurry programs
+--- in Haskell (type "Prog").
+---
+--- @author Michael Hanus
+--- @version September 2003
+---
+--- Version for Haskell (slightly modified):
+---  December 2004, Martin Engelke (men@informatik.uni-kiel.de)
+---
+--- Added part calls for constructors, Bernd Brassel, August 2005
+--- Added source references, Bernd Brassel, May 2009
+------------------------------------------------------------------------------
+
+{-# LANGUAGE DeriveDataTypeable, RankNTypes #-}
+
+module Curry.ExtendedFlat (SrcRef,Prog(..),
+                           QName(..), qnOf,mkQName,
+                           Visibility(..),
+                           TVarIndex, TypeDecl(..), ConsDecl(..), TypeExpr(..),
+                           OpDecl(..), Fixity(..),
+                           VarIndex(..), mkIdx,
+                           FuncDecl(..), Rule(..), 
+                           CaseType(..), CombType(..), Expr(..), BranchExpr(..),
+                           Pattern(..), Literal(..), 
+		           readFlatCurry, readFlatInterface, readFlat, 
+		           writeFlatCurry,writeExtendedFlat,gshowsPrec
+                          ) where
+
+import Data.List(intersperse)
+import Control.Monad (liftM)
+import Data.Generics hiding (Fixity)
+import Data.Function(on)
+import System.FilePath
+
+import PathUtils (writeModule, maybeReadModule)
+import Filenames(flatName)
+import Curry.Base.Position (SrcRef)
+
+------------------------------------------------------------------------------
+-- Definition of data types for representing FlatCurry programs:
+-- =============================================================
+
+--- Data type for representing a Curry module in the intermediate form.
+--- A value of this data type has the form
+--- <CODE>
+---  (Prog modname imports typedecls functions opdecls translation_table)
+--- </CODE>
+--- where modname: name of this module,
+---       imports: list of modules names that are imported,
+---       typedecls, opdecls, functions, translation of type names
+---       and constructor/function names: see below
+
+data Prog = Prog String [String] [TypeDecl] [FuncDecl] [OpDecl] 
+	    deriving (Read, Show, Eq,Data,Typeable)
+
+
+-------------------------------------------------------------------------
+--- The data type for representing qualified names.
+--- In FlatCurry all names are qualified to avoid name clashes.
+--- The first component is the module name and the second component the
+--- unqualified name as it occurs in the source program.
+--- The additional information about source references and types should
+--- be invisible for the normal usage of QName.
+-------------------------------------------------------------------------
+
+data QName = QName {srcRef      :: Maybe SrcRef,
+                    typeofQName :: Maybe TypeExpr,
+                    modName     :: String,
+                    localName   :: String} deriving (Data,Typeable)
+
+
+instance Read QName where
+  readsPrec d r = 
+       [ (mkQName nm,s) | (nm,s) <- readsPrec d r ]
+    ++ [ (QName r t m n, s) | ((r, t, m, n),s) <- readsPrec d r ]
+
+instance Show QName where
+  showsPrec d (QName r t m n)
+      = showsPrec d (r,t,m,n)
+
+instance Eq QName where (==) = (==) `on` qnOf
+
+instance Ord QName where compare = compare `on` qnOf
+
+mkQName :: (String,String) -> QName
+mkQName = uncurry (QName Nothing Nothing)
+
+qnOf :: QName -> (String,String) 
+qnOf QName{modName=m,localName=n} = (m,n)
+
+
+-------------------------------------------------------------------------
+--- The data type for representing variable names.
+--- The additional information should
+--- be invisible for the normal usage of VarIndex.
+-------------------------------------------------------------------------
+
+data VarIndex = VarIndex {
+                    typeofVar :: Maybe TypeExpr,
+                    idxOf     :: Int
+                } deriving (Data,Typeable)
+
+onIndex :: (Int -> Int) -> VarIndex -> VarIndex
+onIndex f (VarIndex{ typeofVar = t, idxOf = x})
+    = VarIndex t (f x)
+
+onIndexes :: (Int ->Int -> Int) -> VarIndex -> VarIndex -> VarIndex
+onIndexes g x = VarIndex (typeofVar x) . (g `on` idxOf) x
+
+mkIdx :: Int -> VarIndex
+mkIdx = VarIndex Nothing
+
+
+instance Read VarIndex where
+  readsPrec d r = 
+       [ (mkIdx i,s) | (i,s) <- readsPrec d r ]
+    ++ [ (VarIndex t i,s) | ((t,i),s) <- readsPrec d r ]
+
+instance Show VarIndex where
+  showsPrec d (VarIndex t i)= showsPrec d (t,i)
+
+instance Eq VarIndex where
+    (==) = (==) `on` idxOf
+
+instance Ord VarIndex where
+    compare = compare `on` idxOf
+
+instance Num VarIndex where
+  (+) = onIndexes  (+)
+  (*) = onIndexes  (*)
+  (-) = onIndexes  (-)
+  abs = onIndex abs
+  signum = onIndex signum
+  fromInteger = mkIdx . fromInteger
+
+------------------------------------------------------------
+--- Data type to specify the visibility of various entities.
+------------------------------------------------------------
+
+data Visibility = Public    -- public (exported) entity
+                | Private   -- private entity
+		deriving (Read, Show, Eq,Data,Typeable)
+
+--- The data type for representing type variables.
+--- They are represented by (TVar i) where i is a type variable index.
+
+type TVarIndex = Int
+
+--- Data type for representing definitions of algebraic data types.
+--- <PRE>
+--- A data type definition of the form
+---
+--- data t x1...xn = ...| c t1....tkc |...
+---
+--- is represented by the FlatCurry term
+---
+--- (Type t [i1,...,in] [...(Cons c kc [t1,...,tkc])...])
+---
+--- where each ij is the index of the type variable xj
+---
+--- Note: the type variable indices are unique inside each type declaration
+---       and are usually numbered from 0
+---
+--- Thus, a data type declaration consists of the name of the data type,
+--- a list of type parameters and a list of constructor declarations.
+--- </PRE>
+
+data TypeDecl = Type    QName Visibility [TVarIndex] [ConsDecl]
+              | TypeSyn QName Visibility [TVarIndex] TypeExpr
+	      deriving (Read, Show, Eq,Data,Typeable)
+
+--- A constructor declaration consists of the name and arity of the
+--- constructor and a list of the argument types of the constructor.
+
+data ConsDecl = Cons QName Int Visibility [TypeExpr]
+	      deriving (Read, Show, Eq,Data,Typeable)
+
+
+--- Data type for type expressions.
+--- A type expression is either a type variable, a function type,
+--- or a type constructor application.
+---
+--- Note: the names of the predefined type constructors are
+---       "Int", "Float", "Bool", "Char", "IO", "Success",
+---       "()" (unit type), "(,...,)" (tuple types), "[]" (list type)
+
+data TypeExpr =
+     TVar TVarIndex                 -- type variable
+   | FuncType TypeExpr TypeExpr     -- function type t1->t2
+   | TCons QName [TypeExpr]         -- type constructor application
+   deriving (Read, Show, Eq,Data,Typeable)            --    TCons module name typeargs
+
+
+--- Data type for operator declarations.
+--- An operator declaration "fix p n" in Curry corresponds to the
+--- FlatCurry term (Op n fix p).
+--- Note: the constructor definition of 'Op' differs from the original
+--- PAKCS definition using Haskell type 'Integer' instead of 'Int'
+--- for representing the precedence. 
+
+data OpDecl = Op QName Fixity Integer deriving (Read, Show, Eq,Data,Typeable)
+
+--- Data types for the different choices for the fixity of an operator.
+
+data Fixity = InfixOp | InfixlOp | InfixrOp deriving (Read, Show, Eq,Data,Typeable)
+
+
+--- Data type for representing object variables.
+--- Object variables occurring in expressions are represented by (Var i)
+--- where i is a variable index.
+
+--- Data type for representing function declarations.
+--- <PRE>
+--- A function declaration in FlatCurry is a term of the form
+---
+---  (Func name arity type (Rule [i_1,...,i_arity] e))
+---
+--- and represents the function "name" with definition
+---
+---   name :: type
+---   name x_1...x_arity = e
+---
+--- where each i_j is the index of the variable x_j
+---
+--- Note: the variable indices are unique inside each function declaration
+---       and are usually numbered from 0
+---
+--- External functions are represented as (Func name arity type (External s))
+--- where s is the external name associated to this function.
+---
+--- Thus, a function declaration consists of the name, arity, type, and rule.
+--- </PRE>
+
+data FuncDecl = Func QName Int Visibility TypeExpr Rule
+	      deriving (Read, Show, Eq,Data,Typeable)
+
+
+--- A rule is either a list of formal parameters together with an expression
+--- or an "External" tag.
+
+data Rule = Rule [VarIndex] Expr
+          | External String
+	  deriving (Read, Show, Eq,Data,Typeable)
+
+--- Data type for classifying case expressions.
+--- Case expressions can be either flexible or rigid in Curry.
+
+data CaseType = Rigid | Flex deriving (Read, Show, Eq,Data,Typeable)
+
+--- Data type for classifying combinations
+--- (i.e., a function/constructor applied to some arguments).
+--- @cons FuncCall     - a call to a function all arguments are provided
+--- @cons ConsCall     - a call with a constructor at the top,
+---                      all arguments are provided
+--- @cons FuncPartCall - a partial call to a function
+---                      (i.e., not all arguments are provided) 
+---                      where the parameter is the number of
+---                      missing arguments
+--- @cons ConsPartCall - a partial call to a constructor along with 
+---                      number of missing arguments
+
+data CombType = FuncCall 
+              | ConsCall 
+              | FuncPartCall Int 
+              | ConsPartCall Int deriving (Read, Show, Eq,Data,Typeable)
+
+--- Data type for representing expressions.
+---
+--- Remarks:
+--- <PRE>
+--- 1. if-then-else expressions are represented as function calls:
+---      (if e1 then e2 else e3)
+---    is represented as
+---      (Comb FuncCall ("Prelude","if_then_else") [e1,e2,e3])
+--- 
+--- 2. Higher order applications are represented as calls to the (external)
+---    function "apply". For instance, the rule
+---      app f x = f x
+---    is represented as
+---      (Rule  [0,1] (Comb FuncCall ("Prelude","apply") [Var 0, Var 1]))
+--- 
+--- 3. A conditional rule is represented as a call to an external function
+---    "cond" where the first argument is the condition (a constraint).
+---    For instance, the rule
+---      equal2 x | x=:=2 = success
+---    is represented as
+---      (Rule [0]
+---            (Comb FuncCall ("Prelude","cond")
+---                  [Comb FuncCall ("Prelude","=:=") [Var 0, Lit (Intc 2)],
+---                   Comb FuncCall ("Prelude","success") []]))
+--- 
+--- 4. Functions with evaluation annotation "choice" are represented
+---    by a rule whose right-hand side is enclosed in a call to the
+---    external function "Prelude.commit".
+---    Furthermore, all rules of the original definition must be
+---    represented by conditional expressions (i.e., (cond [c,e]))
+---    after pattern matching.
+---    Example:
+--- 
+---       m eval choice
+---       m [] y = y
+---       m x [] = x
+--- 
+---    is translated into (note that the conditional branches can be also
+---    wrapped with Free declarations in general):
+--- 
+---       Rule [0,1]
+---            (Comb FuncCall ("Prelude","commit")
+---              [Or (Case Rigid (Var 0)
+---                     [(Pattern ("Prelude","[]") []
+---                         (Comb FuncCall ("Prelude","cond")
+---                               [Comb FuncCall ("Prelude","success") [],
+---                                Var 1]))] )
+---                  (Case Rigid (Var 1)
+---                     [(Pattern ("Prelude","[]") []
+---                         (Comb FuncCall ("Prelude","cond")
+---                               [Comb FuncCall ("Prelude","success") [],
+---                                Var 0]))] )])
+--- 
+---    Operational meaning of (Prelude.commit e):
+---    evaluate e with local search spaces and commit to the first
+---    (Comb FuncCall ("Prelude","cond") [c,ge]) in e whose constraint c
+---    is satisfied
+--- </PRE>
+--- @cons Var - variable (represented by unique index)
+--- @cons Lit - literal (Integer/Float/Char constant)
+--- @cons Comb - application (f e1 ... en) of function/constructor f
+---              with n<=arity(f)
+--- @cons Free - introduction of free local variables
+--- @cons Or - disjunction of two expressions (used to translate rules
+---            with overlapping left-hand sides)
+--- @cons Case - case distinction (rigid or flex)
+
+data Expr = Var VarIndex 
+          | Lit Literal
+          | Comb CombType QName [Expr]
+          | Free [VarIndex] Expr
+          | Let [(VarIndex,Expr)] Expr
+          | Or Expr Expr
+          | Case SrcRef CaseType Expr [BranchExpr]
+	  deriving (Read, Show, Eq,Data,Typeable)
+
+
+--- Data type for representing branches in a case expression.
+--- <PRE>
+--- Branches "(m.c x1...xn) -> e" in case expressions are represented as
+---
+---   (Branch (Pattern (m,c) [i1,...,in]) e)
+---
+--- where each ij is the index of the pattern variable xj, or as
+---
+---   (Branch (LPattern (Intc i)) e)
+---
+--- for integers as branch patterns (similarly for other literals
+--- like float or character constants).
+--- </PRE>
+
+data BranchExpr = Branch Pattern Expr deriving (Read, Show, Eq,Data,Typeable)
+
+--- Data type for representing patterns in case expressions.
+
+data Pattern = Pattern QName [VarIndex]
+             | LPattern Literal
+	     deriving (Read, Show, Eq,Data,Typeable)
+
+--- Data type for representing literals occurring in an expression
+--- or case branch. It is either an integer, a float, or a character constant.
+--- Note: the constructor definition of 'Intc' differs from the original
+--- PAKCS definition. It uses Haskell type 'Integer' instead of 'Int'
+--- to provide an unlimited range of integer numbers. Furthermore
+--- float values are represented with Haskell type 'Double' instead of
+--- 'Float'.
+
+data Literal = Intc   SrcRef Integer
+             | Floatc SrcRef Double
+             | Charc  SrcRef Char
+	     deriving (Read, Show, Eq,Data,Typeable)
+
+
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+
+-- Reads a FlatCurry file (extension ".fcy") and returns the corresponding
+-- FlatCurry program term (type 'Prog') as a value of type 'Maybe'.
+readFlatCurry :: FilePath -> IO (Maybe Prog)
+readFlatCurry fn 
+   = do let filename = flatName fn
+        readFlat filename
+
+-- Reads a FlatInterface file (extension ".fint") and returns the
+-- corresponding term (type 'Prog') as a value of type 'Maybe'.
+readFlatInterface :: String -> IO (Maybe Prog)
+readFlatInterface fn
+   = do let filename = replaceExtension fn ".fint"
+        readFlat filename
+
+-- Reads a Flat file and returns the corresponding term (type 'Prog') as
+-- a value of type 'Maybe'.
+readFlat :: FilePath -> IO (Maybe Prog)
+readFlat = liftM (fmap read) . maybeReadModule
+  
+-- Writes a FlatCurry program term into a file.
+writeFlatCurry :: String -> Prog -> IO ()
+writeFlatCurry filename prog
+   = writeModule filename (showFlatCurry' False prog)
+
+-- Writes a FlatCurry program term with source references into a file.
+writeExtendedFlat :: String -> Prog -> IO ()
+writeExtendedFlat filename prog =
+  writeModule (replaceExtension filename ".efc") (showFlatCurry' True prog)
+
+
+showFlatCurry' :: Bool -> Prog -> String
+showFlatCurry' b x = gshowsPrec b False x ""
+
+gshowsPrec :: Data a => Bool -> Bool -> a -> ShowS
+gshowsPrec showType d = 
+  genericShowsPrec d `ext1Q` showsList
+                     `ext2Q` showsTuple
+                     `extQ`  (const id :: SrcRef -> ShowS)
+                     `extQ`  (const id :: [SrcRef] -> ShowS)
+                     `extQ`  (shows :: String -> ShowS)
+                     `extQ`  (shows :: Char -> ShowS)
+                     `extQ`  showsQName d
+                     `extQ`  showsVarIndex d
+                                      
+      where
+        showsQName :: Bool -> QName -> ShowS
+        showsQName d qn@QName{modName=m,localName=n,typeofQName=t} = 
+          if showType then showParen d (shows qn{srcRef=Nothing})
+                      else shows (m,n)
+
+        showsVarIndex :: Bool -> VarIndex -> ShowS
+        showsVarIndex d
+            | showType  = showParen d . shows
+            | otherwise = shows . idxOf
+
+        genericShowsPrec :: Data a => Bool -> a -> ShowS
+        genericShowsPrec d t = let args = intersperse (showChar ' ') $
+                                          gmapQ (gshowsPrec showType True) t in
+                               showParen (d && not (null args)) $
+                               showString (showConstr (toConstr t)) .
+                               (if null args then id else showChar ' ') .
+                               foldr (.) id args
+
+        showsList :: Data a => [a] -> ShowS
+        showsList xs = showChar '[' . 
+                       foldr (.) (showChar ']') 
+                             (intersperse (showChar ',') $ 
+                              map (gshowsPrec showType False) xs)
+                       
+
+        showsTuple :: (Data a,Data b) => (a,b) -> ShowS
+        showsTuple (x,y) = showChar '(' . 
+                           gshowsPrec showType False x . 
+                           showChar ',' .
+                           gshowsPrec showType False y .
+                           showChar ')' 
+
+
+newtype Q r a = Q (a -> r)
+ 
+ext2Q :: (Data d, Typeable2 t) => (d -> q) -> 
+   (forall d1 d2. (Data d1, Data d2) => t d1 d2 -> q) -> d -> q
+ext2Q def ext arg =
+   case dataCast2 (Q ext) of
+     Just (Q ext') -> ext' arg
+     Nothing       -> def arg
+
+------------------------------------------------------------------------------
+------------------------------------------------------------------------------
+
diff --git a/src/Curry/Syntax.hs b/src/Curry/Syntax.hs
new file mode 100644
--- /dev/null
+++ b/src/Curry/Syntax.hs
@@ -0,0 +1,36 @@
+module Curry.Syntax(module Curry.Syntax.Type,
+                   parseModule, parseHeader
+                   ) where
+
+import Control.Monad
+import Data.List
+
+import Curry.Base.MessageMonad
+import Curry.Syntax.Type
+
+import qualified Curry.Syntax.Parser as CSP
+
+import Curry.Syntax.Unlit
+
+
+
+parseModule :: Bool -> FilePath -> String -> MsgMonad Module
+parseModule likeFlat fn =
+  unlitLiterate fn >=> CSP.parseSource likeFlat fn
+
+
+parseHeader :: FilePath -> String -> MsgMonad Module
+parseHeader fn =
+  unlitLiterate fn >=> CSP.parseHeader fn
+
+-- Literate source files use the extension ".lcurry"
+unlitLiterate :: FilePath -> String -> MsgMonad String
+unlitLiterate fn s
+  | isLiterateSource fn = unlit fn s
+  | otherwise = return s
+
+isLiterateSource :: FilePath -> Bool
+isLiterateSource fn = litExt `isSuffixOf` fn
+
+litExt = ".lcurry"
+
diff --git a/src/Curry/Syntax/LLParseComb.lhs b/src/Curry/Syntax/LLParseComb.lhs
new file mode 100644
--- /dev/null
+++ b/src/Curry/Syntax/LLParseComb.lhs
@@ -0,0 +1,290 @@
+% -*- LaTeX -*-
+% $Id: LLParseComb.lhs,v 1.26 2004/02/15 23:11:30 wlux Exp $
+%
+% Copyright (c) 1999-2004, Wolfgang Lux
+% See LICENSE for the full license.
+%
+\nwfilename{LLParseComb.lhs}
+\section{Parsing Combinators}\label{sec:ll-parsecomb}
+The parsing combinators implemented in the module \texttt{LLParseComb}
+are based on the LL(1) parsing combinators developed by Swierstra and
+Duponcheel~\cite{SwierstraDuponcheel96:Parsers}. They have been
+adapted to using continuation passing style in order to work with the
+lexing combinators described in the previous section. In addition, the
+facilities for error correction are omitted in this implementation.
+
+The two functions \texttt{applyParser} and \texttt{prefixParser} use
+the specified parser for parsing a string. When \texttt{applyParser}
+is used, an error is reported if the parser does not consume the whole
+string, whereas \texttt{prefixParser} discards the rest of the input
+string in this case.
+\begin{verbatim}
+
+> module Curry.Syntax.LLParseComb(Symbol(..),Parser,
+>                    applyParser,prefixParser, position,succeed,symbol,
+>                    (<?>),(<|>),(<|?>),(<*>),(<\>),(<\\>),
+>                    opt,(<$>),(<$->),(<*->),(<-*>),(<**>),(<??>),(<.>),
+>                    many,many1, sepBy,sepBy1, chainr,chainr1,chainl,chainl1,
+>                    bracket,ops, layoutOn,layoutOff,layoutEnd) where
+
+> import Control.Monad
+> import Data.Maybe
+> import qualified Data.Set as Set
+> import qualified Data.Map as Map
+
+> import Curry.Syntax.LexComb
+> import Curry.Base.MessageMonad
+> import Curry.Base.Position
+
+
+> infixl 5 <\>, <\\>
+> infixl 4 <*>, <$>, <$->, <*->, <-*>, <**>, <??>, <.>
+> infixl 3 <|>, <|?>
+> infixl 2 <?>, `opt`
+
+\end{verbatim}
+\paragraph{Parser types}
+\begin{verbatim}
+
+> class (Ord s,Show s) => Symbol s where
+>   isEOF :: s -> Bool
+
+> type Empty = Bool
+> type SuccessCont s a = Position -> s -> P a
+> type FailureCont a = Position -> String -> P a
+> type Lexer s a = SuccessCont s a -> FailureCont a -> P a
+> type ParseFun s a b = (a -> SuccessCont s b) -> FailureCont b
+>                     -> SuccessCont s b
+
+> data Parser s a b = Parser (Maybe (ParseFun s a b))
+>                            (Map.Map s (Lexer s b -> ParseFun s a b))
+
+> instance Symbol s => Show (Parser s a b) where
+>   showsPrec p (Parser e ps) = showParen (p >= 10) $                      -- $
+>     showString "Parser " . shows (isJust e) .
+>     showChar ' ' . shows (Map.keysSet ps)
+
+> applyParser :: Symbol s => Parser s a a -> Lexer s a -> FilePath -> String
+>             -> MsgMonad a
+> applyParser p lexer = parse (lexer (choose p lexer done failP) failP)
+>   where done x pos s
+>           | isEOF s = returnP x
+>           | otherwise = failP pos (unexpected s)
+
+> prefixParser :: Symbol s => Parser s a a -> Lexer s a -> FilePath -> String
+>              -> MsgMonad a
+> prefixParser p lexer = parse (lexer (choose p lexer discard failP) failP)
+>   where discard x _ _ = returnP x
+
+> choose :: Symbol s => Parser s a b -> Lexer s b -> ParseFun s a b
+> choose (Parser e ps) lexer success fail pos s =
+>   case Map.lookup s ps of
+>     Just p -> p lexer success fail pos s
+>     Nothing ->
+>       case e of
+>         Just p -> p success fail pos s
+>         Nothing -> fail pos (unexpected s)
+
+> unexpected :: Symbol s => s -> String
+> unexpected s
+>   | isEOF s = "Unexpected end-of-file"
+>   | otherwise = "Unexpected token " ++ show s
+
+\end{verbatim}
+\paragraph{Basic combinators}
+\begin{verbatim}
+
+> position :: Symbol s => Parser s Position b
+> position = Parser (Just p) Map.empty
+>   where p success _ pos = success pos pos
+
+> succeed :: Symbol s => a -> Parser s a b
+> succeed x = Parser (Just p) Map.empty
+>   where p success _ = success x
+
+> symbol :: Symbol s => s -> Parser s s a
+> symbol s = Parser Nothing (Map.singleton s p)
+>   where p lexer success fail pos s = lexer (success s) fail
+
+> (<?>) :: Symbol s => Parser s a b -> String -> Parser s a b
+> p <?> msg = p <|> Parser (Just pfail) Map.empty
+>   where pfail _ fail pos _ = fail pos msg
+
+> (<|>) :: Symbol s => Parser s a b -> Parser s a b -> Parser s a b
+> Parser e1 ps1 <|> Parser e2 ps2
+>   | isJust e1 && isJust e2 = error "Ambiguous parser for empty word"
+>   | not (Set.null common) = error ("Ambiguous parser for " ++ show common)
+>   | otherwise = Parser (e1 `mplus` e2) (Map.union ps1 ps2)
+>   where common = Map.keysSet ps1 `Set.intersection` Map.keysSet ps2
+
+\end{verbatim}
+The parsing combinators presented so far require that the grammar
+being parsed is LL(1). In some cases it may be difficult or even
+impossible to transform a grammar into LL(1) form. As a remedy, we
+include a non-deterministic version of the choice combinator in
+addition to the deterministic combinator adapted from the paper. For
+every symbol from the intersection of the parser's first sets, the
+combinator \texttt{(<|?>)} applies both parsing functions to the input
+stream and uses that one which processes the longer prefix of the
+input stream irrespective of whether it succeeds or fails. If both
+functions recognize the same prefix, we choose the one that succeeds
+and report an ambiguous parse error if both succeed.
+\begin{verbatim}
+
+> (<|?>) :: Symbol s => Parser s a b -> Parser s a b -> Parser s a b
+> Parser e1 ps1 <|?> Parser e2 ps2
+>   | isJust e1 && isJust e2 = error "Ambiguous parser for empty word"
+>   | otherwise = Parser (e1 `mplus` e2) (Map.union ps1' ps2)
+>   where ps1' = Map.fromList [(s,maybe p (try p) (Map.lookup s ps2))
+>                           | (s,p) <- Map.toList ps1]
+>         try p1 p2 lexer success fail pos s =
+>           closeP1 p2s `thenP` \p2s' ->
+>           closeP1 p2f `thenP` \p2f' ->
+>           parse p1 (retry p2s') (retry p2f')
+>           where p2s r1 = parse p2 (select True r1) (select False r1)
+>                 p2f r1 = parse p2 (flip (select False) r1) (select False r1)
+>                 parse p psucc pfail =
+>                   p lexer (successK psucc) (failK pfail) pos s
+>                 successK k x pos s = k (pos,success x pos s)
+>                 failK k pos msg = k (pos,fail pos msg)
+>                 retry k (pos,p) = closeP0 p `thenP` curry k pos
+>         select suc (pos1,p1) (pos2,p2) =
+>           case pos1 `compare` pos2 of
+>             GT -> p1
+>             EQ
+>               | suc -> error ("Ambiguous parse before " ++ show pos1)
+>               | otherwise -> p1
+>             LT -> p2
+
+> (<*>) :: Symbol s => Parser s (a -> b) c -> Parser s a c -> Parser s b c
+> Parser (Just p1) ps1 <*> ~p2@(Parser e2 ps2) =
+>   Parser (fmap (seqEE p1) e2)
+>          (Map.union (fmap (flip seqPP p2) ps1) (fmap (seqEP p1) ps2))
+> Parser Nothing ps1 <*> p2 = Parser Nothing (fmap (flip seqPP p2) ps1)
+
+> seqEE :: Symbol s => ParseFun s (a -> b) c -> ParseFun s a c
+>       -> ParseFun s b c
+> seqEE p1 p2 success fail = p1 (\f -> p2 (success . f) fail) fail
+
+> seqEP :: Symbol s => ParseFun s (a -> b) c -> (Lexer s c -> ParseFun s a c)
+>       -> Lexer s c -> ParseFun s b c
+> seqEP p1 p2 lexer success fail = p1 (\f -> p2 lexer (success . f) fail) fail
+
+> seqPP :: Symbol s => (Lexer s c -> ParseFun s (a -> b) c) -> Parser s a c
+>       -> Lexer s c -> ParseFun s b c
+> seqPP p1 p2 lexer success fail =
+>   p1 lexer (\f -> choose p2 lexer (success . f) fail) fail
+
+\end{verbatim}
+The combinators \verb|<\\>| and \verb|<\>| can be used to restrict
+the first set of a parser. This is useful for combining two parsers
+with an overlapping first set with the deterministic combinator <|>.
+\begin{verbatim}
+
+> (<\>) :: Symbol s => Parser s a c -> Parser s b c -> Parser s a c
+> p <\> Parser _ ps = p <\\> Map.keys ps
+
+> (<\\>) :: Symbol s => Parser s a b -> [s] -> Parser s a b
+> Parser e ps <\\> xs = Parser e (foldr Map.delete ps xs)
+
+\end{verbatim}
+\paragraph{Other combinators.}
+Note that some of these combinators have not been published in the
+paper, but were taken from the implementation found on the web.
+\begin{verbatim}
+
+> opt :: Symbol s => Parser s a b -> a -> Parser s a b
+> p `opt` x = p <|> succeed x
+
+> (<$>) :: Symbol s => (a -> b) -> Parser s a c -> Parser s b c
+> f <$> p = succeed f <*> p
+
+> (<$->) :: Symbol s => a -> Parser s b c -> Parser s a c
+> f <$-> p = const f <$> p {-$-}
+
+> (<*->) :: Symbol s => Parser s a c -> Parser s b c -> Parser s a c
+> p <*-> q = const <$> p <*> q {-$-}
+
+> (<-*>) :: Symbol s => Parser s a c -> Parser s b c -> Parser s b c
+> p <-*> q = const id <$> p <*> q {-$-}
+
+> (<**>) :: Symbol s => Parser s a c -> Parser s (a -> b) c -> Parser s b c
+> p <**> q = flip ($) <$> p <*> q
+
+> (<??>) :: Symbol s => Parser s a b -> Parser s (a -> a) b -> Parser s a b
+> p <??> q = p <**> (q `opt` id)
+
+> (<.>) :: Symbol s => Parser s (a -> b) d -> Parser s (b -> c) d
+>       -> Parser s (a -> c) d
+> p1 <.> p2 = p1 <**> ((.) <$> p2)
+
+> many :: Symbol s => Parser s a b -> Parser s [a] b
+> many p = many1 p `opt` []
+
+> many1 :: Symbol s => Parser s a b -> Parser s [a] b
+> -- many1 p = (:) <$> p <*> many p
+> many1 p = (:) <$> p <*> (many1 p `opt` [])
+
+\end{verbatim}
+The first definition of \texttt{many1} is commented out because it
+does not compile under nhc. This is due to a -- known -- bug in the
+type checker of nhc which expects a default declaration when compiling
+mutually recursive functions with class constraints. However, no such
+default can be given in the above case because neither of the types
+involved is a numeric type.
+\begin{verbatim}
+
+> sepBy :: Symbol s => Parser s a c -> Parser s b c -> Parser s [a] c
+> p `sepBy` q = p `sepBy1` q `opt` []
+
+> sepBy1 :: Symbol s => Parser s a c -> Parser s b c -> Parser s [a] c
+> p `sepBy1` q = (:) <$> p <*> many (q <-*> p) {-$-}
+
+> chainr :: Symbol s => Parser s a b -> Parser s (a -> a -> a) b -> a
+>        -> Parser s a b
+> chainr p op x = chainr1 p op `opt` x
+
+> chainr1 :: Symbol s => Parser s a b -> Parser s (a -> a -> a) b
+>         -> Parser s a b
+> chainr1 p op = r
+>   where r = p <**> (flip <$> op <*> r `opt` id) {-$-}
+
+> chainl :: Symbol s => Parser s a b -> Parser s (a -> a -> a) b -> a
+>        -> Parser s a b
+> chainl p op x = chainl1 p op `opt` x
+
+> chainl1 :: Symbol s => Parser s a b -> Parser s (a -> a -> a) b
+>         -> Parser s a b
+> chainl1 p op = foldF <$> p <*> many (flip <$> op <*> p)
+>   where foldF x [] = x
+>         foldF x (f:fs) = foldF (f x) fs
+
+> bracket :: Symbol s => Parser s a c -> Parser s b c -> Parser s a c
+>         -> Parser s b c
+> bracket open p close = open <-*> p <*-> close
+
+> ops :: Symbol s => [(s,a)] -> Parser s a b
+> ops [] = error "internal error: ops"
+> ops [(s,x)] = x <$-> symbol s
+> ops ((s,x):rest) = x <$-> symbol s <|> ops rest
+
+\end{verbatim}
+\paragraph{Layout combinators}
+Note that the layout functions grab the next token (and its position).
+After modifying the layout context, the continuation is called with
+the same token and an undefined result.
+\begin{verbatim}
+
+> layoutOn :: Symbol s => Parser s a b
+> layoutOn = Parser (Just on) Map.empty
+>   where on success _ pos = pushContext (column pos) . success undefined pos
+
+> layoutOff :: Symbol s => Parser s a b
+> layoutOff = Parser (Just off) Map.empty
+>   where off success _ pos = pushContext (-1) . success undefined pos
+
+> layoutEnd :: Symbol s => Parser s a b
+> layoutEnd = Parser (Just end) Map.empty
+>   where end success _ pos = popContext . success undefined pos
+
+\end{verbatim}
diff --git a/src/Curry/Syntax/LexComb.lhs b/src/Curry/Syntax/LexComb.lhs
new file mode 100644
--- /dev/null
+++ b/src/Curry/Syntax/LexComb.lhs
@@ -0,0 +1,104 @@
+% -*- LaTeX -*-
+% $Id: LexComb.lhs,v 1.16 2004/01/20 16:44:14 wlux Exp $
+%
+% Copyright (c) 1999-2004, Wolfgang Lux
+% See LICENSE for the full license.
+%
+\nwfilename{LexComb.lhs}
+\section{Lexing combinators}
+The module \texttt{LexComb} provides the basic types and combinators
+to implement the lexers. The combinators use continuation passing code
+in a monadic style. The first argument of the continuation function is
+the string to be parsed, the second is the current position, and the
+third is a flag which signals the lexer that it is lexing the
+beginning of a line and therefore has to check for layout tokens. The
+fourth argument is a stack of indentations that is used to handle
+nested layout groups.
+\begin{verbatim}
+
+> module Curry.Syntax.LexComb where
+
+> import Data.Char
+
+> import Curry.Base.MessageMonad
+> import Curry.Base.Position
+
+> infixl 1 `thenP`, `thenP_`
+
+> type Indent = Int
+> type Context = [Indent]
+> type P a = Position -> String -> Bool -> Context -> MsgMonad a
+
+> parse :: P a -> FilePath -> String -> MsgMonad a
+> parse p fn s = p (first fn) s False []
+
+\end{verbatim}
+Monad functions for the lexer.
+\begin{verbatim}
+
+> returnP :: a -> P a
+> returnP x _ _ _ _ = return x
+
+> thenP :: P a -> (a -> P b) -> P b
+> thenP lex k pos s bol ctxt = lex pos s bol ctxt >>= \x -> k x pos s bol ctxt
+
+> thenP_ :: P a -> P b -> P b
+> p1 `thenP_` p2 = p1 `thenP` \_ -> p2
+
+> failP :: Position -> String -> P a
+> failP pos msg _ _ _ _ = failWith (parseError pos msg)
+
+> closeP0 :: P a -> P (P a)
+> closeP0 lex pos s bol ctxt = return (\_ _ _ _ -> lex pos s bol ctxt)
+
+> closeP1 :: (a -> P b) -> P (a -> P b)
+> closeP1 f pos s bol ctxt = return (\x _ _ _ _ -> f x pos s bol ctxt)
+
+> parseError :: Position -> String -> String
+> parseError p what = "\n" ++ show p ++ ": " ++ what
+
+\end{verbatim}
+Combinators that handle layout.
+\begin{verbatim}
+
+> pushContext :: Int -> P a -> P a
+> pushContext col cont pos s bol ctxt = cont pos s bol (col:ctxt)
+
+> popContext :: P a -> P a
+> popContext cont pos s bol (_:ctxt) = cont pos s bol ctxt
+> popContext cont pos s bol [] = 
+>    error "parse error: popping layout from empty context stack. \
+>          \Perhaps you have inserted too many '}'?"
+
+\end{verbatim}
+Conversions from strings into numbers.
+\begin{verbatim}
+
+> convertSignedIntegral :: Num a => a -> String -> a
+> convertSignedIntegral b ('+':s) = convertIntegral b s
+> convertSignedIntegral b ('-':s) = - convertIntegral b s
+> convertSignedIntegral b s = convertIntegral b s
+
+> convertIntegral :: Num a => a -> String -> a
+> convertIntegral b = foldl op 0
+>   where m `op` n | isDigit n = b * m + fromIntegral (ord n - ord0)
+>                  | isUpper n = b * m + fromIntegral (ord n - ordA)
+>                  | otherwise = b * m + fromIntegral (ord n - orda)
+>         ord0 = ord '0'
+>         ordA = ord 'A' - 10
+>         orda = ord 'a' - 10
+
+> convertSignedFloating :: Fractional a => String -> String -> Int -> a
+> convertSignedFloating ('+':m) f e = convertFloating m f e
+> convertSignedFloating ('-':m) f e = - convertFloating m f e
+> convertSignedFloating m f e = convertFloating m f e
+
+> convertFloating :: Fractional a => String -> String -> Int -> a
+> convertFloating m f e
+>   | e' == 0 = m'
+>   | e' > 0  = m' * 10^e'
+>   | otherwise = m' / 10^(-e')
+>   where m' = convertIntegral 10 (m ++ f)
+>         e' = e - length f
+
+\end{verbatim}
diff --git a/src/Curry/Syntax/Lexer.lhs b/src/Curry/Syntax/Lexer.lhs
new file mode 100644
--- /dev/null
+++ b/src/Curry/Syntax/Lexer.lhs
@@ -0,0 +1,630 @@
+
+% $Id: CurryLexer.lhs,v 1.40 2004/03/04 22:39:12 wlux Exp $
+%
+% Copyright (c) 1999-2004, Wolfgang Lux
+% See LICENSE for the full license.
+%
+% Modified by Martin Engelke (men@informatik.uni-kiel.de)
+%
+\nwfilename{CurryLexer.lhs}
+\section{A Lexer for Curry}
+In this section a lexer for Curry is implemented.
+\begin{verbatim}
+ 
+> module Curry.Syntax.Lexer (lexFile,lexer, Token (..), Category(..), Attributes(..)) where
+
+> import Data.Char 
+> import Data.List
+> import qualified Data.Map as Map
+
+> import Curry.Syntax.LexComb
+> import Curry.Base.Position
+
+
+
+\end{verbatim}
+\paragraph{Tokens} Note that the equality and ordering instances of
+\texttt{Token} disregard the attributes.
+\begin{verbatim}
+
+> data Token = Token Category Attributes
+
+> instance Eq Token where
+>   Token t1 _ == Token t2 _ = t1 == t2
+> instance Ord Token where
+>   Token t1 _ `compare` Token t2 _ = t1 `compare` t2
+
+> data Category =
+>   -- literals
+>     CharTok | IntTok | FloatTok | IntegerTok | StringTok
+>   -- identifiers
+>   | Id | QId | Sym | QSym
+>   -- punctuation symbols
+>   | LeftParen | RightParen | Semicolon | LeftBrace | RightBrace
+>   | LeftBracket | RightBracket | Comma | Underscore | Backquote
+>   -- turn off layout (inserted by bbr)
+>   | LeftBraceSemicolon
+>   -- virtual punctation (inserted by layout)
+>   | VSemicolon | VRightBrace
+>   -- reserved identifiers
+>   | KW_case | KW_choice | KW_data | KW_do | KW_else | KW_eval | KW_external
+>   | KW_free | KW_if | KW_import | KW_in | KW_infix | KW_infixl | KW_infixr
+>   | KW_let | KW_module | KW_newtype | KW_of | KW_rigid | KW_then | KW_type
+>   | KW_where
+>   -- reserved operators
+>   | At | Colon | DotDot | DoubleColon | Equals | Backslash | Bar
+>   | LeftArrow | RightArrow | Tilde | Binds
+>   -- special identifiers
+>   | Id_as | Id_ccall | Id_forall | Id_hiding | Id_interface | Id_primitive
+>   | Id_qualified
+>   -- special operators
+>   | Sym_Dot | Sym_Minus | Sym_MinusDot
+>   -- end-of-file token
+>   | EOF
+>   -- comments (only for full lexer) inserted by men & bbr
+>   | LineComment | NestedComment 
+>   deriving (Eq,Ord)
+
+\end{verbatim}
+There are different kinds of attributes associated with the tokens.
+Most attributes simply save the string corresponding to the token.
+However, for qualified identifiers, we also record the list of module
+qualifiers. The values corresponding to a literal token are properly
+converted already. To simplify the creation and extraction of
+attribute values we make use of records.
+\begin{verbatim}
+
+> data Attributes =
+>     NoAttributes
+>   | CharAttributes{ cval :: Char, original :: String}
+>   | IntAttributes{ ival :: Int , original :: String}
+>   | FloatAttributes{ fval :: Double, original :: String}
+>   | IntegerAttributes{ intval :: Integer, original :: String}
+>   | StringAttributes{ sval :: String, original :: String}
+>   | IdentAttributes{ modul :: [String], sval :: String}
+
+> instance Show Attributes where
+>   showsPrec _ NoAttributes = showChar '_'
+>   showsPrec _ (CharAttributes cval _) = shows cval
+>   showsPrec _ (IntAttributes ival _) = shows ival
+>   showsPrec _ (FloatAttributes fval _) = shows fval
+>   showsPrec _ (IntegerAttributes intval _) = shows intval
+>   showsPrec _ (StringAttributes sval _) = shows sval
+>   showsPrec _ (IdentAttributes mIdent ident) =
+>     showString ("`" ++ concat (intersperse "." (mIdent ++ [ident])) ++ "'")
+
+\end{verbatim}
+The following functions can be used to construct tokens with
+specific attributes.
+\begin{verbatim}
+
+> tok :: Category -> Token
+> tok t = Token t NoAttributes
+
+> idTok :: Category -> [String] -> String -> Token
+> idTok t mIdent ident = Token t IdentAttributes{ modul = mIdent, sval = ident }
+
+> charTok :: Char -> String -> Token
+> charTok c o = Token CharTok CharAttributes{ cval = c, original = o }
+
+> intTok :: Int -> String -> Token
+> intTok base digits =
+>   Token IntTok IntAttributes{ ival = convertIntegral base digits,
+>                               original = digits}
+
+> floatTok :: String -> String -> Int -> String -> Token
+> floatTok mant frac exp rest =
+>   Token FloatTok FloatAttributes{ fval = convertFloating mant frac exp, 
+>                                   original = mant++"."++frac++rest}
+ 
+> integerTok :: Integer -> String -> Token
+> integerTok base digits =
+>   Token IntegerTok
+>         IntegerAttributes{intval = (convertIntegral base digits) :: Integer,
+>                           original = digits}
+
+> stringTok :: String -> String -> Token
+> stringTok cs o = Token StringTok StringAttributes{ sval = cs, original = o }
+
+> lineCommentTok :: String -> Token
+> lineCommentTok s = Token LineComment StringAttributes{ sval = s, original = s}
+
+> nestedCommentTok :: String -> Token
+> nestedCommentTok s = Token NestedComment StringAttributes{ sval = s, original = s }
+
+\end{verbatim}
+The \texttt{Show} instance of \texttt{Token} is designed to display
+all tokens in their source representation.
+\begin{verbatim}
+
+> instance Show Token where
+>   showsPrec _ (Token Id a) = showString "identifier " . shows a
+>   showsPrec _ (Token QId a) = showString "qualified identifier " . shows a
+>   showsPrec _ (Token Sym a) = showString "operator " . shows a
+>   showsPrec _ (Token QSym a) = showString "qualified operator " . shows a
+>   showsPrec _ (Token IntTok a) = showString "integer " . shows a
+>   showsPrec _ (Token FloatTok a) = showString "float " . shows a
+>   showsPrec _ (Token CharTok a) = showString "character " . shows a
+>   showsPrec _ (Token IntegerTok a) = showString "integer " . shows a
+>   showsPrec _ (Token StringTok a) = showString "string " . shows a
+>   showsPrec _ (Token LeftParen _) = showString "`('"
+>   showsPrec _ (Token RightParen _) = showString "`)'"
+>   showsPrec _ (Token Semicolon _) = showString "`;'"
+>   showsPrec _ (Token LeftBrace _) = showString "`{'"
+>   showsPrec _ (Token RightBrace _) = showString "`}'"
+>   showsPrec _ (Token LeftBracket _) = showString "`['"
+>   showsPrec _ (Token RightBracket _) = showString "`]'"
+>   showsPrec _ (Token Comma _) = showString "`,'"
+>   showsPrec _ (Token Underscore _) = showString "`_'"
+>   showsPrec _ (Token Backquote _) = showString "``'"
+>   showsPrec _ (Token VSemicolon _) =
+>     showString "`;' (inserted due to layout)"
+>   showsPrec _ (Token VRightBrace _) =
+>     showString "`}' (inserted due to layout)"
+>   showsPrec _ (Token At _) = showString "`@'"
+>   showsPrec _ (Token Colon _) = showString "`:'"
+>   showsPrec _ (Token DotDot _) = showString "`..'"
+>   showsPrec _ (Token DoubleColon _) = showString "`::'"
+>   showsPrec _ (Token Equals _) = showString "`='"
+>   showsPrec _ (Token Backslash _) = showString "`\\'"
+>   showsPrec _ (Token Bar _) = showString "`|'"
+>   showsPrec _ (Token LeftArrow _) = showString "`<-'"
+>   showsPrec _ (Token RightArrow _) = showString "`->'"
+>   showsPrec _ (Token Tilde _) = showString "`~'"
+>   showsPrec _ (Token Binds _) = showString "`:='"
+>   showsPrec _ (Token Sym_Dot _) = showString "operator `.'"
+>   showsPrec _ (Token Sym_Minus _) = showString "operator `-'"
+>   showsPrec _ (Token Sym_MinusDot _) = showString "operator `-.'"
+>   showsPrec _ (Token KW_case _) = showString "`case'"
+>   showsPrec _ (Token KW_choice _) = showString "`choice'"
+>   showsPrec _ (Token KW_data _) = showString "`data'"
+>   showsPrec _ (Token KW_do _) = showString "`do'"
+>   showsPrec _ (Token KW_else _) = showString "`else'"
+>   showsPrec _ (Token KW_eval _) = showString "`eval'"
+>   showsPrec _ (Token KW_external _) = showString "`external'"
+>   showsPrec _ (Token KW_free _) = showString "`free'"
+>   showsPrec _ (Token KW_if _) = showString "`if'"
+>   showsPrec _ (Token KW_import _) = showString "`import'"
+>   showsPrec _ (Token KW_in _) = showString "`in'"
+>   showsPrec _ (Token KW_infix _) = showString "`infix'"
+>   showsPrec _ (Token KW_infixl _) = showString "`infixl'"
+>   showsPrec _ (Token KW_infixr _) = showString "`infixr'"
+>   showsPrec _ (Token KW_let _) = showString "`let'"
+>   showsPrec _ (Token KW_module _) = showString "`module'"
+>   showsPrec _ (Token KW_newtype _) = showString "`newtype'"
+>   showsPrec _ (Token KW_of _) = showString "`of'"
+>   showsPrec _ (Token KW_rigid _) = showString "`rigid'"
+>   showsPrec _ (Token KW_then _) = showString "`then'"
+>   showsPrec _ (Token KW_type _) = showString "`type'"
+>   showsPrec _ (Token KW_where _) = showString "`where'"
+>   showsPrec _ (Token Id_as _) = showString "identifier `as'"
+>   showsPrec _ (Token Id_ccall _) = showString "identifier `ccall'"
+>   showsPrec _ (Token Id_forall _) = showString "identifier `forall'"
+>   showsPrec _ (Token Id_hiding _) = showString "identifier `hiding'"
+>   showsPrec _ (Token Id_interface _) = showString "identifier `interface'"
+>   showsPrec _ (Token Id_primitive _) = showString "identifier `primitive'"
+>   showsPrec _ (Token Id_qualified _) = showString "identifier `qualified'"
+>   showsPrec _ (Token EOF _) = showString "<end-of-file>"
+>   showsPrec _ (Token LineComment a) = shows a
+>   showsPrec _ (Token NestedComment a) = shows a
+
+\end{verbatim}
+Tables for reserved operators and identifiers
+\begin{verbatim}
+
+> reserved_ops, reserved_and_special_ops :: Map.Map String Category
+> reserved_ops = Map.fromList [
+>     ("@",  At),
+>     ("::", DoubleColon),
+>     ("..", DotDot),
+>     ("=",  Equals),
+>     ("\\", Backslash),
+>     ("|",  Bar),
+>     ("<-", LeftArrow),
+>     ("->", RightArrow),
+>     ("~",  Tilde),
+>     (":=", Binds)
+>   ]
+> reserved_and_special_ops = foldr (uncurry Map.insert) reserved_ops [
+>     (":",  Colon),
+>     (".",  Sym_Dot),
+>     ("-",  Sym_Minus),
+>     ("-.", Sym_MinusDot)
+>   ]
+
+> reserved_ids, reserved_and_special_ids :: Map.Map String Category
+> reserved_ids = Map.fromList [
+>     ("case",     KW_case),
+>     ("choice",   KW_choice),
+>     ("data",     KW_data),
+>     ("do",       KW_do),
+>     ("else",     KW_else),
+>     ("eval",     KW_eval),
+>     ("external", KW_external),
+>     ("free",     KW_free),
+>     ("if",       KW_if),
+>     ("import",   KW_import),
+>     ("in",       KW_in),
+>     ("infix",    KW_infix),
+>     ("infixl",   KW_infixl),
+>     ("infixr",   KW_infixr),
+>     ("let",      KW_let),
+>     ("module",   KW_module),
+>     ("newtype",  KW_newtype),
+>     ("of",       KW_of),
+>     ("rigid",    KW_rigid),
+>     ("then",     KW_then),
+>     ("type",     KW_type),
+>     ("where",    KW_where)
+>   ]
+> reserved_and_special_ids = foldr (uncurry Map.insert) reserved_ids [
+>     ("as",        Id_as),
+>     ("ccall",     Id_ccall),
+>     ("forall",    Id_forall),
+>     ("hiding",    Id_hiding),
+>     ("interface", Id_interface),
+>     ("primitive", Id_primitive),
+>     ("qualified", Id_qualified)
+>   ]
+
+\end{verbatim}
+Character classes
+\begin{verbatim}
+
+> isIdent, isSym, isOctit, isHexit :: Char -> Bool
+> isIdent c = isAlphaNum c || c `elem` "'_"
+> isSym c = c `elem` "~!@#$%^&*+-=<>:?./|\\" {-$-}
+> isOctit c = c >= '0' && c <= '7'
+> isHexit c = isDigit c || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f'
+
+inserted for full lexing (men&bbr)
+
+> isLineComment, isNestedComment :: String -> Bool
+> isLineComment ('-':'-':_) = True
+> isLineComment _ = False
+> isNestedComment ('{':'-':s) = True
+> isNestedComment _ = False
+
+
+\end{verbatim}
+Lexing functions
+\begin{verbatim}
+
+> type SuccessP a = Position -> Token -> P a
+> type FailP a = Position -> String -> P a
+
+> lexFile :: P [(Position,Token)]
+> lexFile = fullLexer tokens failP
+>   where tokens p t@(Token c _)
+>           | c == EOF = returnP [(p,t)]
+>           | otherwise = lexFile `thenP` returnP . ((p,t):)
+
+> lexer :: SuccessP a -> FailP a -> P a
+> lexer success fail = skipBlanks
+>   where -- skipBlanks moves past whitespace and comments
+>         skipBlanks p [] bol = success p (tok EOF) p [] bol
+>         skipBlanks p ('\t':s) bol = skipBlanks (tab p) s bol
+>         skipBlanks p ('\n':s) bol = skipBlanks (nl p) s True
+>         skipBlanks p ('-':'-':s) bol =
+>           skipBlanks (nl p) (tail' (dropWhile (/= '\n') s)) True
+>         skipBlanks p ('{':'-':s) bol =
+>           nestedComment p skipBlanks fail (incr p 2) s bol
+>         skipBlanks p (c:s) bol
+>           | isSpace c = skipBlanks (next p) s bol
+>           | otherwise =
+>               (if bol then lexBOL else lexToken) success fail p (c:s) bol
+>         tail' [] = []
+>         tail' (_:tl) = tl
+
+> fullLexer :: SuccessP a -> FailP a -> P a
+> fullLexer success fail = skipBlanks
+>   where -- skipBlanks moves past whitespace 
+>         skipBlanks p [] bol = success p (tok EOF) p [] bol
+>         skipBlanks p ('\t':s) bol = skipBlanks (tab p) s bol
+>         skipBlanks p ('\n':s) bol = skipBlanks (nl p) s True
+>         skipBlanks p s@('-':'-':_) bol = lexLineComment success p s bol
+>         skipBlanks p s@('{':'-':_) bol =
+>           lexNestedComment 0 id p success fail p s bol
+>         skipBlanks p (c:s) bol
+>           | isSpace c = skipBlanks (next p) s bol
+>           | otherwise =
+>               (if bol then lexBOL else lexToken) success fail p (c:s) bol
+>         tail' [] = []
+>         tail' (_:tl) = tl
+
+> lexLineComment :: SuccessP a -> P a
+> lexLineComment success p s = case break (=='\n') s of
+>   (comment,rest) -> success p (lineCommentTok comment) (incr p (length comment)) rest
+ 
+> lexNestedComment :: Int -> (String -> String) -> 
+>                     Position -> SuccessP a -> FailP a -> P a
+> lexNestedComment 1 comment p0 success fail p ('-':'}':s) = 
+>   success p0 (nestedCommentTok (comment "-}") ) (incr p 2) s 
+> lexNestedComment n comment p0 success fail p ('{':'-':s) = 
+>   lexNestedComment (n+1) (comment . ("{-"++)) p0 success fail (incr p 2) s
+> lexNestedComment n comment p0 success fail p ('-':'}':s) = 
+>   lexNestedComment (n-1) (comment . ("-}"++)) p0 success fail (incr p 2) s
+> lexNestedComment n comment p0 success fail p (c@'\t':s) = 
+>   lexNestedComment n (comment . (c:)) p0 success fail (tab p) s
+> lexNestedComment n comment p0 success fail p (c@'\n':s) = 
+>   lexNestedComment n (comment . (c:)) p0 success fail (nl p) s
+> lexNestedComment n comment p0 success fail p (c:s) = 
+>   lexNestedComment n (comment . (c:)) p0 success fail (next p) s
+> lexNestedComment n comment p0 success fail p "" = 
+>   fail p0 "Unterminated nested comment" p []
+
+> nestedComment :: Position -> P a -> FailP a -> P a
+> nestedComment p0 success fail p ('-':'}':s) = success (incr p 2) s
+> nestedComment p0 success fail p ('{':'-':s) =
+>   nestedComment p (nestedComment p0 success fail) fail (incr p 2) s
+> nestedComment p0 success fail p ('\t':s) =
+>   nestedComment p0 success fail (tab p) s
+> nestedComment p0 success fail p ('\n':s) =
+>   nestedComment p0 success fail (nl p) s
+> nestedComment p0 success fail p (_:s) =
+>   nestedComment p0 success fail (next p) s
+> nestedComment p0 success fail p [] =
+>   fail p0 "Unterminated nested comment at end-of-file" p []
+
+
+> lexBOL :: SuccessP a -> FailP a -> P a
+> lexBOL success fail p s _ [] = lexToken success fail p s False []
+> lexBOL success fail p s _ ctxt@(n:rest)
+>   | col < n = success p (tok VRightBrace) p s True rest
+>   | col == n = success p (tok VSemicolon) p s False ctxt
+>   | otherwise = lexToken success fail p s False ctxt
+>   where col = column p
+
+> lexToken :: SuccessP a -> FailP a -> P a
+> lexToken success fail p [] = success p (tok EOF) p []
+> lexToken success fail p (c:s)
+>   | c == '(' = token LeftParen
+>   | c == ')' = token RightParen
+>   | c == ',' = token Comma
+>   | c == ';' = token Semicolon
+>   | c == '[' = token LeftBracket
+>   | c == ']' = token RightBracket
+>   | c == '_' = token Underscore
+>   | c == '`' = token Backquote
+>   | c == '{' = lexLeftBrace (token LeftBrace) (next p) (success p) s 
+>   | c == '}' = \bol -> token RightBrace bol . drop 1
+>   | c == '\'' = lexChar p success fail (next p) s
+>   | c == '\"' = lexString p success fail (next p) s
+>   | isAlpha c = lexIdent (success p) p (c:s)
+>   | isSym c = lexSym (success p) p (c:s)
+>   | isDigit c = lexNumber (success p) p (c:s)
+>   | otherwise = fail p ("Illegal character " ++ show c) p s
+>   where token t = success p (tok t) (next p) s
+
+> lexIdent :: (Token -> P a) -> P a
+> lexIdent cont p s =
+>   maybe (lexOptQual cont (token Id) [ident]) (cont . token)
+>         (Map.lookup ident reserved_and_special_ids)
+>         (incr p (length ident)) rest
+>   where (ident,rest) = span isIdent s
+>         token t = idTok t [] ident
+
+> lexSym :: (Token -> P a) -> P a
+> lexSym cont p s =
+>   cont (idTok (maybe Sym id (Map.lookup sym reserved_and_special_ops)) [] sym)
+>        (incr p (length sym)) rest
+>   where (sym,rest) = span isSym s
+
+> lexLeftBrace leftBrace _ _       []    = leftBrace
+> lexLeftBrace leftBrace p cont (c:s) 
+>   | c==';'    = cont (tok LeftBraceSemicolon) (next p) s
+>   | otherwise = leftBrace
+
+\end{verbatim}
+{\em Note:} the function \texttt{lexOptQual} has been extended to provide
+the qualified use of the Prelude list operators and tuples.
+\begin{verbatim}
+
+> lexOptQual :: (Token -> P a) -> Token -> [String] -> P a
+> lexOptQual cont token mIdent p ('.':c:s)
+>   | isAlpha c = lexQualIdent cont identCont mIdent (next p) (c:s)
+>   | isSym c = lexQualSym cont identCont mIdent (next p) (c:s)
+>   | c=='(' || c=='[' 
+>     = lexQualPreludeSym cont token identCont mIdent (next p) (c:s)
+>  where identCont _ _ = cont token p ('.':c:s)
+> lexOptQual cont token mIdent p s = cont token p s
+
+> lexQualIdent :: (Token -> P a) -> P a -> [String] -> P a
+> lexQualIdent cont identCont mIdent p s =
+>   maybe (lexOptQual cont (idTok QId mIdent ident) (mIdent ++ [ident]))
+>         (const identCont)
+>         (Map.lookup ident reserved_ids)
+>         (incr p (length ident)) rest
+>   where (ident,rest) = span isIdent s
+
+> lexQualSym :: (Token -> P a) -> P a -> [String] -> P a
+> lexQualSym cont identCont mIdent p s =
+>   maybe (cont (idTok QSym mIdent sym)) (const identCont)
+>         (Map.lookup sym reserved_ops)
+>         (incr p (length sym)) rest
+>   where (sym,rest) = span isSym s
+
+
+> lexQualPreludeSym :: (Token -> P a) -> Token -> P a -> [String] -> P a
+> lexQualPreludeSym cont _ identCont mIdent p ('[':']':rest) =
+>   cont (idTok QId mIdent "[]") (incr p 2) rest
+> lexQualPreludeSym cont _ identCont mIdent p ('(':rest)
+>   | not (null rest') && head rest'==')' 
+>   = cont (idTok QId mIdent ('(':tup++")")) (incr p (length tup+2)) (tail rest')
+>   where (tup,rest') = span (==',') rest
+> lexQualPreludeSym cont token _ _ p s =  cont token p s
+
+
+\end{verbatim}
+{\em Note:} since Curry allows an unlimited range of integer numbers,
+read numbers must be converted to Haskell type \texttt{Integer}.
+\begin{verbatim}
+
+> lexNumber :: (Token -> P a) -> P a
+> lexNumber cont p ('0':c:s)
+>   | c `elem` "oO" = lexOctal cont nullCont (incr p 2) s
+>   | c `elem` "xX" = lexHexadecimal cont nullCont (incr p 2) s
+>   where nullCont _ _ = cont (intTok 10 "0") (next p) (c:s)
+> lexNumber cont p s
+>     = lexOptFraction cont (integerTok 10 digits) digits
+>                      (incr p (length digits)) rest
+>   where (digits,rest) = span isDigit s
+>         num           = (read digits) :: Integer
+
+> lexOctal :: (Token -> P a) -> P a -> P a
+> lexOctal cont nullCont p s
+>   | null digits = nullCont undefined undefined
+>   | otherwise = cont (integerTok 8 digits) (incr p (length digits)) rest
+>   where (digits,rest) = span isOctit s
+
+> lexHexadecimal :: (Token -> P a) -> P a -> P a
+> lexHexadecimal cont nullCont p s
+>   | null digits = nullCont undefined undefined
+>   | otherwise = cont (integerTok 16 digits) (incr p (length digits)) rest
+>   where (digits,rest) = span isHexit s
+
+> lexOptFraction :: (Token -> P a) -> Token -> String -> P a
+> lexOptFraction cont _ mant p ('.':c:s)
+>   | isDigit c = lexOptExponent cont (floatTok mant frac 0 "") mant frac
+>                                (incr p (length frac+1)) rest
+>   where (frac,rest) = span isDigit (c:s)
+> lexOptFraction cont token mant p (c:s)
+>   | c `elem` "eE" = lexSignedExponent cont intCont mant "" [c] (next p) s
+>   where intCont _ _ = cont token p (c:s)
+> lexOptFraction cont token _ p s = cont token p s
+
+> lexOptExponent :: (Token -> P a) -> Token -> String -> String -> P a
+> lexOptExponent cont token mant frac p (c:s)
+>   | c `elem` "eE" = lexSignedExponent cont floatCont mant frac [c] (next p) s
+>   where floatCont _ _ = cont token p (c:s)
+> lexOptExponent cont token mant frac p s = cont token p s
+
+> lexSignedExponent :: (Token -> P a) -> P a -> String -> String -> String -> P a
+> lexSignedExponent cont floatCont mant frac e p ('+':c:s)
+>   | isDigit c = lexExponent cont mant frac (e++"+") id (next p) (c:s)
+> lexSignedExponent cont floatCont mant frac e p ('-':c:s)
+>   | isDigit c = lexExponent cont mant frac (e++"-") negate (next p) (c:s)
+> lexSignedExponent cont floatCont mant frac e p (c:s)
+>   | isDigit c = lexExponent cont mant frac e id p (c:s)
+> lexSignedExponent cont floatCont mant frac e p s = floatCont p s
+
+> lexExponent :: (Token -> P a) -> String -> String -> String -> (Int -> Int) -> P a
+> lexExponent cont mant frac e expSign p s =
+>   cont (floatTok mant frac exp (e++digits)) (incr p (length digits)) rest
+>   where (digits,rest) = span isDigit s
+>         exp = expSign (convertIntegral 10 digits)
+
+> lexChar :: Position -> SuccessP a -> FailP a -> P a
+> lexChar p0 success fail p [] = fail p0 "Illegal character constant" p []
+> lexChar p0 success fail p (c:s)
+>   | c == '\\' = lexEscape p (lexCharEnd p0 success fail) fail (next p) s
+>   | c == '\n' = fail p0 "Illegal character constant" p (c:s)
+>   | c == '\t' = lexCharEnd p0 success fail c "\t" (tab p) s
+>   | otherwise = lexCharEnd p0 success fail c [c] (next p) s
+
+> lexCharEnd :: Position -> SuccessP a -> FailP a -> Char -> String -> P a
+> lexCharEnd p0 success fail c o p ('\'':s) = success p0 (charTok c o) (next p) s
+> lexCharEnd p0 success fail c o p s =
+>   fail p0 "Improperly terminated character constant" p s
+
+> lexString :: Position -> SuccessP a -> FailP a -> P a
+> lexString p0 success fail = lexStringRest p0 success fail "" id
+
+> lexStringRest :: Position -> SuccessP a -> FailP a -> String -> (String -> String) -> P a
+> lexStringRest p0 success fail s0 so p [] = 
+>   fail p0 "Improperly terminated string constant" p []
+> lexStringRest p0 success fail s0 so p (c:s)
+>   | c == '\\' =
+>       lexStringEscape p (lexStringRest p0 success fail) fail s0 so (next p) s
+>   | c == '\"' = success p0 (stringTok (reverse s0) (so "")) (next p) s
+>   | c == '\n' = fail p0 "Improperly terminated string constant" p []
+>   | c == '\t' = lexStringRest p0 success fail (c:s0) (so . (c:)) (tab p) s
+>   | otherwise = lexStringRest p0 success fail (c:s0) (so . (c:)) (next p) s
+
+> lexStringEscape ::  Position -> (String -> (String -> String) -> P a) -> FailP a -> 
+>                                  String -> (String -> String) -> P a
+> lexStringEscape p0 success fail s0 so p [] = lexEscape p0 undefined fail p []
+> lexStringEscape p0 success fail s0 so p (c:s)
+>   | c == '&' = success s0 (so . ("\\&"++)) (next p) s
+>   | isSpace c = lexStringGap (success s0) fail so p (c:s)
+>   | otherwise = lexEscape p0 (\ c' s' -> success (c':s0) (so . (s'++))) fail p (c:s)
+
+> lexStringGap :: ((String -> String) -> P a) -> FailP a -> (String -> String) -> P a
+> lexStringGap success fail so p [] = fail p "End of file in string gap" p []
+> lexStringGap success fail so p (c:s)
+>   | c == '\\' = success (so . (c:)) (next p) s
+>   | c == '\t' = lexStringGap success fail (so . (c:)) (tab p) s
+>   | c == '\n' = lexStringGap success fail (so . (c:)) (nl p) s
+>   | isSpace c = lexStringGap success fail (so . (c:)) (next p) s
+>   | otherwise = fail p ("Illegal character in string gap " ++ show c) p s
+
+> lexEscape :: Position -> (Char -> String -> P a) -> FailP a -> P a
+> lexEscape p0 success fail p ('a':s) = success '\a' "\\a" (next p) s
+> lexEscape p0 success fail p ('b':s) = success '\b' "\\b" (next p) s
+> lexEscape p0 success fail p ('f':s) = success '\f' "\\f" (next p) s
+> lexEscape p0 success fail p ('n':s) = success '\n' "\\n" (next p) s
+> lexEscape p0 success fail p ('r':s) = success '\r' "\\r" (next p) s
+> lexEscape p0 success fail p ('t':s) = success '\t' "\\t" (next p) s
+> lexEscape p0 success fail p ('v':s) = success '\v' "\\v" (next p) s
+> lexEscape p0 success fail p ('\\':s) = success '\\' "\\\\" (next p) s
+> lexEscape p0 success fail p ('"':s) = success '\"' "\\\"" (next p) s
+> lexEscape p0 success fail p ('\'':s) = success '\'' "\\\'" (next p) s
+> lexEscape p0 success fail p ('^':c:s)
+>   | isUpper c || c `elem` "@[\\]^_" =
+>       success (chr (ord c `mod` 32)) ("\\^"++[c]) (incr p 2) s
+> lexEscape p0 success fail p ('o':c:s)
+>   | isOctit c = numEscape p0 success fail 8 isOctit ("\\o"++) (next p) (c:s)
+> lexEscape p0 success fail p ('x':c:s)
+>   | isHexit c = numEscape p0 success fail 16 isHexit ("\\x"++) (next p) (c:s)
+> lexEscape p0 success fail p (c:s)
+>   | isDigit c = numEscape p0 success fail 10 isDigit ("\\"++) p (c:s)
+> lexEscape p0 success fail p s = asciiEscape p0 success fail p s
+
+> asciiEscape :: Position -> (Char -> String -> P a) -> FailP a -> P a
+> asciiEscape p0 success fail p ('N':'U':'L':s) = success '\NUL' "\\NUL" (incr p 3) s
+> asciiEscape p0 success fail p ('S':'O':'H':s) = success '\SOH' "\\SOH" (incr p 3) s
+> asciiEscape p0 success fail p ('S':'T':'X':s) = success '\STX' "\\STX" (incr p 3) s
+> asciiEscape p0 success fail p ('E':'T':'X':s) = success '\ETX' "\\ETX" (incr p 3) s
+> asciiEscape p0 success fail p ('E':'O':'T':s) = success '\EOT' "\\EOT" (incr p 3) s
+> asciiEscape p0 success fail p ('E':'N':'Q':s) = success '\ENQ' "\\ENQ" (incr p 3) s
+> asciiEscape p0 success fail p ('A':'C':'K':s) = success '\ACK' "\\ACK" (incr p 3) s 
+> asciiEscape p0 success fail p ('B':'E':'L':s) = success '\BEL' "\\BEL" (incr p 3) s
+> asciiEscape p0 success fail p ('B':'S':s) = success '\BS' "\\BS" (incr p 2) s
+> asciiEscape p0 success fail p ('H':'T':s) = success '\HT' "\\HT" (incr p 2) s
+> asciiEscape p0 success fail p ('L':'F':s) = success '\LF' "\\LF" (incr p 2) s
+> asciiEscape p0 success fail p ('V':'T':s) = success '\VT' "\\VT" (incr p 2) s
+> asciiEscape p0 success fail p ('F':'F':s) = success '\FF' "\\FF" (incr p 2) s
+> asciiEscape p0 success fail p ('C':'R':s) = success '\CR' "\\CR" (incr p 2) s
+> asciiEscape p0 success fail p ('S':'O':s) = success '\SO' "\\SO" (incr p 2) s
+> asciiEscape p0 success fail p ('S':'I':s) = success '\SI' "\\SI" (incr p 2) s
+> asciiEscape p0 success fail p ('D':'L':'E':s) = success '\DLE' "\\DLE" (incr p 3) s 
+> asciiEscape p0 success fail p ('D':'C':'1':s) = success '\DC1' "\\DC1" (incr p 3) s
+> asciiEscape p0 success fail p ('D':'C':'2':s) = success '\DC2' "\\DC2" (incr p 3) s
+> asciiEscape p0 success fail p ('D':'C':'3':s) = success '\DC3' "\\DC3" (incr p 3) s
+> asciiEscape p0 success fail p ('D':'C':'4':s) = success '\DC4' "\\DC4" (incr p 3) s
+> asciiEscape p0 success fail p ('N':'A':'K':s) = success '\NAK' "\\NAK" (incr p 3) s
+> asciiEscape p0 success fail p ('S':'Y':'N':s) = success '\SYN' "\\SYN" (incr p 3) s
+> asciiEscape p0 success fail p ('E':'T':'B':s) = success '\ETB' "\\ETB" (incr p 3) s
+> asciiEscape p0 success fail p ('C':'A':'N':s) = success '\CAN' "\\CAN" (incr p 3) s 
+> asciiEscape p0 success fail p ('E':'M':s) = success '\EM' "\\EM" (incr p 2) s
+> asciiEscape p0 success fail p ('S':'U':'B':s) = success '\SUB' "\\SUB" (incr p 3) s
+> asciiEscape p0 success fail p ('E':'S':'C':s) = success '\ESC' "\\ESC" (incr p 3) s
+> asciiEscape p0 success fail p ('F':'S':s) = success '\FS' "\\FS" (incr p 2) s
+> asciiEscape p0 success fail p ('G':'S':s) = success '\GS' "\\GS" (incr p 2) s
+> asciiEscape p0 success fail p ('R':'S':s) = success '\RS' "\\RS" (incr p 2) s
+> asciiEscape p0 success fail p ('U':'S':s) = success '\US' "\\US" (incr p 2) s
+> asciiEscape p0 success fail p ('S':'P':s) = success '\SP' "\\SP" (incr p 2) s
+> asciiEscape p0 success fail p ('D':'E':'L':s) = success '\DEL' "\\DEL" (incr p 3) s
+> asciiEscape p0 success fail p s = fail p0 "Illegal escape sequence" p s
+
+> numEscape :: Position -> (Char -> String -> P a) -> FailP a -> Int
+>           -> (Char -> Bool) -> (String -> String) -> P a
+> numEscape p0 success fail b isDigit so p s
+>   | n >= min && n <= max = success (chr n) (so digits) (incr p (length digits)) rest
+>   | otherwise = fail p0 "Numeric escape out-of-range" p s
+>   where (digits,rest) = span isDigit s
+>         n = convertIntegral b digits
+>         min = ord minBound
+>         max = ord maxBound
+
+\end{verbatim}
diff --git a/src/Curry/Syntax/Parser.lhs b/src/Curry/Syntax/Parser.lhs
new file mode 100644
--- /dev/null
+++ b/src/Curry/Syntax/Parser.lhs
@@ -0,0 +1,806 @@
+
+% $Id: CurryParser.lhs,v 1.75 2004/02/15 23:11:28 wlux Exp $
+%
+% Copyright (c) 1999-2004, Wolfgang Lux
+% See LICENSE for the full license.
+%
+% Modified by Martin Engelke (men@informatik.uni-kiel.de)
+%
+\nwfilename{CurryParser.lhs}
+\section{A Parser for Curry}
+The Curry parser is implemented using the (mostly) LL(1) parsing
+combinators described in appendix~\ref{sec:ll-parsecomb}.
+\begin{verbatim}
+
+> module Curry.Syntax.Parser where
+
+> import Curry.Base.Ident
+> import Curry.Base.Position
+> import Curry.Base.MessageMonad
+> import Curry.Syntax.LLParseComb
+> import Curry.Syntax.Type
+> import Curry.Syntax.Lexer
+
+> instance Symbol Token where
+>   isEOF (Token c _) = c == EOF
+
+\end{verbatim}
+\paragraph{Modules}
+\begin{verbatim}
+
+> parseSource :: Bool -> FilePath -> String -> MsgMonad Module
+> parseSource flat path = 
+>    fmap addSrcRefs . applyParser ( moduleHeader <*> decls flat) lexer path
+
+> parseHeader :: FilePath -> String -> MsgMonad Module
+> parseHeader = prefixParser (moduleHeader <*->
+>                             (leftBrace `opt` undefined) <*>
+>                             many (importDecl <*-> many semicolon))
+>                            lexer
+
+> moduleHeader :: Parser Token ([Decl] -> Module) a
+> moduleHeader = Module <$-> token KW_module
+>                       <*> (mIdent <?> "module name expected")
+>                       <*> ((Just <$> exportSpec) `opt` Nothing)
+>                       <*-> (token KW_where <?> "where expected")
+>          `opt` Module mainMIdent Nothing
+
+> exportSpec :: Parser Token ExportSpec a
+> exportSpec = Exporting <$> position <*> parens (export `sepBy` comma)
+
+> export :: Parser Token Export a
+> export = qtycon <**> (parens spec `opt` Export)
+>      <|> Export <$> qfun <\> qtycon
+>      <|> ExportModule <$-> token KW_module <*> mIdent
+>   where spec = ExportTypeAll <$-> token DotDot
+>            <|> flip ExportTypeWith <$> con `sepBy` comma
+
+\end{verbatim}
+\paragraph{Interfaces}
+Since this modified version of MCC uses FlatCurry interfaces instead of
+".icurry" files, a separate parser is not required any longer.
+\begin{verbatim}
+
+> --parseInterface :: FilePath -> String -> Error Interface
+> --parseInterface fn s = applyParser parseIface lexer fn s
+
+> --parseIface :: Parser Token Interface a
+> --parseIface = Interface <$-> token Id_interface
+> --                       <*> (mIdent <?> "module name expected")
+> --                       <*-> (token KW_where <?> "where expected")
+> --                       <*> braces intfDecls
+
+\end{verbatim}
+
+
+
+\paragraph{Declarations}
+\begin{verbatim}
+
+> decls :: Bool -> Parser Token [Decl] a
+> decls = layout . globalDecls
+
+> globalDecls :: Bool -> Parser Token [Decl] a
+> globalDecls flat =
+>       (:) <$> importDecl <*> (semicolon <-*> globalDecls flat `opt` [])
+>   <|> topDecl flat `sepBy` semicolon
+
+> topDecl :: Bool -> Parser Token Decl a
+> topDecl flat
+>   | flat = infixDecl <|> dataDecl flat <|> typeDecl <|> functionDecl flat
+>   | otherwise = infixDecl
+>             <|> dataDecl flat <|> newtypeDecl <|> typeDecl
+>             <|> functionDecl flat <|> externalDecl
+
+> localDefs :: Bool -> Parser Token [Decl] a
+> localDefs flat = token KW_where <-*> layout (valueDecls flat)
+>            `opt` []
+
+> valueDecls :: Bool -> Parser Token [Decl] a
+> valueDecls flat = localDecl flat `sepBy` semicolon
+>   where localDecl flat
+>           | flat = infixDecl <|> valueDecl flat
+>           | otherwise = infixDecl <|> valueDecl flat <|> externalDecl
+
+> importDecl :: Parser Token Decl a
+> importDecl =
+>   flip . ImportDecl <$> position <*-> token KW_import 
+>                     <*> (True <$-> token Id_qualified `opt` False)
+>                     <*> mIdent
+>                     <*> (Just <$-> token Id_as <*> mIdent `opt` Nothing)
+>                     <*> (Just <$> importSpec `opt` Nothing)
+
+> importSpec :: Parser Token ImportSpec a
+> importSpec = position <**> (Hiding <$-> token Id_hiding `opt` Importing)
+>                       <*> parens (spec `sepBy` comma)
+>   where spec = tycon <**> (parens constrs `opt` Import)
+>            <|> Import <$> fun <\> tycon
+>         constrs = ImportTypeAll <$-> token DotDot
+>               <|> flip ImportTypeWith <$> con `sepBy` comma
+
+> infixDecl :: Parser Token Decl a
+> infixDecl = infixDeclLhs InfixDecl <*> funop `sepBy1` comma
+
+> infixDeclLhs :: (Position -> Infix -> Integer -> a) -> Parser Token a b
+> infixDeclLhs f = f <$> position <*> tokenOps infixKW <*> integer
+>   where infixKW = [(KW_infix,Infix),(KW_infixl,InfixL),(KW_infixr,InfixR)]
+
+> dataDecl :: Bool -> Parser Token Decl a
+> dataDecl flat = typeDeclLhs DataDecl KW_data <*> constrs
+>   where constrs = equals <-*> constrDecl flat `sepBy1` bar
+>             `opt` []
+
+> newtypeDecl :: Parser Token Decl a
+> newtypeDecl =
+>   typeDeclLhs NewtypeDecl KW_newtype <*-> equals <*> newConstrDecl
+
+> typeDecl :: Parser Token Decl a
+> typeDecl = typeDeclLhs TypeDecl KW_type <*-> equals <*> typeDeclRhs --type0
+
+> typeDeclLhs :: (Position -> Ident -> [Ident] -> a) -> Category
+>             -> Parser Token a b
+> typeDeclLhs f kw = f <$> position <*-> token kw <*> tycon <*> many typeVar
+>   where typeVar = tyvar <|> anonId <$-> token Underscore
+
+> typeDeclRhs :: Parser Token TypeExpr a
+> typeDeclRhs = type0
+>	        <|> flip RecordType Nothing
+>		   <$> (layoutOff <-*> braces (labelDecls `sepBy` comma))
+
+> labelDecls = (,) <$> labId `sepBy1` comma <*-> token DoubleColon <*> type0
+
+> constrDecl :: Bool -> Parser Token ConstrDecl a
+> constrDecl flat = position <**> (existVars <**> constr)
+>   where constr = conId <**> identDecl
+>              <|> leftParen <-*> parenDecl
+>              <|> type1 <\> conId <\> leftParen <**> opDecl
+>         identDecl = many type2 <**> (conType <$> opDecl `opt` conDecl)
+>         parenDecl = conOpDeclPrefix 
+>	              <$> conSym <*-> rightParen <*> type2 <*> type2
+>                 <|> tupleType <*-> rightParen <**> opDecl
+>         opDecl = conOpDecl <$> conop <*> type1
+>         conType f tys c = f (ConstructorType (qualify c) tys)
+>         conDecl tys c tvs p = ConstrDecl p tvs c tys
+>         conOpDecl op ty2 ty1 tvs p = ConOpDecl p tvs ty1 op ty2
+>         conOpDeclPrefix op ty1 ty2 tvs p = ConOpDecl p tvs ty1 op ty2
+
+> newConstrDecl :: Parser Token NewConstrDecl a
+> newConstrDecl =
+>   NewConstrDecl <$> position <*> existVars <*> con <*> type2
+
+> existVars :: Parser Token [Ident] a
+> {-
+> existVars flat
+>   | flat = succeed []
+>   | otherwise = token Id_forall <-*> many1 tyvar <*-> dot `opt` []
+> -}
+> existVars = succeed []
+
+> functionDecl :: Bool -> Parser Token Decl a
+> functionDecl flat = position <**> decl
+>   where decl = fun `sepBy1` comma <**> funListDecl flat
+>           <|?> funDecl <$> lhs <*> declRhs flat
+>         lhs = (\f -> (f,FunLhs f [])) <$> fun
+>          <|?> funLhs
+
+> valueDecl :: Bool -> Parser Token Decl a
+> valueDecl flat = position <**> decl
+>   where decl = var `sepBy1` comma <**> valListDecl flat
+>           <|?> valDecl <$> constrTerm0 <*> declRhs flat
+>           <|?> funDecl <$> curriedLhs <*> declRhs flat
+>         valDecl t@(ConstructorPattern c ts)
+>           | not (isConstrId c) = funDecl (f,FunLhs f ts)
+>           where f = unqualify c
+>         valDecl t = opDecl id t
+>         opDecl f (InfixPattern t1 op t2)
+>           | isConstrId op = opDecl (f . InfixPattern t1 op) t2
+>           | otherwise = funDecl (op',OpLhs (f t1) op' t2)
+>           where op' = unqualify op
+>         opDecl f t = patDecl (f t)
+>         isConstrId c = c == qConsId || isQualified c || isQTupleId c
+
+> funDecl :: (Ident,Lhs) -> Rhs -> Position -> Decl
+> funDecl (f,lhs) rhs p = FunctionDecl p f [Equation p lhs rhs]
+
+> patDecl :: ConstrTerm -> Rhs -> Position -> Decl
+> patDecl t rhs p = PatternDecl p t rhs
+
+> funListDecl :: Bool -> Parser Token ([Ident] -> Position -> Decl) a
+> funListDecl flat
+>   | flat = typeSig <$-> token DoubleColon <*> type0
+>        <|> evalAnnot <$-> token KW_eval <*> tokenOps evalKW
+>        <|> externalDecl <$-> token KW_external
+>   | otherwise = typeSig <$-> token DoubleColon <*> type0
+>             <|> evalAnnot <$-> token KW_eval <*> tokenOps evalKW
+>   where typeSig ty vs p = TypeSig p vs ty
+>         evalAnnot ev vs p = EvalAnnot p vs ev
+>         evalKW = [(KW_rigid,EvalRigid),(KW_choice,EvalChoice)]
+>         externalDecl vs p = FlatExternalDecl p vs
+
+> valListDecl :: Bool -> Parser Token ([Ident] -> Position -> Decl) a
+> valListDecl flat = funListDecl flat <|> extraVars <$-> token KW_free
+>   where extraVars vs p = ExtraVariables p vs
+
+> funLhs :: Parser Token (Ident,Lhs) a
+> funLhs = funLhs <$> fun <*> many1 constrTerm2
+>     <|?> flip ($ id) <$> constrTerm1 <*> opLhs'
+>     <|?> curriedLhs
+>   where opLhs' = opLhs <$> funSym <*> constrTerm0
+>              <|> infixPat <$> gConSym <\> funSym <*> constrTerm1 <*> opLhs'
+>              <|> backquote <-*> opIdLhs
+>         opIdLhs = opLhs <$> funId <*-> checkBackquote <*> constrTerm0
+>               <|> infixPat <$> qConId <\> funId <*-> backquote <*> constrTerm1
+>                            <*> opLhs'
+>         funLhs f ts = (f,FunLhs f ts)
+>         opLhs op t2 f t1 = (op,OpLhs (f t1) op t2)
+>         infixPat op t2 f g t1 = f (g . InfixPattern t1 op) t2
+
+> curriedLhs :: Parser Token (Ident,Lhs) a
+> curriedLhs = apLhs <$> parens funLhs <*> many1 constrTerm2
+>   where apLhs (f,lhs) ts = (f,ApLhs lhs ts)
+
+> declRhs :: Bool -> Parser Token Rhs a
+> declRhs flat = rhs flat equals
+
+> rhs :: Bool -> Parser Token a b -> Parser Token Rhs b
+> rhs flat eq = rhsExpr <*> localDefs flat
+>   where rhsExpr = SimpleRhs <$-> eq <*> position <*> expr flat
+>               <|> GuardedRhs <$> many1 (condExpr flat eq)
+
+> externalDecl :: Parser Token Decl a
+> externalDecl =
+>   ExternalDecl <$> position <*-> token KW_external
+>                <*> callConv <*> (Just <$> string `opt` Nothing)
+>                <*> fun <*-> token DoubleColon <*> type0
+>   where callConv = CallConvPrimitive <$-> token Id_primitive
+>                <|> CallConvCCall <$-> token Id_ccall
+>                <?> "Unsupported calling convention"
+
+\end{verbatim}
+\paragraph{Interface declarations}
+\begin{verbatim}
+
+> --intfDecls :: Parser Token [IDecl] a
+> --intfDecls = (:) <$> iImportDecl <*> (semicolon <-*> intfDecls `opt` [])
+> --        <|> intfDecl `sepBy` semicolon
+
+> --intfDecl :: Parser Token IDecl a
+> --intfDecl = iInfixDecl
+> --       <|> iHidingDecl <|> iDataDecl <|> iNewtypeDecl <|> iTypeDecl
+> --       <|> iFunctionDecl <\> token Id_hiding
+
+> --iImportDecl :: Parser Token IDecl a
+> --iImportDecl = IImportDecl <$> position <*-> token KW_import <*> mIdent
+
+> --iInfixDecl :: Parser Token IDecl a
+> --iInfixDecl = infixDeclLhs IInfixDecl <*> qfunop
+
+> --iHidingDecl :: Parser Token IDecl a
+> --iHidingDecl = position <*-> token Id_hiding <**> (dataDecl <|> funcDecl)
+> --  where dataDecl = hiddenData <$-> token KW_data <*> tycon <*> many tyvar
+> --        funcDecl = hidingFunc <$-> token DoubleColon <*> type0
+> --        hiddenData tc tvs p = HidingDataDecl p tc tvs
+> --        hidingFunc ty p = IFunctionDecl p hidingId ty
+> --        hidingId = qualify (mkIdent "hiding")
+
+> --iDataDecl :: Parser Token IDecl a
+> --iDataDecl = iTypeDeclLhs IDataDecl KW_data <*> constrs
+> --  where constrs = equals <-*> iConstrDecl `sepBy1` bar
+> --            `opt` []
+> --        iConstrDecl = Just <$> constrDecl False <\> token Underscore
+> --                  <|> Nothing <$-> token Underscore
+
+> --iNewtypeDecl :: Parser Token IDecl a
+> --iNewtypeDecl =
+> --  iTypeDeclLhs INewtypeDecl KW_newtype <*-> equals <*> newConstrDecl
+
+> --iTypeDecl :: Parser Token IDecl a
+> --iTypeDecl = iTypeDeclLhs ITypeDecl KW_type <*-> equals <*> type0
+
+> --iTypeDeclLhs :: (Position -> QualIdent -> [Ident] -> a) -> Category
+> --             -> Parser Token a b
+> --iTypeDeclLhs f kw = f <$> position <*-> token kw <*> qtycon <*> many tyvar
+
+> --iFunctionDecl :: Parser Token IDecl a
+> --iFunctionDecl = IFunctionDecl <$> position <*> qfun <*-> token DoubleColon
+> --                              <*> type0
+
+\end{verbatim}
+\paragraph{Types}
+\begin{verbatim}
+
+> type0 :: Parser Token TypeExpr a
+> type0 = type1 `chainr1` (ArrowType <$-> token RightArrow)
+
+> type1 :: Parser Token TypeExpr a
+> type1 = ConstructorType <$> qtycon <*> many type2
+>     <|> type2 <\> qtycon
+
+> type2 :: Parser Token TypeExpr a
+> type2 = anonType <|> identType <|> parenType <|> listType
+
+> anonType :: Parser Token TypeExpr a
+> anonType = VariableType anonId <$-> token Underscore
+
+> identType :: Parser Token TypeExpr a
+> identType = VariableType <$> tyvar
+>         <|> flip ConstructorType [] <$> qtycon <\> tyvar
+
+> parenType :: Parser Token TypeExpr a
+> parenType = parens tupleType
+
+> tupleType :: Parser Token TypeExpr a
+> tupleType = type0 <??> (tuple <$> many1 (comma <-*> type0))
+>       `opt` TupleType []
+>   where tuple tys ty = TupleType (ty:tys)
+
+> listType :: Parser Token TypeExpr a
+> listType = ListType <$> brackets type0
+
+\end{verbatim}
+\paragraph{Literals}
+\begin{verbatim}
+
+> literal :: Parser Token Literal a
+> literal = mk Char   <$> char
+>       <|> mkInt     <$> integer
+>       <|> mk Float  <$> float
+>       <|> mk String <$> string
+
+\end{verbatim}
+\paragraph{Patterns}
+\begin{verbatim}
+
+> constrTerm0 :: Parser Token ConstrTerm a
+> constrTerm0 = constrTerm1 `chainr1` (flip InfixPattern <$> gconop)
+
+> constrTerm1 :: Parser Token ConstrTerm a
+> constrTerm1 = varId <**> identPattern
+>	    <|> ConstructorPattern <$> qConId <\> varId <*> many constrTerm2
+>           <|> minus <**> negNum
+>           <|> fminus <**> negFloat
+>           <|> leftParen <-*> parenPattern
+>           <|> constrTerm2 <\> qConId <\> leftParen
+>   where identPattern = optAsPattern
+>                    <|> conPattern <$> many1 constrTerm2
+>         parenPattern = minus <**> minusPattern negNum
+>                    <|> fminus <**> minusPattern negFloat
+>                    <|> gconPattern
+>                    <|> funSym <\> minus <\> fminus <*-> rightParen
+>                                                    <**> identPattern
+>                    <|> parenTuplePattern <\> minus <\> fminus <*-> rightParen
+>         minusPattern p = rightParen <-*> identPattern
+>                      <|> parenMinusPattern p <*-> rightParen
+>         gconPattern = ConstructorPattern <$> gconId <*-> rightParen
+>                                          <*> many constrTerm2
+>         conPattern ts = flip ConstructorPattern ts . qualify
+
+> constrTerm2 :: Parser Token ConstrTerm a
+> constrTerm2 = literalPattern <|> anonPattern <|> identPattern
+>           <|> parenPattern <|> listPattern <|> lazyPattern
+>	    <|> recordPattern
+
+> literalPattern :: Parser Token ConstrTerm a
+> literalPattern = LiteralPattern <$> literal
+
+> anonPattern :: Parser Token ConstrTerm a
+> anonPattern = VariablePattern anonId <$-> token Underscore
+
+> identPattern :: Parser Token ConstrTerm a
+> identPattern = varId <**> optAsPattern
+>            <|> flip ConstructorPattern [] <$> qConId <\> varId
+
+> parenPattern :: Parser Token ConstrTerm a
+> parenPattern = leftParen <-*> parenPattern
+>   where parenPattern = minus <**> minusPattern negNum
+>                    <|> fminus <**> minusPattern negFloat
+>                    <|> flip ConstructorPattern [] <$> gconId <*-> rightParen
+>                    <|> funSym <\> minus <\> fminus <*-> rightParen
+>                                                    <**> optAsPattern
+>                    <|> parenTuplePattern <\> minus <\> fminus <*-> rightParen
+>         minusPattern p = rightParen <-*> optAsPattern
+>                      <|> parenMinusPattern p <*-> rightParen
+
+> listPattern :: Parser Token ConstrTerm a
+> listPattern = mk' ListPattern <$> brackets (constrTerm0 `sepBy` comma)
+
+> lazyPattern :: Parser Token ConstrTerm a
+> lazyPattern = mk LazyPattern <$-> token Tilde <*> constrTerm2
+
+> recordPattern :: Parser Token ConstrTerm a
+> recordPattern = layoutOff <-*> braces content
+>   where
+>   content = RecordPattern <$> fields <*> record
+>   fields = fieldPatt `sepBy` comma
+>   fieldPatt = Field <$> position <*> labId <*-> checkEquals <*> constrTerm0
+>   record = Just <$-> checkBar <*> constrTerm2 `opt` Nothing
+
+\end{verbatim}
+Partial patterns used in the combinators above, but also for parsing
+the left-hand side of a declaration.
+\begin{verbatim}
+
+> gconId :: Parser Token QualIdent a
+> gconId = colon <|> tupleCommas
+
+> negNum,negFloat :: Parser Token (Ident -> ConstrTerm) a
+> negNum = flip NegativePattern 
+>          <$> (mkInt <$> integer <|> mk Float <$> float)
+> negFloat = flip NegativePattern . mk Float 
+>            <$> (fromIntegral <$> integer <|> float)
+
+> optAsPattern :: Parser Token (Ident -> ConstrTerm) a
+> optAsPattern = flip AsPattern <$-> token At <*> constrTerm2
+>          `opt` VariablePattern
+
+> optInfixPattern :: Parser Token (ConstrTerm -> ConstrTerm) a
+> optInfixPattern = infixPat <$> gconop <*> constrTerm0
+>             `opt` id
+>   where infixPat op t2 t1 = InfixPattern t1 op t2
+
+> optTuplePattern :: Parser Token (ConstrTerm -> ConstrTerm) a
+> optTuplePattern = tuple <$> many1 (comma <-*> constrTerm0)
+>             `opt` ParenPattern
+>   where tuple ts t = mk TuplePattern (t:ts)
+
+> parenMinusPattern :: Parser Token (Ident -> ConstrTerm) a
+>                   -> Parser Token (Ident -> ConstrTerm) a
+> parenMinusPattern p = p <.> optInfixPattern <.> optTuplePattern
+
+> parenTuplePattern :: Parser Token ConstrTerm a
+> parenTuplePattern = constrTerm0 <**> optTuplePattern
+>               `opt` mk TuplePattern []
+
+\end{verbatim}
+\paragraph{Expressions}
+\begin{verbatim}
+
+> condExpr :: Bool -> Parser Token a b -> Parser Token CondExpr b
+> condExpr flat eq =
+>   CondExpr <$> position <*-> bar <*> expr0 flat <*-> eq <*> expr flat
+
+> expr :: Bool -> Parser Token Expression a
+> expr flat = expr0 flat <??> (flip Typed <$-> token DoubleColon <*> type0)
+
+> expr0 :: Bool -> Parser Token Expression a
+> expr0 flat = expr1 flat `chainr1` (flip InfixApply <$> infixOp)
+
+> expr1 :: Bool -> Parser Token Expression a
+> expr1 flat = UnaryMinus <$> (minus <|> fminus) <*> expr2 flat
+>          <|> expr2 flat
+
+> expr2 :: Bool -> Parser Token Expression a
+> expr2 flat = lambdaExpr flat <|> letExpr flat <|> doExpr flat
+>          <|> ifExpr flat <|> caseExpr flat
+>          <|> expr3 flat <**> applicOrSelect
+>   where
+>   applicOrSelect = flip RecordSelection 
+>	                  <$-> (token RightArrow <?> "-> expected")
+>			  <*> labId
+>		 <|?> (\es e -> foldl1 Apply (e:es))
+>		          <$> many (expr3 flat) 
+
+> expr3 :: Bool -> Parser Token Expression a
+> expr3 flat = expr3' 
+>   where
+>   expr3' = constant <|> variable <|> parenExpr flat
+>        <|> listExpr flat <|> recordExpr flat
+
+> constant :: Parser Token Expression a
+> constant = Literal <$> literal
+
+> variable :: Parser Token Expression a
+> variable = Variable <$> qFunId
+
+> parenExpr :: Bool -> Parser Token Expression a
+> parenExpr flat = parens pExpr
+>   where pExpr = (minus <|> fminus) <**> minusOrTuple
+>             <|> Constructor <$> tupleCommas
+>             <|> leftSectionOrTuple <\> minus <\> fminus
+>             <|> opOrRightSection <\> minus <\> fminus
+>           `opt` mk Tuple []
+>         minusOrTuple = flip UnaryMinus <$> expr1 flat <.> infixOrTuple
+>                  `opt` Variable . qualify
+>         leftSectionOrTuple = expr1 flat <**> infixOrTuple
+>         infixOrTuple = ($ id) <$> infixOrTuple'
+>         infixOrTuple' = infixOp <**> leftSectionOrExp
+>                     <|> (.) <$> (optType <.> tupleExpr)
+>         leftSectionOrExp = expr1 flat <**> (infixApp <$> infixOrTuple')
+>                      `opt` leftSection
+>         optType = flip Typed <$-> token DoubleColon <*> type0
+>             `opt` id
+>         tupleExpr = tuple <$> many1 (comma <-*> expr flat)
+>               `opt` Paren
+>         opOrRightSection = qFunSym <**> optRightSection
+>                        <|> colon <**> optCRightSection
+>                        <|> infixOp <\> colon <\> qFunSym <**> rightSection
+>         optRightSection = (. InfixOp) <$> rightSection `opt` Variable
+>         optCRightSection = (. InfixConstr) <$> rightSection `opt` Constructor
+>         rightSection = flip RightSection <$> expr0 flat
+>         infixApp f e2 op g e1 = f (g . InfixApply e1 op) e2
+>         leftSection op f e = LeftSection (f e) op
+>         tuple es e = mk Tuple (e:es)
+
+> infixOp :: Parser Token InfixOp a
+> infixOp = InfixOp <$> qfunop
+>       <|> InfixConstr <$> colon
+
+> listExpr :: Bool -> Parser Token Expression a
+> listExpr flat = brackets (elements `opt` mk' List [])
+>   where elements = expr flat <**> rest
+>         rest = comprehension
+>            <|> enumeration (flip EnumFromTo) EnumFrom
+>            <|> comma <-*> expr flat <**>
+>                (enumeration (flip3 EnumFromThenTo) (flip EnumFromThen)
+>                <|> list <$> many (comma <-*> expr flat))
+>          `opt` (\e -> mk' List [e])
+>         comprehension = flip (mk ListCompr) <$-> bar <*> quals flat
+>         enumeration enumTo enum =
+>           token DotDot <-*> (enumTo <$> expr flat `opt` enum)
+>         list es e2 e1 = mk' List (e1:e2:es)
+>         flip3 f x y z = f z y x
+
+> recordExpr :: Bool -> Parser Token Expression a
+> recordExpr flat = layoutOff <-*> braces content
+>   where content = RecordConstr <$> fieldConstr `sepBy` comma
+>	            <|?> RecordUpdate <$> fieldUpdate `sepBy` comma
+>		                      <*-> checkBar <*> expr flat
+>	  fieldConstr = Field <$> position <*> labId 
+>		              <*-> checkEquals <*> expr flat
+>	  fieldUpdate = Field <$> position <*> labId 
+>		              <*-> checkBinds <*> expr flat
+
+> lambdaExpr :: Bool -> Parser Token Expression a
+> lambdaExpr flat =
+>   mk Lambda <$-> token Backslash <*> many1 constrTerm2
+>          <*-> (token RightArrow <?> "-> expected") <*> expr flat
+
+> letExpr :: Bool -> Parser Token Expression a
+> letExpr flat = Let <$-> token KW_let <*> layout (valueDecls flat)
+>                    <*-> (token KW_in <?> "in expected") <*> expr flat
+
+> doExpr :: Bool -> Parser Token Expression a
+> doExpr flat = uncurry Do <$-> token KW_do <*> layout (stmts flat)
+
+> ifExpr :: Bool -> Parser Token Expression a
+> ifExpr flat =
+>   mk IfThenElse <$-> token KW_if <*> expr flat
+>              <*-> (token KW_then <?> "then expected") <*> expr flat
+>              <*-> (token KW_else <?> "else expected") <*> expr flat
+
+> caseExpr :: Bool -> Parser Token Expression a
+> caseExpr flat = mk Case <$-> token KW_case <*> expr flat
+>                 <*-> (token KW_of <?> "of expected") <*> layout (alts flat)
+
+> alts :: Bool -> Parser Token [Alt] a
+> alts flat = alt flat `sepBy1` semicolon
+
+> alt :: Bool -> Parser Token Alt a
+> alt flat = Alt <$> position <*> constrTerm0
+>                <*> rhs flat (token RightArrow <?> "-> expected")
+
+\end{verbatim}
+\paragraph{Statements in list comprehensions and \texttt{do} expressions}
+Parsing statements is a bit difficult because the syntax of patterns
+and expressions largely overlaps. The parser will first try to
+recognize the prefix \emph{Pattern}~\texttt{<-} of a binding statement
+and if this fails fall back into parsing an expression statement. In
+addition, we have to be prepared that the sequence
+\texttt{let}~\emph{LocalDefs} can be either a let-statement or the
+prefix of a let expression.
+\begin{verbatim}
+
+> stmts :: Bool -> Parser Token ([Statement],Expression) a
+> stmts flat = stmt flat (reqStmts flat) (optStmts flat)
+
+> reqStmts :: Bool -> Parser Token (Statement -> ([Statement],Expression)) a
+> reqStmts flat = (\(sts,e) st -> (st : sts,e)) <$-> semicolon <*> stmts flat
+
+> optStmts :: Bool -> Parser Token (Expression -> ([Statement],Expression)) a
+> optStmts flat = succeed (mk StmtExpr) <.> reqStmts flat
+>           `opt` (,) []
+
+> quals :: Bool -> Parser Token [Statement] a
+> quals flat = stmt flat (succeed id) (succeed $ mk StmtExpr) `sepBy1` comma
+
+> stmt :: Bool -> Parser Token (Statement -> a) b
+>      -> Parser Token (Expression -> a) b -> Parser Token a b
+> stmt flat stmtCont exprCont = letStmt flat stmtCont exprCont
+>                           <|> exprOrBindStmt flat stmtCont exprCont
+
+> letStmt :: Bool -> Parser Token (Statement -> a) b
+>         -> Parser Token (Expression -> a) b -> Parser Token a b
+> letStmt flat stmtCont exprCont =
+>   token KW_let <-*> layout (valueDecls flat) <**> optExpr
+>   where optExpr = flip Let <$-> token KW_in <*> expr flat <.> exprCont
+>               <|> succeed StmtDecl <.> stmtCont
+
+> exprOrBindStmt :: Bool -> Parser Token (Statement -> a) b
+>                -> Parser Token (Expression -> a) b
+>                -> Parser Token a b
+> exprOrBindStmt flat stmtCont exprCont =
+>        mk StmtBind <$> constrTerm0 <*-> leftArrow <*> expr flat <**> stmtCont
+>   <|?> expr flat <\> token KW_let <**> exprCont
+
+\end{verbatim}
+\paragraph{Literals, identifiers, and (infix) operators}
+\begin{verbatim}
+
+> char :: Parser Token Char a
+> char = cval <$> token CharTok
+
+> int, checkInt :: Parser Token Int a
+> int = ival <$> token IntTok
+> checkInt = int <?> "integer number expected"
+
+> float, checkFloat :: Parser Token Double a
+> float = fval <$> token FloatTok
+> checkFloat = float <?> "floating point number expected"
+
+> integer, checkInteger :: Parser Token Integer a
+> integer = intval <$> token IntegerTok
+> checkInteger = integer <?> "integer number expected"
+
+> string :: Parser Token String a
+> string = sval <$> token StringTok
+
+> tycon, tyvar :: Parser Token Ident a
+> tycon = conId
+> tyvar = varId
+
+> qtycon :: Parser Token QualIdent a
+> qtycon = qConId
+
+> varId, funId, conId, labId :: Parser Token Ident a
+> varId = ident
+> funId = ident
+> conId = ident
+> labId = renameLabel <$> ident
+
+> funSym, conSym :: Parser Token Ident a
+> funSym = sym
+> conSym = sym
+
+> var, fun, con :: Parser Token Ident a
+> var = varId <|> parens (funSym <?> "operator symbol expected")
+> fun = funId <|> parens (funSym <?> "operator symbol expected")
+> con = conId <|> parens (conSym <?> "operator symbol expected")
+
+> funop, conop :: Parser Token Ident a
+> funop = funSym <|> backquotes (funId <?> "operator name expected")
+> conop = conSym <|> backquotes (conId <?> "operator name expected")
+
+> qFunId, qConId, qLabId :: Parser Token QualIdent a
+> qFunId = qIdent
+> qConId = qIdent
+> qLabId = qIdent
+
+> qFunSym, qConSym :: Parser Token QualIdent a
+> qFunSym = qSym
+> qConSym = qSym
+> gConSym = qConSym <|> colon
+
+> qfun, qcon :: Parser Token QualIdent a
+> qfun = qFunId <|> parens (qFunSym <?> "operator symbol expected")
+> qcon = qConId <|> parens (qConSym <?> "operator symbol expected")
+
+> qfunop, qconop, gconop :: Parser Token QualIdent a
+> qfunop = qFunSym <|> backquotes (qFunId <?> "operator name expected")
+> qconop = qConSym <|> backquotes (qConId <?> "operator name expected")
+> gconop = gConSym <|> backquotes (qConId <?> "operator name expected")
+
+> ident :: Parser Token Ident a
+> ident = (\ pos -> mkIdentPosition pos . sval) <$> position <*> 
+>        tokens [Id,Id_as,Id_ccall,Id_forall,Id_hiding,
+>                Id_interface,Id_primitive,Id_qualified]
+
+> qIdent :: Parser Token QualIdent a
+> qIdent = qualify <$> ident <|> mkQIdent <$> position <*> token QId
+>   where mkQIdent p a = qualifyWith (mkMIdent (modul a)) 
+>                                    (mkIdentPosition p (sval a))
+
+> mIdent :: Parser Token ModuleIdent a
+> mIdent = mIdent <$> position <*> 
+>      tokens [Id,QId,Id_as,Id_ccall,Id_forall,Id_hiding,
+>              Id_interface,Id_primitive,Id_qualified]
+>   where mIdent p a = addPositionModuleIdent p $ 
+>                      mkMIdent (modul a ++ [sval a])
+
+> sym :: Parser Token Ident a
+> sym = (\ pos -> mkIdentPosition pos . sval) <$> position <*> 
+>       tokens [Sym,Sym_Dot,Sym_Minus,Sym_MinusDot]
+
+> qSym :: Parser Token QualIdent a
+> qSym = qualify <$> sym <|> mkQIdent <$> position <*> token QSym
+>   where mkQIdent p a = qualifyWith (mkMIdent (modul a)) 
+>                                    (mkIdentPosition p (sval a))
+
+> colon :: Parser Token QualIdent a
+> colon = (\ p _ -> qualify $ addPositionIdent p consId) <$> 
+>         position <*> token Colon
+
+> minus :: Parser Token Ident a
+> minus = (\ p _ -> addPositionIdent p minusId) <$> 
+>         position <*> token Sym_Minus
+
+> fminus :: Parser Token Ident a
+> fminus = (\ p _ -> addPositionIdent p fminusId) <$> 
+>         position <*> token Sym_MinusDot
+
+> tupleCommas :: Parser Token QualIdent a
+> tupleCommas = (\ p -> qualify . addPositionIdent p . tupleId . succ . length )
+>               <$> position <*> many1 comma
+
+\end{verbatim}
+\paragraph{Layout}
+\begin{verbatim}
+
+> layout :: Parser Token a b -> Parser Token a b
+> layout p = layoutOff <-*> bracket leftBraceSemicolon p rightBrace
+>        <|> layoutOn <-*> p <*-> (token VRightBrace <|> layoutEnd)
+
+\end{verbatim}
+\paragraph{More combinators}
+\begin{verbatim}
+
+> braces, brackets, parens, backquotes :: Parser Token a b -> Parser Token a b
+> braces p = bracket leftBrace p rightBrace
+> brackets p = bracket leftBracket p rightBracket
+> parens p = bracket leftParen p rightParen
+> backquotes p = bracket backquote p checkBackquote
+
+\end{verbatim}
+\paragraph{Simple token parsers}
+\begin{verbatim}
+
+> token :: Category -> Parser Token Attributes a
+> token c = attr <$> symbol (Token c NoAttributes)
+>   where attr (Token _ a) = a
+
+> tokens :: [Category] -> Parser Token Attributes a
+> tokens = foldr1 (<|>) . map token
+
+> tokenOps :: [(Category,a)] -> Parser Token a b
+> tokenOps cs = ops [(Token c NoAttributes,x) | (c,x) <- cs]
+
+> dot, comma, semicolon, bar, equals, binds :: Parser Token Attributes a
+> dot = token Sym_Dot
+> comma = token Comma
+> semicolon = token Semicolon <|> token VSemicolon
+> bar = token Bar
+> equals = token Equals
+> binds = token Binds
+
+> checkBar, checkEquals, checkBinds :: Parser Token Attributes a
+> checkBar = bar <?> "| expected"
+> checkEquals = equals <?> "= expected"
+> checkBinds = binds <?> ":= expected"
+
+> backquote, checkBackquote :: Parser Token Attributes a
+> backquote = token Backquote
+> checkBackquote = backquote <?> "backquote (`) expected"
+
+> leftParen, rightParen :: Parser Token Attributes a
+> leftParen = token LeftParen
+> rightParen = token RightParen
+
+> leftBracket, rightBracket :: Parser Token Attributes a
+> leftBracket = token LeftBracket
+> rightBracket = token RightBracket
+
+> leftBrace, leftBraceSemicolon, rightBrace :: Parser Token Attributes a
+> leftBrace = token LeftBrace
+> leftBraceSemicolon = token LeftBraceSemicolon
+> rightBrace = token RightBrace
+
+> leftArrow :: Parser Token Attributes a
+> leftArrow = token LeftArrow
+
+\end{verbatim}
+\paragraph{Ident}
+\begin{verbatim}
+
+> mkIdentPosition :: Position -> String -> Ident
+> mkIdentPosition pos = addPositionIdent pos . mkIdent
+
+\end{verbatim}
diff --git a/src/Curry/Syntax/Pretty.lhs b/src/Curry/Syntax/Pretty.lhs
new file mode 100644
--- /dev/null
+++ b/src/Curry/Syntax/Pretty.lhs
@@ -0,0 +1,367 @@
+
+% $Id: CurryPP.lhs,v 1.50 2004/02/15 22:10:27 wlux Exp $
+%
+% Copyright (c) 1999-2004, Wolfgang Lux
+% See LICENSE for the full license.
+%
+% Modified by Martin Engelke (men@informatik.uni-kiel.de)
+%
+\nwfilename{CurryPP.lhs}
+\section{A Pretty Printer for Curry}\label{sec:CurryPP}
+This module implements a pretty printer for Curry expressions. It was
+derived from the Haskell pretty printer provided in Simon Marlow's
+Haskell parser.
+\begin{verbatim}
+
+> module Curry.Syntax.Pretty where
+
+> import Curry.Base.Ident
+> import Curry.Syntax.Type
+
+> import PrettyCombinators
+
+\end{verbatim}
+Pretty print a module
+\begin{verbatim}
+
+> ppModule :: Module -> Doc
+> ppModule (Module m es ds) = ppModuleHeader m es $$ ppBlock ds
+
+\end{verbatim}
+Module header
+\begin{verbatim}
+
+> ppModuleHeader :: ModuleIdent -> Maybe ExportSpec -> Doc
+> ppModuleHeader m es =
+>   text "module" <+> ppMIdent m <+> maybePP ppExportSpec es <+> text "where"
+
+> ppExportSpec :: ExportSpec -> Doc
+> ppExportSpec (Exporting _ es) = parenList (map ppExport es)
+
+> ppExport :: Export -> Doc
+> ppExport (Export x) = ppQIdent x
+> ppExport (ExportTypeWith tc cs) = ppQIdent tc <> parenList (map ppIdent cs)
+> ppExport (ExportTypeAll tc) = ppQIdent tc <> text "(..)"
+> ppExport (ExportModule m) = text "module" <+> ppMIdent m
+
+\end{verbatim}
+Declarations
+\begin{verbatim}
+
+> ppBlock :: [Decl] -> Doc
+> ppBlock = vcat . map ppDecl
+
+> ppDecl :: Decl -> Doc
+> ppDecl (ImportDecl _ m q asM is) =
+>   text "import" <+> ppQualified q <+> ppMIdent m <+> maybePP ppAs asM
+>                 <+> maybePP ppImportSpec is
+>   where ppQualified q = if q then text "qualified" else empty
+>         ppAs m = text "as" <+> ppMIdent m
+> ppDecl (InfixDecl _ fix p ops) = ppPrec fix p <+> list (map ppInfixOp ops)
+> ppDecl (DataDecl _ tc tvs cs) =
+>   sep (ppTypeDeclLhs "data" tc tvs :
+>        map indent (zipWith (<+>) (equals : repeat vbar) (map ppConstr cs)))
+> ppDecl (NewtypeDecl _ tc tvs nc) =
+>   sep [ppTypeDeclLhs "newtype" tc tvs <+> equals,indent (ppNewConstr nc)]
+> ppDecl (TypeDecl _ tc tvs ty) =
+>   sep [ppTypeDeclLhs "type" tc tvs <+> equals,indent (ppTypeExpr 0 ty)]
+> ppDecl (TypeSig _ fs ty) =
+>   list (map ppIdent fs) <+> text "::" <+> ppTypeExpr 0 ty
+> ppDecl (EvalAnnot _ fs ev) =
+>   list (map ppIdent fs) <+> text "eval" <+> ppEval ev
+>   where ppEval EvalRigid = text "rigid"
+>         ppEval EvalChoice = text "choice"
+> ppDecl (FunctionDecl _ _ eqs) = vcat (map ppEquation eqs)
+> ppDecl (ExternalDecl p cc impent f ty) =
+>   sep [text "external" <+> ppCallConv cc <+> maybePP (text . show) impent,
+>        indent (ppDecl (TypeSig p [f] ty))]
+>   where ppCallConv CallConvPrimitive = text "primitive"
+>         ppCallConv CallConvCCall = text "ccall"
+> ppDecl (FlatExternalDecl _ fs) = list (map ppIdent fs) <+> text "external"
+> ppDecl (PatternDecl _ t rhs) = ppRule (ppConstrTerm 0 t) equals rhs
+> ppDecl (ExtraVariables _ vs) = list (map ppIdent vs) <+> text "free"
+
+> ppImportSpec :: ImportSpec -> Doc
+> ppImportSpec (Importing _ is) = parenList (map ppImport is)
+> ppImportSpec (Hiding _ is) = text "hiding" <+> parenList (map ppImport is)
+
+> ppImport :: Import -> Doc
+> ppImport (Import x) = ppIdent x
+> ppImport (ImportTypeWith tc cs) = ppIdent tc <> parenList (map ppIdent cs)
+> ppImport (ImportTypeAll tc) = ppIdent tc <> text "(..)"
+
+> ppPrec :: Infix -> Integer -> Doc
+> ppPrec fix p = ppAssoc fix <+> ppPrio p
+>   where ppAssoc InfixL = text "infixl"
+>         ppAssoc InfixR = text "infixr"
+>         ppAssoc Infix = text "infix"
+>         ppPrio p = if p < 0 then empty else integer p
+
+> ppTypeDeclLhs :: String -> Ident -> [Ident] -> Doc
+> ppTypeDeclLhs kw tc tvs = text kw <+> ppIdent tc <+> hsep (map ppIdent tvs)
+
+> ppConstr :: ConstrDecl -> Doc
+> ppConstr (ConstrDecl _ tvs c tys) =
+>   sep [ppExistVars tvs,ppIdent c <+> fsep (map (ppTypeExpr 2) tys)]
+> ppConstr (ConOpDecl _ tvs ty1 op ty2) =
+>   sep [ppExistVars tvs,ppTypeExpr 1 ty1,ppInfixOp op <+> ppTypeExpr 1 ty2]
+
+> ppNewConstr :: NewConstrDecl -> Doc
+> ppNewConstr (NewConstrDecl _ tvs c ty) =
+>   sep [ppExistVars tvs,ppIdent c <+> ppTypeExpr 2 ty]
+
+> ppExistVars :: [Ident] -> Doc
+> ppExistVars tvs
+>   | null tvs = empty
+>   | otherwise = text "forall" <+> hsep (map ppIdent tvs) <+> char '.'
+
+> ppEquation :: Equation -> Doc
+> ppEquation (Equation _ lhs rhs) = ppRule (ppLhs lhs) equals rhs
+
+> ppLhs :: Lhs -> Doc
+> ppLhs (FunLhs f ts) = ppIdent f <+> fsep (map (ppConstrTerm 2) ts)
+> ppLhs (OpLhs t1 f t2) =
+>   ppConstrTerm 1 t1 <+> ppInfixOp f <+> ppConstrTerm 1 t2
+> ppLhs (ApLhs lhs ts) = parens (ppLhs lhs) <+> fsep (map (ppConstrTerm 2) ts)
+
+> ppRule :: Doc -> Doc -> Rhs -> Doc
+> ppRule lhs eq (SimpleRhs _ e ds) =
+>   sep [lhs <+> eq,indent (ppExpr 0 e)] $$ ppLocalDefs ds
+> ppRule lhs eq (GuardedRhs es ds) =
+>   sep [lhs,indent (vcat (map (ppCondExpr eq) es))] $$ ppLocalDefs ds
+
+> ppLocalDefs :: [Decl] -> Doc
+> ppLocalDefs ds
+>   | null ds = empty
+>   | otherwise = indent (text "where" <+> ppBlock ds)
+
+\end{verbatim}
+Interfaces
+\begin{verbatim}
+
+> ppInterface :: Interface -> Doc
+> ppInterface (Interface m ds) =
+>   text "interface" <+> ppMIdent m <+> text "where" <+> lbrace
+>     $$ vcat (punctuate semi (map ppIDecl ds)) $$ rbrace
+
+> ppIDecl :: IDecl -> Doc
+> ppIDecl (IImportDecl _ m) = text "import" <+> ppMIdent m
+> ppIDecl (IInfixDecl _ fix p op) = ppPrec fix p <+> ppQInfixOp op
+> ppIDecl (HidingDataDecl _ tc tvs) =
+>   text "hiding" <+> ppITypeDeclLhs "data" (qualify tc) tvs
+> ppIDecl (IDataDecl _ tc tvs cs) =
+>   sep (ppITypeDeclLhs "data" tc tvs :
+>        map indent (zipWith (<+>) (equals : repeat vbar) (map ppIConstr cs)))
+>   where ppIConstr = maybe (char '_') ppConstr
+> ppIDecl (INewtypeDecl _ tc tvs nc) =
+>   sep [ppITypeDeclLhs "newtype" tc tvs <+> equals,indent (ppNewConstr nc)]
+> ppIDecl (ITypeDecl _ tc tvs ty) =
+>   sep [ppITypeDeclLhs "type" tc tvs <+> equals,indent (ppTypeExpr 0 ty)]
+> ppIDecl (IFunctionDecl _ f _ ty) = ppQIdent f <+> text "::" <+> ppTypeExpr 0 ty
+
+> ppITypeDeclLhs :: String -> QualIdent -> [Ident] -> Doc
+> ppITypeDeclLhs kw tc tvs = text kw <+> ppQIdent tc <+> hsep (map ppIdent tvs)
+
+\end{verbatim}
+Types
+\begin{verbatim}
+
+> ppTypeExpr :: Int -> TypeExpr -> Doc
+> ppTypeExpr p (ConstructorType tc tys) =
+>   parenExp (p > 1 && not (null tys))
+>            (ppQIdent tc <+> fsep (map (ppTypeExpr 2) tys))
+> ppTypeExpr _ (VariableType tv) = ppIdent tv
+> ppTypeExpr _ (TupleType tys) = parenList (map (ppTypeExpr 0) tys)
+> ppTypeExpr _ (ListType ty) = brackets (ppTypeExpr 0 ty)
+> ppTypeExpr p (ArrowType ty1 ty2) =
+>   parenExp (p > 0) (fsep (ppArrowType (ArrowType ty1 ty2)))
+>   where ppArrowType (ArrowType ty1 ty2) =
+>           ppTypeExpr 1 ty1 <+> rarrow : ppArrowType ty2
+>         ppArrowType ty = [ppTypeExpr 0 ty]
+> ppTypeExpr p (RecordType fs rty) = 
+>   braces (list (map ppTypedField fs) 
+>           <> maybe empty (\ty -> space <> char '|' <+> ppTypeExpr 0 ty) rty)
+>   where
+>   ppTypedField (ls,ty) = 
+>     list (map ppIdent ls) <> text "::" <> ppTypeExpr 0 ty
+
+
+
+\end{verbatim}
+Literals
+\begin{verbatim}
+
+> ppLiteral :: Literal -> Doc
+> ppLiteral (Char _ c)   = text (show c)
+> ppLiteral (Int _ i)    = integer i
+> ppLiteral (Float _ f)  = double f
+> ppLiteral (String _ s) = text (show s)
+
+\end{verbatim}
+Patterns
+\begin{verbatim}
+
+> ppConstrTerm :: Int -> ConstrTerm -> Doc
+> ppConstrTerm p (LiteralPattern l) =
+>   parenExp (p > 1 && isNegative l) (ppLiteral l)
+>   where isNegative (Char _ _)   = False
+>         isNegative (Int _ i)    = i < 0
+>         isNegative (Float _ f)  = f < 0.0
+>         isNegative (String _ _) = False
+> ppConstrTerm p (NegativePattern op l) =
+>   parenExp (p > 1) (ppInfixOp op <> ppLiteral l)
+> ppConstrTerm _ (VariablePattern v) = ppIdent v
+> ppConstrTerm p (ConstructorPattern c ts) =
+>   parenExp (p > 1 && not (null ts))
+>            (ppQIdent c <+> fsep (map (ppConstrTerm 2) ts))
+> ppConstrTerm p (InfixPattern t1 c t2) =
+>   parenExp (p > 0)
+>            (sep [ppConstrTerm 1 t1 <+> ppQInfixOp c,
+>                  indent (ppConstrTerm 0 t2)])
+> ppConstrTerm _ (ParenPattern t) = parens (ppConstrTerm 0 t)
+> ppConstrTerm _ (TuplePattern _ ts) = parenList (map (ppConstrTerm 0) ts)
+> ppConstrTerm _ (ListPattern _ ts) = bracketList (map (ppConstrTerm 0) ts)
+> ppConstrTerm _ (AsPattern v t) = ppIdent v <> char '@' <> ppConstrTerm 2 t
+> ppConstrTerm _ (LazyPattern _ t) = char '~' <> ppConstrTerm 2 t
+> ppConstrTerm p (FunctionPattern f ts) =
+>   parenExp (p > 1 && not (null ts))
+>            (ppQIdent f <+> fsep (map (ppConstrTerm 2) ts))
+> ppConstrTerm p (InfixFuncPattern t1 f t2) =
+>   parenExp (p > 0)
+>            (sep [ppConstrTerm 1 t1 <+> ppQInfixOp f,
+>                  indent (ppConstrTerm 0 t2)])
+> ppConstrTerm p (RecordPattern fs rt) =
+>   braces (list (map ppFieldPatt fs)
+>          <> (maybe empty (\t -> space <> char '|' <+> ppConstrTerm 0 t) rt))
+
+> ppFieldPatt :: Field ConstrTerm -> Doc
+> ppFieldPatt (Field _ l t) = ppIdent l <> equals <> ppConstrTerm 0 t
+
+\end{verbatim}
+Expressions
+\begin{verbatim}
+
+> ppCondExpr :: Doc -> CondExpr -> Doc
+> ppCondExpr eq (CondExpr _ g e) =
+>   vbar <+> sep [ppExpr 0 g <+> eq,indent (ppExpr 0 e)]
+
+> ppExpr :: Int -> Expression -> Doc
+> ppExpr _ (Literal l) = ppLiteral l
+> ppExpr _ (Variable v) = ppQIdent v
+> ppExpr _ (Constructor c) = ppQIdent c
+> ppExpr _ (Paren e) = parens (ppExpr 0 e)
+> ppExpr p (Typed e ty) =
+>   parenExp (p > 0) (ppExpr 0 e <+> text "::" <+> ppTypeExpr 0 ty)
+> ppExpr _ (Tuple _ es) = parenList (map (ppExpr 0) es)
+> ppExpr _ (List _ es) = bracketList (map (ppExpr 0) es)
+> ppExpr _ (ListCompr _ e qs) =
+>   brackets (ppExpr 0 e <+> vbar <+> list (map ppStmt qs))
+> ppExpr _ (EnumFrom e) = brackets (ppExpr 0 e <+> text "..")
+> ppExpr _ (EnumFromThen e1 e2) =
+>   brackets (ppExpr 0 e1 <> comma <+> ppExpr 0 e2 <+> text "..")
+> ppExpr _ (EnumFromTo e1 e2) =
+>   brackets (ppExpr 0 e1 <+> text ".." <+> ppExpr 0 e2)
+> ppExpr _ (EnumFromThenTo e1 e2 e3) =
+>   brackets (ppExpr 0 e1 <> comma <+> ppExpr 0 e2
+>               <+> text ".." <+> ppExpr 0 e3)
+> ppExpr p (UnaryMinus op e) = parenExp (p > 1) (ppInfixOp op <> ppExpr 1 e)
+> ppExpr p (Apply e1 e2) =
+>   parenExp (p > 1) (sep [ppExpr 1 e1,indent (ppExpr 2 e2)])
+> ppExpr p (InfixApply e1 op e2) =
+>   parenExp (p > 0) (sep [ppExpr 1 e1 <+> ppQInfixOp (opName op),
+>                          indent (ppExpr 1 e2)])
+> ppExpr _ (LeftSection e op) = parens (ppExpr 1 e <+> ppQInfixOp (opName op))
+> ppExpr _ (RightSection op e) = parens (ppQInfixOp (opName op) <+> ppExpr 1 e)
+> ppExpr p (Lambda _ t e) =
+>   parenExp (p > 0)
+>            (sep [backsl <> fsep (map (ppConstrTerm 2) t) <+> rarrow,
+>                  indent (ppExpr 0 e)])
+> ppExpr p (Let ds e) =
+>   parenExp (p > 0)
+>            (sep [text "let" <+> ppBlock ds <+> text "in",ppExpr 0 e])
+> ppExpr p (Do sts e) =
+>   parenExp (p > 0) (text "do" <+> (vcat (map ppStmt sts) $$ ppExpr 0 e))
+> ppExpr p (IfThenElse _ e1 e2 e3) =
+>   parenExp (p > 0)
+>            (text "if" <+>
+>             sep [ppExpr 0 e1,
+>                  text "then" <+> ppExpr 0 e2,
+>                  text "else" <+> ppExpr 0 e3])
+> ppExpr p (Case _ e alts) =
+>   parenExp (p > 0)
+>            (text "case" <+> ppExpr 0 e <+> text "of" $$
+>             indent (vcat (map ppAlt alts)))
+> ppExpr p (RecordConstr fs) =
+>   braces (list (map (ppFieldExpr equals) fs))
+> ppExpr p (RecordSelection e l) =
+>   parenExp (p > 0)
+>            (ppExpr 1 e <+> text "->" <+> ppIdent l)
+> ppExpr p (RecordUpdate fs e) =
+>   braces (list (map (ppFieldExpr (text ":=")) fs)
+>          <+> char '|' <+> ppExpr 0 e)
+
+> ppStmt :: Statement -> Doc
+> ppStmt (StmtExpr _ e) = ppExpr 0 e
+> ppStmt (StmtBind _ t e) = sep [ppConstrTerm 0 t <+> larrow,indent (ppExpr 0 e)]
+> ppStmt (StmtDecl ds) = text "let" <+> ppBlock ds
+
+> ppAlt :: Alt -> Doc
+> ppAlt (Alt _ t rhs) = ppRule (ppConstrTerm 0 t) rarrow rhs
+
+> ppFieldExpr :: Doc -> Field Expression -> Doc
+> ppFieldExpr comb (Field _ l e) = ppIdent l <> comb <> ppExpr 0 e
+
+> ppOp :: InfixOp -> Doc
+> ppOp (InfixOp op) = ppQInfixOp op
+> ppOp (InfixConstr op) = ppQInfixOp op
+
+\end{verbatim}
+
+Names
+\begin{verbatim}
+
+> ppIdent :: Ident -> Doc
+> ppIdent x = parenExp (isInfixOp x) (text (name x))
+
+> ppQIdent :: QualIdent -> Doc
+> ppQIdent x = parenExp (isQInfixOp x) (text (qualName x))
+
+> ppInfixOp :: Ident -> Doc
+> ppInfixOp x = backQuoteExp (not (isInfixOp x)) (text (name x))
+
+> ppQInfixOp :: QualIdent -> Doc
+> ppQInfixOp x = backQuoteExp (not (isQInfixOp x)) (text (qualName x))
+
+> ppMIdent :: ModuleIdent -> Doc
+> ppMIdent m = text (moduleName m)
+
+\end{verbatim}
+Print printing utilities
+\begin{verbatim}
+
+> indent :: Doc -> Doc
+> indent = nest 2
+
+> maybePP :: (a -> Doc) -> Maybe a -> Doc
+> maybePP pp = maybe empty pp
+
+> parenExp :: Bool -> Doc -> Doc
+> parenExp b doc = if b then parens doc else doc
+
+> backQuoteExp :: Bool -> Doc -> Doc
+> backQuoteExp b doc = if b then backQuote <> doc <> backQuote else doc
+
+> list, parenList, bracketList, braceList :: [Doc] -> Doc
+> list = fsep . punctuate comma
+> parenList = parens . list
+> bracketList = brackets . list
+> braceList = braces . list
+
+> backQuote,backsl,vbar,rarrow,larrow :: Doc
+> backQuote = char '`'
+> backsl = char '\\'
+> vbar = char '|'
+> rarrow = text "->"
+> larrow = text "<-"
+
+\end{verbatim}
diff --git a/src/Curry/Syntax/ShowModule.hs b/src/Curry/Syntax/ShowModule.hs
new file mode 100644
--- /dev/null
+++ b/src/Curry/Syntax/ShowModule.hs
@@ -0,0 +1,499 @@
+--- Transform a CurrySyntax module into a string representation without any
+--- pretty printing.
+--- Behaves like a derived Show instance even on parts with a specific one.
+--- 
+--- @author Sebastian Fischer (sebf@informatik.uni-kiel.de)
+--- @version December 2008
+--- bug fixed by bbr
+
+
+module Curry.Syntax.ShowModule ( showModule ) where
+
+import Curry.Base.Ident
+import Curry.Base.Position
+import Curry.Syntax.Type
+
+showModule :: Module -> String
+showModule m = showsModule m "\n"
+
+showsModule :: Module -> ShowS
+showsModule (Module mident espec decls)
+  = showsString "Module "
+  . showsModuleIdent mident . newline
+  . showsMaybe showsExportSpec espec . newline
+  . showsList (\d -> showsDecl d . newline) decls
+
+showsPosition :: Position -> ShowS
+showsPosition Position{line=row,column=col} = showsPair shows shows (row,col)
+-- showsPosition (Position file row col)
+--   = showsString "(Position "
+--   . shows file . space
+--   . shows row . space
+--   . shows col
+--   . showsString ")"
+
+showsExportSpec :: ExportSpec -> ShowS
+showsExportSpec (Exporting pos exports)
+  = showsString "(Exporting "
+  . showsPosition pos . space
+  . showsList showsExport exports
+  . showsString ")"
+
+showsExport :: Export -> ShowS
+showsExport (Export qident)
+  = showsString "(Export " . showsQualIdent qident . showsString ")"
+showsExport (ExportTypeWith qident ids)
+  = showsString "(ExportTypeWith "
+  . showsQualIdent qident . space
+  . showsList showsIdent ids
+  . showsString ")"
+showsExport (ExportTypeAll qident)
+  = showsString "(ExportTypeAll " . showsQualIdent qident . showsString ")"
+showsExport (ExportModule m) 
+  = showsString "(ExportModule " . showsModuleIdent m . showChar ')'
+
+showsImportSpec :: ImportSpec -> ShowS
+showsImportSpec (Importing pos imports)
+  = showsString "(Importing "
+  . showsPosition pos . space
+  . showsList showsImport imports
+  . showsString ")"
+showsImportSpec (Hiding pos imports)
+  = showsString "(Hiding "
+  . showsPosition pos . space
+  . showsList showsImport imports
+  . showsString ")"
+
+showsImport :: Import -> ShowS
+showsImport (Import ident)
+  = showsString "(Import " . showsIdent ident . showsString ")"
+showsImport (ImportTypeWith ident idents)
+  = showsString "(ImportTypeWith "
+  . showsIdent ident . space
+  . showsList showsIdent idents
+  . showsString ")"
+showsImport (ImportTypeAll ident)
+  = showsString "(ImportTypeAll " . showsIdent ident . showsString ")"
+
+showsDecl :: Decl -> ShowS
+showsDecl (ImportDecl pos mident quali mmident mimpspec)
+  = showsString "(ImportDecl "
+  . showsPosition pos . space
+  . showsModuleIdent mident . space
+  . shows quali . space
+  . showsMaybe showsModuleIdent mmident . space
+  . showsMaybe showsImportSpec mimpspec
+  . showsString ")"
+showsDecl (InfixDecl pos infx prec idents)
+  = showsString "(InfixDecl "
+  . showsPosition pos . space
+  . shows infx . space
+  . shows prec . space
+  . showsList showsIdent idents
+  . showsString ")"
+showsDecl (DataDecl pos ident idents consdecls)
+  = showsString "(DataDecl "
+  . showsPosition pos . space
+  . showsIdent ident . space
+  . showsList showsIdent idents . space
+  . showsList showsConsDecl consdecls
+  . showsString ")"
+showsDecl (NewtypeDecl pos ident idents newconsdecl)
+  = showsString "(NewtypeDecl "
+  . showsPosition pos . space
+  . showsIdent ident . space
+  . showsList showsIdent idents . space
+  . showsNewConsDecl newconsdecl
+  . showsString ")"
+showsDecl (TypeDecl pos ident idents typ)
+  = showsString "(TypeDecl "
+  . showsPosition pos . space
+  . showsIdent ident . space
+  . showsList showsIdent idents . space
+  . showsTypeExpr typ
+  . showsString ")"
+showsDecl (TypeSig pos idents typ)
+  = showsString "(TypeSig "
+  . showsPosition pos . space
+  . showsList showsIdent idents . space
+  . showsTypeExpr typ
+  . showsString ")"
+showsDecl (EvalAnnot pos idents annot)
+  = showsString "(EvalAnnot "
+  . showsPosition pos . space
+  . showsList showsIdent idents . space
+  . shows annot
+  . showsString ")"
+showsDecl (FunctionDecl pos ident eqs)
+  = showsString "(FunctionDecl "
+  . showsPosition pos . space
+  . showsIdent ident . space
+  . showsList showsEquation eqs
+  . showsString ")"
+showsDecl (ExternalDecl pos cconv mstr ident typ)
+  = showsString "(ExternalDecl "
+  . showsPosition pos . space
+  . shows cconv . space
+  . shows mstr . space
+  . showsIdent ident . space
+  . showsTypeExpr typ
+  . showsString ")"
+showsDecl (FlatExternalDecl pos idents)
+  = showsString "(FlatExternalDecl "
+  . showsPosition pos . space
+  . showsList showsIdent idents
+  . showsString ")"
+showsDecl (PatternDecl pos cons rhs)
+  = showsString "(PatternDecl "
+  . showsPosition pos . space
+  . showsConsTerm cons . space
+  . showsRhs rhs
+  . showsString ")"
+showsDecl (ExtraVariables pos idents)
+  = showsString "(ExtraVariables "
+  . showsPosition pos . space
+  . showsList showsIdent idents
+  . showsString ")"
+
+showsConsDecl :: ConstrDecl -> ShowS
+showsConsDecl (ConstrDecl pos idents ident types)
+  = showsString "(ConstrDecl "
+  . showsPosition pos . space
+  . showsList showsIdent idents . space
+  . showsIdent ident . space
+  . showsList showsTypeExpr types
+  . showsString ")"
+
+showsNewConsDecl :: NewConstrDecl -> ShowS
+showsNewConsDecl (NewConstrDecl pos idents ident typ)
+  = showsString "(NewConstrDecl "
+  . showsPosition pos . space
+  . showsList showsIdent idents . space
+  . showsIdent ident . space
+  . showsTypeExpr typ
+  . showsString ")"
+
+showsTypeExpr :: TypeExpr -> ShowS
+showsTypeExpr (ConstructorType qident types)
+  = showsString "(ConstructorType "
+  . showsQualIdent qident . space
+  . showsList showsTypeExpr types
+  . showsString ")"
+showsTypeExpr (VariableType ident)
+  = showsString "(VariableType " . showsIdent ident . showsString ")"
+showsTypeExpr (TupleType types)
+  = showsString "(TupleType " . showsList showsTypeExpr types . showsString ")"
+showsTypeExpr (ListType typ)
+  = showsString "(ListType " . showsTypeExpr typ . showsString ")"
+showsTypeExpr (ArrowType dom ran)
+  = showsString "(ArrowType "
+  . showsTypeExpr dom . space
+  . showsTypeExpr ran
+  . showsString ")"
+showsTypeExpr (RecordType fieldts mtyp)
+  = showsString "(RecordType "
+  . showsList (showsPair (showsList showsIdent) showsTypeExpr) fieldts . space
+  . showsMaybe showsTypeExpr mtyp
+  . showsString ")"
+
+showsEquation :: Equation -> ShowS
+showsEquation (Equation pos lhs rhs)
+  = showsString "(Equation "
+  . showsPosition pos . space
+  . showsLhs lhs . space
+  . showsRhs rhs
+  . showsString ")"
+
+showsLhs :: Lhs -> ShowS
+showsLhs (FunLhs ident conss)
+  = showsString "(FunLhs "
+  . showsIdent ident . space
+  . showsList showsConsTerm conss
+  . showsString ")"
+showsLhs (OpLhs cons1 ident cons2)
+  = showsString "(OpLhs "
+  . showsConsTerm cons1 . space
+  . showsIdent ident . space
+  . showsConsTerm cons2
+  . showsString ")"
+showsLhs (ApLhs lhs conss)
+  = showsString "(ApLhs "
+  . showsLhs lhs . space
+  . showsList showsConsTerm conss
+  . showsString ")"
+
+showsRhs :: Rhs -> ShowS
+showsRhs (SimpleRhs pos exp decls)
+  = showsString "(SimpleRhs "
+  . showsPosition pos . space
+  . showsExpression exp . space
+  . showsList showsDecl decls
+  . showsString ")"
+showsRhs (GuardedRhs cexps decls)
+  = showsString "(GuardedRhs "
+  . showsList showsCondExpr cexps . space
+  . showsList showsDecl decls
+  . showsString ")"
+
+showsCondExpr :: CondExpr -> ShowS
+showsCondExpr (CondExpr pos exp1 exp2)
+  = showsString "(CondExpr "
+  . showsPosition pos . space
+  . showsExpression exp1 . space
+  . showsExpression exp2
+  . showsString ")"
+
+showsLiteral :: Literal -> ShowS
+showsLiteral (Char _ c) = showsString "(Char " . shows c . showsString ")"
+showsLiteral (Int ident n)
+  = showsString "(Int "
+  . showsIdent ident . space
+  . shows n
+  . showsString ")"
+showsLiteral (Float _ x) = showsString "(Float " . shows x . showsString ")"
+showsLiteral (String _ s) = showsString "(String " . shows s . showsString ")"
+
+showsConsTerm :: ConstrTerm -> ShowS
+showsConsTerm (LiteralPattern lit)
+  = showsString "(LiteralPattern "
+  . showsLiteral lit
+  . showsString ")"
+showsConsTerm (NegativePattern ident lit)
+  = showsString "(NegativePattern "
+  . showsIdent ident . space
+  . showsLiteral lit
+  . showsString ")"
+showsConsTerm (VariablePattern ident)
+  = showsString "(VariablePattern "
+  . showsIdent ident 
+  . showsString ")"
+showsConsTerm (ConstructorPattern qident conss)
+  = showsString "(ConstructorPattern "
+  . showsQualIdent qident . space
+  . showsList showsConsTerm conss
+  . showsString ")"
+showsConsTerm (InfixPattern cons1 qident cons2)
+  = showsString "(InfixPattern "
+  . showsConsTerm cons1 . space
+  . showsQualIdent qident . space
+  . showsConsTerm cons2
+  . showsString ")"
+showsConsTerm (ParenPattern cons)
+  = showsString "(ParenPattern "
+  . showsConsTerm cons
+  . showsString ")"
+showsConsTerm (TuplePattern _ conss)
+  = showsString "(TuplePattern "
+  . showsList showsConsTerm conss
+  . showsString ")"
+showsConsTerm (ListPattern _ conss)
+  = showsString "(ListPattern "
+  . showsList showsConsTerm conss
+  . showsString ")"
+showsConsTerm (AsPattern ident cons)
+  = showsString "(AsPattern "
+  . showsIdent ident . space
+  . showsConsTerm cons
+  . showsString ")"
+showsConsTerm (LazyPattern _ cons)
+  = showsString "(LazyPattern "
+  . showsConsTerm cons
+  . showsString ")"
+showsConsTerm (FunctionPattern qident conss)
+  = showsString "(FunctionPattern "
+  . showsQualIdent qident . space
+  . showsList showsConsTerm conss
+  . showsString ")"
+showsConsTerm (InfixFuncPattern cons1 qident cons2)
+  = showsString "(InfixFuncPattern "
+  . showsConsTerm cons1 . space
+  . showsQualIdent qident . space
+  . showsConsTerm cons2
+  . showsString ")"
+showsConsTerm (RecordPattern cfields mcons)
+  = shows "(RecordPattern "
+  . showsList (showsField showsConsTerm) cfields . space
+  . showsMaybe showsConsTerm mcons
+  . showsString ")"
+
+showsExpression :: Expression -> ShowS
+showsExpression (Literal lit)
+  = showsString "(Literal " . showsLiteral lit . showsString ")"
+showsExpression (Variable qident)
+  = showsString "(Variable " . showsQualIdent qident . showsString ")"
+showsExpression (Constructor qident)
+  = showsString "(Constructor " . showsQualIdent qident . showsString ")"
+showsExpression (Paren exp)
+  = showsString "(Paren " . showsExpression exp . showsString ")"
+showsExpression (Typed exp typ)
+  = showsString "(Typed "
+  . showsExpression exp . space
+  . showsTypeExpr typ
+  . showsString ")"
+showsExpression (Tuple _ exps)
+  = showsString "(Tuple " . showsList showsExpression exps . showsString ")"
+showsExpression (List _ exps)
+  = showsString "(List " . showsList showsExpression exps . showsString ")"
+showsExpression (ListCompr _ exp stmts)
+  = showsString "(ListCompr "
+  . showsExpression exp . space
+  . showsList showsStatement stmts
+  . showsString ")"
+showsExpression (EnumFrom exp)
+  = showsString "(EnumFrom " . showsExpression exp . showsString ")"
+showsExpression (EnumFromThen exp1 exp2)
+  = showsString "(EnumFromThen "
+  . showsExpression exp1 . space
+  . showsExpression exp2
+  . showsString ")"
+showsExpression (EnumFromTo exp1 exp2)
+  = showsString "(EnumFromTo "
+  . showsExpression exp1 . space
+  . showsExpression exp2
+  . showsString ")"
+showsExpression (EnumFromThenTo exp1 exp2 exp3)
+  = showsString "(EnumFromThenTo "
+  . showsExpression exp1 . space
+  . showsExpression exp2 . space
+  . showsExpression exp3
+  . showsString ")"
+showsExpression (UnaryMinus ident exp)
+  = showsString "(UnaryMinus "
+  . showsIdent ident . space
+  . showsExpression exp
+  . showsString ")"
+showsExpression (Apply exp1 exp2)
+  = showsString "(Apply "
+  . showsExpression exp1 . space
+  . showsExpression exp2
+  . showsString ")"
+showsExpression (InfixApply exp1 op exp2)
+  = showsString "(InfixApply "
+  . showsExpression exp1 . space
+  . showsInfixOp op . space
+  . showsExpression exp2
+  . showsString ")"
+showsExpression (LeftSection exp op)
+  = showsString "(LeftSection "
+  . showsExpression exp . space
+  . showsInfixOp op
+  . showsString ")"
+showsExpression (RightSection op exp)
+  = showsString "(RightSection "
+  . showsInfixOp op . space
+  . showsExpression exp
+  . showsString ")"
+showsExpression (Lambda _ conss exp)
+  = showsString "(Lambda "
+  . showsList showsConsTerm conss . space
+  . showsExpression exp 
+  . showsString ")"
+showsExpression (Let decls exp)
+  = showsString "(Let "
+  . showsList showsDecl decls . space
+  . showsExpression exp 
+  . showsString ")"
+showsExpression (Do stmts exp)
+  = showsString "(Do "
+  . showsList showsStatement stmts . space
+  . showsExpression exp
+  . showsString ")"
+showsExpression (IfThenElse _ exp1 exp2 exp3)
+  = showsString "(IfThenElse "
+  . showsExpression exp1 . space
+  . showsExpression exp2 . space
+  . showsExpression exp3
+  . showsString ")"
+showsExpression (Case _ exp alts)
+  = showsString "(Case "
+  . showsExpression exp . space
+  . showsList showsAlt alts
+  . showsString ")"
+showsExpression (RecordConstr efields)
+  = showsString "(RecordConstr "
+  . showsList (showsField showsExpression) efields
+  . showsString ")"
+showsExpression (RecordSelection exp ident)
+  = showsString "(RecordSelection "
+  . showsExpression exp . space
+  . showsIdent ident
+  . showsString ")"
+showsExpression (RecordUpdate efields exp)
+  = showsString "(RecordUpdate "
+  . showsList (showsField showsExpression) efields . space
+  . showsExpression exp
+  . showsString ")"
+
+showsInfixOp :: InfixOp -> ShowS
+showsInfixOp (InfixOp qident)
+  = showsString "(InfixOp " . showsQualIdent qident . showsString ")"
+showsInfixOp (InfixConstr qident)
+  = showsString "(InfixConstr " . showsQualIdent qident . showsString ")"
+
+showsStatement :: Statement -> ShowS
+showsStatement (StmtExpr _ exp)
+  = showsString "(StmtExpr " . showsExpression exp . showsString ")"
+showsStatement (StmtDecl decls)
+  = showsString "(StmtDecl " . showsList showsDecl decls . showsString ")"
+showsStatement (StmtBind _ cons exp)
+  = showsString "(StmtBind "
+  . showsConsTerm cons . space
+  . showsExpression exp
+  . showsString ")"
+
+showsAlt :: Alt -> ShowS
+showsAlt (Alt pos cons rhs)
+  = showsString "(Alt "
+  . showsPosition pos . space
+  . showsConsTerm cons . space
+  . showsRhs rhs
+  . showsString ")"
+
+showsField :: (a -> ShowS) -> Field a -> ShowS
+showsField sa (Field pos ident a)
+  = showsString "(Field "
+  . showsPosition pos . space
+  . showsIdent ident . space
+  . sa a
+  . showsString ")"
+
+showsString :: String -> ShowS
+showsString = (++)
+
+space :: ShowS
+space = showsString " "
+
+newline :: ShowS
+newline = showsString "\n"
+
+showsMaybe :: (a -> ShowS) -> Maybe a -> ShowS
+showsMaybe shs
+  = maybe (showsString "Nothing")
+          (\x -> showsString "(Just " . shs x . showsString ")")
+
+showsList :: (a -> ShowS) -> [a] -> ShowS
+showsList _ [] = showsString "[]"
+showsList shs (x:xs)
+  = showsString "["
+  . foldl (\sys y -> sys . showsString "," . shs y) (shs x) xs
+  . showsString "]"
+
+showsPair :: (a -> ShowS) -> (b -> ShowS) -> (a,b) -> ShowS
+showsPair sa sb (a,b)
+  = showsString "(" . sa a . showsString "," . sb b . showsString ")"
+
+
+showsIdent :: Ident -> ShowS
+showsIdent (Ident _ name n)
+  = showsString "(Ident " . shows name . space . shows n . showsString ")"
+
+showsQualIdent :: QualIdent -> ShowS
+showsQualIdent (QualIdent mident ident)
+    = showsString "(QualIdent "
+      . showsMaybe showsModuleIdent mident 
+      . space
+      . showsIdent ident
+      . showsString ")"
+
+showsModuleIdent :: ModuleIdent -> ShowS
+showsModuleIdent = shows . moduleName
diff --git a/src/Curry/Syntax/Type.lhs b/src/Curry/Syntax/Type.lhs
new file mode 100644
--- /dev/null
+++ b/src/Curry/Syntax/Type.lhs
@@ -0,0 +1,315 @@
+> {-# LANGUAGE DeriveDataTypeable #-}
+
+% $Id: CurrySyntax.lhs,v 1.43 2004/02/15 22:10:31 wlux Exp $
+%
+% Copyright (c) 1999-2004, Wolfgang Lux
+% See LICENSE for the full license.
+%
+% Modified by Martin Engelke (men@informatik.uni-kiel.de)
+%
+\nwfilename{CurrySyntax.lhs}
+\section{The Parse Tree}
+This module provides the necessary data structures to maintain the
+parsed representation of a Curry program.
+
+\em{Note:} this modified version uses haskell type \texttt{Integer}
+instead of \texttt{Int} for representing integer values. This allows
+an unlimited range of integer constants in Curry programs.
+\begin{verbatim}
+
+> module Curry.Syntax.Type where
+
+> import Curry.Base.Ident
+> import Curry.Base.Position
+> import Data.Generics
+> import Control.Monad.State
+
+\end{verbatim}
+\paragraph{Modules}
+\begin{verbatim}
+
+> data Module = Module ModuleIdent (Maybe ExportSpec) [Decl] 
+>  deriving (Eq,Show,Read,Typeable,Data)
+
+> data ExportSpec = Exporting Position [Export] deriving (Eq,Show,Read,Typeable,Data)
+> data Export =
+>     Export         QualIdent                  -- f/T
+>   | ExportTypeWith QualIdent [Ident]          -- T(C1,...,Cn)
+>   | ExportTypeAll  QualIdent                  -- T(..)
+>   | ExportModule   ModuleIdent
+>   deriving (Eq,Show,Read,Typeable,Data)
+
+\end{verbatim}
+\paragraph{Module declarations}
+\begin{verbatim}
+
+> data ImportSpec =
+>     Importing Position [Import]
+>   | Hiding Position [Import]
+>   deriving (Eq,Show,Read,Typeable,Data)
+> data Import =
+>     Import         Ident            -- f/T
+>   | ImportTypeWith Ident [Ident]    -- T(C1,...,Cn)
+>   | ImportTypeAll  Ident            -- T(..)
+>   deriving (Eq,Show,Read,Typeable,Data)
+
+> data Decl =
+>     ImportDecl Position ModuleIdent Qualified (Maybe ModuleIdent)
+>                (Maybe ImportSpec)
+>   | InfixDecl Position Infix Integer [Ident]
+>   | DataDecl Position Ident [Ident] [ConstrDecl]
+>   | NewtypeDecl Position Ident [Ident] NewConstrDecl
+>   | TypeDecl Position Ident [Ident] TypeExpr
+>   | TypeSig Position [Ident] TypeExpr
+>   | EvalAnnot Position [Ident] EvalAnnotation
+>   | FunctionDecl Position Ident [Equation]
+>   | ExternalDecl Position CallConv (Maybe String) Ident TypeExpr
+>   | FlatExternalDecl Position [Ident]
+>   | PatternDecl Position ConstrTerm Rhs
+>   | ExtraVariables Position [Ident]
+>   deriving (Eq,Show,Read,Typeable,Data)
+
+> data ConstrDecl =
+>     ConstrDecl Position [Ident] Ident [TypeExpr]
+>   | ConOpDecl Position [Ident] TypeExpr Ident TypeExpr
+>   deriving (Eq,Show,Read,Typeable,Data)
+> data NewConstrDecl =
+>   NewConstrDecl Position [Ident] Ident TypeExpr
+>   deriving (Eq,Show,Read,Typeable,Data)
+
+> type Qualified = Bool
+> data Infix = InfixL | InfixR | Infix deriving (Eq,Show,Read,Typeable,Data)
+> data EvalAnnotation = EvalRigid | EvalChoice deriving (Eq,Show,Read,Typeable,Data)
+> data CallConv = CallConvPrimitive | CallConvCCall deriving (Eq,Show,Read,Typeable,Data)
+
+\end{verbatim}
+\paragraph{Module interfaces}
+Interface declarations are restricted to type declarations and signatures. 
+Note that an interface function declaration additionaly contains the 
+function arity (= number of parameters) in order to generate
+correct FlatCurry function applications.
+\begin{verbatim}
+
+> data Interface = Interface ModuleIdent [IDecl] deriving (Eq,Show,Read,Typeable,Data)
+
+> data IDecl =
+>     IImportDecl Position ModuleIdent
+>   | IInfixDecl Position Infix Integer QualIdent
+>   | HidingDataDecl Position Ident [Ident] 
+>   | IDataDecl Position QualIdent [Ident] [Maybe ConstrDecl]
+>   | INewtypeDecl Position QualIdent [Ident] NewConstrDecl
+>   | ITypeDecl Position QualIdent [Ident] TypeExpr
+>   | IFunctionDecl Position QualIdent Int TypeExpr
+>   deriving (Eq,Show,Read,Typeable,Data)
+
+\end{verbatim}
+\paragraph{Types}
+\begin{verbatim}
+
+> data TypeExpr =
+>     ConstructorType QualIdent [TypeExpr]
+>   | VariableType Ident
+>   | TupleType [TypeExpr]
+>   | ListType TypeExpr
+>   | ArrowType TypeExpr TypeExpr
+>   | RecordType [([Ident],TypeExpr)] (Maybe TypeExpr) 
+>     -- {l1 :: t1,...,ln :: tn | r}
+>   deriving (Eq,Show,Read,Typeable,Data)
+
+\end{verbatim}
+\paragraph{Functions}
+\begin{verbatim}
+
+> data Equation = Equation Position Lhs Rhs deriving (Eq,Show,Read,Typeable,Data)
+> data Lhs =
+>     FunLhs Ident [ConstrTerm]
+>   | OpLhs ConstrTerm Ident ConstrTerm
+>   | ApLhs Lhs [ConstrTerm]
+>   deriving (Eq,Show,Read,Typeable,Data)
+> data Rhs =
+>     SimpleRhs Position Expression [Decl]
+>   | GuardedRhs [CondExpr] [Decl]
+>   deriving (Eq,Show,Read,Typeable,Data)
+> data CondExpr = CondExpr Position Expression Expression deriving (Eq,Show,Read,Typeable,Data)
+
+> flatLhs :: Lhs -> (Ident,[ConstrTerm])
+> flatLhs lhs = flat lhs []
+>   where flat (FunLhs f ts) ts' = (f,ts ++ ts')
+>         flat (OpLhs t1 op t2) ts = (op,t1:t2:ts)
+>         flat (ApLhs lhs ts) ts' = flat lhs (ts ++ ts')
+
+\end{verbatim}
+\paragraph{Literals} The \texttt{Ident} argument of an \texttt{Int}
+literal is used for supporting ad-hoc polymorphism on integer
+numbers. An integer literal can be used either as an integer number or
+as a floating-point number depending on its context. The compiler uses
+the identifier of the \texttt{Int} literal for maintaining its type.
+\begin{verbatim}
+
+> data Literal =
+>     Char SrcRef Char                         -- should be Int to handle Unicode
+>   | Int Ident Integer
+>   | Float SrcRef Double
+>   | String SrcRef String                     -- should be [Int] to handle Unicode
+>   deriving (Eq,Show,Read,Typeable,Data)
+
+> mk' :: ([SrcRef] -> a) -> a
+> mk' = ($[])
+
+> mk :: (SrcRef -> a) -> a
+> mk = ($noRef)
+
+> mkInt :: Integer -> Literal
+> mkInt i = mk (\r -> Int (addPositionIdent (AST  r) anonId) i) 
+
+\end{verbatim}
+\paragraph{Patterns}
+\begin{verbatim}
+
+> data ConstrTerm =
+>     LiteralPattern Literal
+>   | NegativePattern Ident Literal
+>   | VariablePattern Ident
+>   | ConstructorPattern QualIdent [ConstrTerm]
+>   | InfixPattern ConstrTerm QualIdent ConstrTerm
+>   | ParenPattern ConstrTerm
+>   | TuplePattern SrcRef [ConstrTerm]
+>   | ListPattern [SrcRef] [ConstrTerm]
+>   | AsPattern Ident ConstrTerm
+>   | LazyPattern SrcRef ConstrTerm
+>   | FunctionPattern QualIdent [ConstrTerm]
+>   | InfixFuncPattern ConstrTerm QualIdent ConstrTerm
+>   | RecordPattern [Field ConstrTerm] (Maybe ConstrTerm)  
+>         -- {l1 = p1, ..., ln = pn}  oder {l1 = p1, ..., ln = pn | p}
+>   deriving (Eq,Show,Read,Typeable,Data)
+
+\end{verbatim}
+\paragraph{Expressions}
+\begin{verbatim}
+
+> data Expression =
+>     Literal Literal
+>   | Variable QualIdent
+>   | Constructor QualIdent
+>   | Paren Expression
+>   | Typed Expression TypeExpr
+>   | Tuple SrcRef [Expression]
+>   | List [SrcRef] [Expression]
+>   | ListCompr SrcRef Expression [Statement] -- the ref corresponds to the main list  
+>   | EnumFrom Expression
+>   | EnumFromThen Expression Expression
+>   | EnumFromTo Expression Expression
+>   | EnumFromThenTo Expression Expression Expression
+>   | UnaryMinus Ident Expression
+>   | Apply Expression Expression
+>   | InfixApply Expression InfixOp Expression
+>   | LeftSection Expression InfixOp
+>   | RightSection InfixOp Expression
+>   | Lambda SrcRef [ConstrTerm] Expression
+>   | Let [Decl] Expression
+>   | Do [Statement] Expression
+>   | IfThenElse SrcRef Expression Expression Expression
+>   | Case SrcRef Expression [Alt]
+>   | RecordConstr [Field Expression]            -- {l1 = e1,...,ln = en}
+>   | RecordSelection Expression Ident           -- e -> l
+>   | RecordUpdate [Field Expression] Expression -- {l1 := e1,...,ln := en | e}
+>   deriving (Eq,Show,Read,Typeable,Data)
+
+> data InfixOp = InfixOp QualIdent | InfixConstr QualIdent deriving (Eq,Show,Read,Typeable,Data)
+
+> data Statement =
+>     StmtExpr SrcRef Expression
+>   | StmtDecl [Decl]
+>   | StmtBind SrcRef ConstrTerm Expression
+>   deriving (Eq,Show,Read,Typeable,Data)
+
+> data Alt = Alt Position ConstrTerm Rhs deriving (Eq,Show,Read,Typeable,Data)
+
+> data Field a = Field Position Ident a deriving (Eq, Show,Read,Typeable,Data)
+
+> fieldLabel :: Field a -> Ident
+> fieldLabel (Field _ l _) = l
+
+> fieldTerm :: Field a -> a
+> fieldTerm (Field _ _ t) = t
+
+> field2Tuple :: Field a -> (Ident,a)
+> field2Tuple (Field _ l t) = (l,t)
+
+> opName :: InfixOp -> QualIdent
+> opName (InfixOp op) = op
+> opName (InfixConstr c) = c
+
+\end{verbatim}
+
+> instance SrcRefOf ConstrTerm where
+>   srcRefOf (LiteralPattern l) = srcRefOf l
+>   srcRefOf (NegativePattern i _) = srcRefOf i
+>   srcRefOf (VariablePattern i) = srcRefOf i
+>   srcRefOf (ConstructorPattern i _) = srcRefOf i
+>   srcRefOf (InfixPattern _ i _) = srcRefOf i
+>   srcRefOf (ParenPattern c) = srcRefOf c
+>   srcRefOf (TuplePattern s _) = s
+>   srcRefOf (ListPattern s _) = error "list pattern has several source refs"
+>   srcRefOf (AsPattern i _) = srcRefOf i
+>   srcRefOf (LazyPattern s _) = s
+>   srcRefOf (FunctionPattern i _) = srcRefOf i
+>   srcRefOf (InfixFuncPattern _ i _) = srcRefOf i
+
+> instance SrcRefOf Literal where
+>   srcRefOf (Char s _)   = s
+>   srcRefOf (Int i _)    = srcRefOf i
+>   srcRefOf (Float s _)  = s
+>   srcRefOf (String s _) = s
+
+---------------------------
+-- add source references
+---------------------------
+
+> type M a = a -> State Int a
+> 
+> addSrcRefs :: Module -> Module
+> addSrcRefs x = evalState (addRef x) 0
+>   where 
+>     addRef :: Data a' => M a' 
+>     addRef = down `extM` addRefPos   
+>                   `extM` addRefSrc   
+>                   `extM` addRefIdent
+>                   `extM` addRefListPat
+>                   `extM` addRefListExp
+>       where
+>         down :: Data a' => M a'
+>         down = gmapM addRef
+> 
+>         addRefPos :: M [SrcRef]
+>         addRefPos _ = liftM (:[]) next
+> 
+>         addRefSrc :: M SrcRef
+>         addRefSrc _ = next
+> 
+>         addRefIdent :: M Ident
+>         addRefIdent ident = liftM (flip addRefId ident) next
+>
+>         addRefListPat :: M ConstrTerm
+>         addRefListPat (ListPattern _ ts) = do
+>           liftM (uncurry ListPattern) (addRefList ts)
+>         addRefListPat ct = gmapM addRef ct
+>   
+>         addRefListExp :: M Expression
+>         addRefListExp (List _ ts) = do
+>           liftM (uncurry List) (addRefList ts)
+>         addRefListExp ct = gmapM addRef ct
+>   
+>         addRefList :: Data a' => [a'] -> State Int ([SrcRef],[a'])
+>         addRefList ts = do
+>           i <- next
+>           let add t = do t' <- addRef t;j <- next; return (j,t')
+>           ists <- sequence (map add ts)
+>           let (is,ts') = unzip ists
+>           return (i:is,ts')
+>         
+>         next :: State Int SrcRef
+>         next = do
+>           i <- get
+>           put $! i+1
+>           return (SrcRef [i])
diff --git a/src/Curry/Syntax/Unlit.hs b/src/Curry/Syntax/Unlit.hs
new file mode 100644
--- /dev/null
+++ b/src/Curry/Syntax/Unlit.hs
@@ -0,0 +1,57 @@
+{-
+  Since version 0.7 of the language report, Curry accepts literate
+  source programs. In a literate source all program lines must begin
+  with a greater sign in the first column. All other lines are assumed
+  to be documentation. In order to avoid some common errors with
+  literate programs, Curry requires at least one program line to be
+  present in the file. In addition, every block of program code must be
+  preceded by a blank line and followed by a blank line.
+-}
+
+
+module Curry.Syntax.Unlit(unlit) where
+
+import Control.Monad(when, zipWithM)
+import Data.Char
+
+import Curry.Base.Position
+import Curry.Base.MessageMonad
+
+
+data Line = Program !Int String
+          | Blank | Comment
+
+classify :: Int -> String -> Line
+classify l ('>':cs)  = Program l cs
+classify _ cs
+  | all isSpace cs = Blank
+  | otherwise      = Comment
+
+{-
+  Process a literate program into error messages (if any) and the
+  corresponding non-literate program.
+-}
+
+unlit :: FilePath -> String -> MsgMonad String
+unlit fn lcy = do ls <- progLines fn (zipWith classify [1..] $ lines lcy)
+                  when (all null ls) $
+                       failWith (fn ++ ": no code in literate script")
+                  return (unlines ls)
+
+{-
+  Check that each program line is not adjacent to a comment line and
+  there is at least one program line.
+-}
+progLines :: FilePath -> [Line] -> MsgMonad [String]
+progLines fn cs 
+   = zipWithM adjacent (Blank : cs) cs
+  where
+    adjacent :: Line -> Line -> MsgMonad String
+    adjacent (Program p _) Comment     = message fn p "followed"
+    adjacent Comment     (Program p _) = message fn p "preceded"
+    adjacent _ (Program _ s)           = return s
+    adjacent _ _                       = return ""
+
+message :: String -> Int -> String -> MsgMonad a
+message file p w = failWithAt (Position file p 1 noRef) msg
+    where msg = "When reading literate source: Program line is " ++ w ++ " by comment line."
diff --git a/src/Curry/Syntax/Utils.hs b/src/Curry/Syntax/Utils.hs
new file mode 100644
--- /dev/null
+++ b/src/Curry/Syntax/Utils.hs
@@ -0,0 +1,202 @@
+module Curry.Syntax.Utils(Expr, fv, qfv,
+                          QuantExpr, bv) where
+
+import qualified Data.Set as Set
+
+import Curry.Base.Ident 
+import Curry.Syntax.Type
+
+{-
+  Free and bound variables
+  
+  The compiler needs to compute the sets of free and bound variables for
+  various different entities. We will devote three type classes to that
+  purpose. The \texttt{QualExpr} class is expected to take into account
+  that it is possible to use a qualified name to refer to a function
+  defined in the current module and therefore \emph{M.x} and $x$, where
+  $M$ is the current module name, should be considered the same name.
+  However note that this is correct only after renaming all local
+  definitions as \emph{M.x} always denotes an entity defined at the
+  top-level.
+  
+  The \texttt{Decl} instance of \texttt{QualExpr} returns all free
+  variables on the right hand side, regardless of whether they are bound
+  on the left hand side. This is more convenient as declarations are
+  usually processed in a declaration group where the set of free
+  variables cannot be computed independently for each declaration. Also
+  note that the operator in a unary minus expression is not a free
+  variable. This operator always refers to a global function from the
+  prelude.
+-}
+
+class Expr e where
+  fv :: e -> [Ident]
+class QualExpr e where
+  qfv :: ModuleIdent -> e -> [Ident]
+class QuantExpr e where
+  bv :: e -> [Ident]
+
+instance Expr e => Expr [e] where
+  fv = concat . map fv
+instance QualExpr e => QualExpr [e] where
+  qfv m = concat . map (qfv m)
+instance QuantExpr e => QuantExpr [e] where
+  bv = concat . map bv
+
+instance QualExpr Decl where
+  qfv m (FunctionDecl _ _ eqs) = qfv m eqs
+  qfv m (PatternDecl _ _ rhs) = qfv m rhs
+  qfv _ _ = []
+
+instance QuantExpr Decl where
+  bv (TypeSig _ vs _) = vs
+  bv (EvalAnnot _ fs _) = fs
+  bv (FunctionDecl _ f _) = [f]
+  bv (ExternalDecl _ _ _ f _) = [f]
+  bv (FlatExternalDecl _ fs) = fs
+  bv (PatternDecl _ t _) = bv t
+  bv (ExtraVariables _ vs) = vs
+  bv _ = []
+
+instance QualExpr Equation where
+  qfv m (Equation _ lhs rhs) = filterBv lhs (qfv m lhs ++ qfv m rhs)
+
+instance QuantExpr Lhs where
+  bv = bv . snd . flatLhs
+
+instance QualExpr Lhs where
+  qfv m lhs = qfv m (snd (flatLhs lhs))
+
+instance QualExpr Rhs where
+  qfv m (SimpleRhs _ e ds) = filterBv ds (qfv m e ++ qfv m ds)
+  qfv m (GuardedRhs es ds) = filterBv ds (qfv m es ++ qfv m ds)
+
+instance QualExpr CondExpr where
+  qfv m (CondExpr _ g e) = qfv m g ++ qfv m e
+
+instance QualExpr Expression where
+  qfv _ (Literal _) = []
+  qfv m (Variable v) = maybe [] return (localIdent m v)
+  qfv _ (Constructor _) = []
+  qfv m (Paren e) = qfv m e
+  qfv m (Typed e _) = qfv m e
+  qfv m (Tuple _ es) = qfv m es
+  qfv m (List _ es) = qfv m es
+  qfv m (ListCompr _ e qs) = foldr (qfvStmt m) (qfv m e) qs
+  qfv m (EnumFrom e) = qfv m e
+  qfv m (EnumFromThen e1 e2) = qfv m e1 ++ qfv m e2
+  qfv m (EnumFromTo e1 e2) = qfv m e1 ++ qfv m e2
+  qfv m (EnumFromThenTo e1 e2 e3) = qfv m e1 ++ qfv m e2 ++ qfv m e3
+  qfv m (UnaryMinus _ e) = qfv m e
+  qfv m (Apply e1 e2) = qfv m e1 ++ qfv m e2
+  qfv m (InfixApply e1 op e2) = qfv m op ++ qfv m e1 ++ qfv m e2
+  qfv m (LeftSection e op) = qfv m op ++ qfv m e
+  qfv m (RightSection op e) = qfv m op ++ qfv m e
+  qfv m (Lambda _ ts e) = filterBv ts (qfv m e)
+  qfv m (Let ds e) = filterBv ds (qfv m ds ++ qfv m e)
+  qfv m (Do sts e) = foldr (qfvStmt m) (qfv m e) sts
+  qfv m (IfThenElse _ e1 e2 e3) = qfv m e1 ++ qfv m e2 ++ qfv m e3
+  qfv m (Case _ e alts) = qfv m e ++ qfv m alts
+  qfv m (RecordConstr fs) = qfv m fs
+  qfv m (RecordSelection e _) = qfv m e
+  qfv m (RecordUpdate fs e) = qfv m e ++ qfv m fs
+
+qfvStmt :: ModuleIdent -> Statement -> [Ident] -> [Ident]
+qfvStmt m st fvs = qfv m st ++ filterBv st fvs
+
+instance QualExpr Statement where
+  qfv m (StmtExpr _ e) = qfv m e
+  qfv m (StmtDecl ds) = filterBv ds (qfv m ds)
+  qfv m (StmtBind _ t e) = qfv m e
+
+instance QualExpr Alt where
+  qfv m (Alt _ t rhs) = filterBv t (qfv m rhs)
+
+instance QuantExpr a => QuantExpr (Field a) where
+  bv (Field _ _ t) = bv t
+
+instance QualExpr a => QualExpr (Field a) where
+  qfv m (Field _ _ t) = qfv m t
+
+instance QuantExpr Statement where
+  bv (StmtExpr _ e) = []
+  bv (StmtBind _ t e) = bv t
+  bv (StmtDecl ds) = bv ds
+
+instance QualExpr InfixOp where
+  qfv m (InfixOp op) = qfv m (Variable op)
+  qfv _ (InfixConstr _) = []
+
+instance QuantExpr ConstrTerm where
+  bv (LiteralPattern _) = []
+  bv (NegativePattern _ _) = []
+  bv (VariablePattern v) = [v]
+  bv (ConstructorPattern c ts) = bv ts
+  bv (InfixPattern t1 op t2) = bv t1 ++ bv t2
+  bv (ParenPattern t) = bv t
+  bv (TuplePattern _ ts) = bv ts
+  bv (ListPattern _ ts) = bv ts
+  bv (AsPattern v t) = v : bv t
+  bv (LazyPattern _ t) = bv t
+  bv (FunctionPattern f ts) = bvFuncPatt (FunctionPattern f ts)
+  bv (InfixFuncPattern t1 op t2) = bvFuncPatt (InfixFuncPattern t1 op t2)
+  bv (RecordPattern fs r) = (maybe [] bv r) ++ bv fs
+
+instance QualExpr ConstrTerm where
+  qfv _ (LiteralPattern _) = []
+  qfv _ (NegativePattern _ _) = []
+  qfv _ (VariablePattern _) = []
+  qfv m (ConstructorPattern _ ts) = qfv m ts
+  qfv m (InfixPattern t1 _ t2) = qfv m [t1,t2]
+  qfv m (ParenPattern t) = qfv m t
+  qfv m (TuplePattern _ ts) = qfv m ts
+  qfv m (ListPattern _ ts) = qfv m ts
+  qfv m (AsPattern _ ts) = qfv m ts
+  qfv m (LazyPattern _ t) = qfv m t
+  qfv m (FunctionPattern f ts) 
+    = (maybe [] return (localIdent m f)) ++ qfv m ts
+  qfv m (InfixFuncPattern t1 op t2) 
+    = (maybe [] return (localIdent m op)) ++ qfv m [t1,t2]
+  qfv m (RecordPattern fs r) = (maybe [] (qfv m) r) ++ qfv m fs
+
+instance Expr TypeExpr where
+  fv (ConstructorType _ tys) = fv tys
+  fv (VariableType tv)
+    | tv == anonId = []
+    | otherwise = [tv]
+  fv (TupleType tys) = fv tys
+  fv (ListType ty) = fv ty
+  fv (ArrowType ty1 ty2) = fv ty1 ++ fv ty2
+  fv (RecordType fs rty) = (maybe [] fv rty) ++ fv (map snd fs)
+
+filterBv :: QuantExpr e => e -> [Ident] -> [Ident]
+filterBv e = filter (`Set.notMember` Set.fromList (bv e))
+
+{-
+  Since multiple variable occurrences are allowed in function patterns,
+  it is necessary to compute the list of bound variables in a different way:
+  Each variable occuring in the function pattern will be unique in the result
+  list.
+ -}
+
+bvFuncPatt :: ConstrTerm -> [Ident]
+bvFuncPatt = bvfp []
+ where
+ bvfp bvs (LiteralPattern _) = bvs
+ bvfp bvs (NegativePattern _ _) = bvs
+ bvfp bvs (VariablePattern v)
+    | elem v bvs = bvs
+    | otherwise  = v:bvs
+ bvfp bvs (ConstructorPattern c ts) = foldl bvfp bvs ts
+ bvfp bvs (InfixPattern t1 op t2) = foldl bvfp bvs [t1,t2]
+ bvfp bvs (ParenPattern t) = bvfp bvs t
+ bvfp bvs (TuplePattern _ ts) = foldl bvfp bvs ts
+ bvfp bvs (ListPattern _ ts) = foldl bvfp bvs ts
+ bvfp bvs (AsPattern v t)
+    | elem v bvs = bvfp bvs t
+    | otherwise  = bvfp (v:bvs) t
+ bvfp bvs (LazyPattern _ t) = bvfp bvs t
+ bvfp bvs (FunctionPattern f ts) = foldl bvfp bvs ts
+ bvfp bvs (InfixFuncPattern t1 op t2) = foldl bvfp bvs [t1, t2]
+ bvfp bvs (RecordPattern fs r)
+    = foldl bvfp (maybe bvs (bvfp bvs) r) (map fieldTerm fs)
diff --git a/src/CurryBuilder.hs b/src/CurryBuilder.hs
--- a/src/CurryBuilder.hs
+++ b/src/CurryBuilder.hs
@@ -13,16 +13,18 @@
 import System.Exit
 import System.Time
 import Control.Monad
+import qualified Data.Map as Map
 import Data.Maybe
 import Data.List 
 import System.IO
 
-import Modules (compileModule_)
+import Curry.Base.Ident
+
+import Modules (compileModule)
 import CurryCompilerOpts 
 import CurryDeps
-import Ident
+import Filenames
 import PathUtils
-import Env
 
 -------------------------------------------------------------------------------
 
@@ -71,7 +73,7 @@
 
  compileFile file
     = do unless (noVerb options) (putStrLn ("compiling " ++ file ++ " ..."))
-	 compileCurry (compOpts True) file
+	 compileModule (compOpts True) file
 	 return ()
 
  skipFile file
@@ -83,7 +85,7 @@
 		(putStrLn ("generating "  
 			   ++ (head (targetNames file))               
 			   ++ " ..."))
-	 compileCurry (compOpts False) file
+	 compileModule (compOpts False) file
 	 return ()
 
  targetNames fn         
@@ -121,7 +123,7 @@
 genDeps :: [FilePath] -> FilePath
 	   -> IO ([(ModuleIdent,Source)], [String])
 genDeps paths file
-   = fmap (flattenDeps . sortDeps) (deps paths [] emptyEnv file)
+   = fmap flattenDeps (deps paths [] Map.empty file)
 
 
 -------------------------------------------------------------------------------
@@ -168,9 +170,6 @@
 --
 outOfDate :: [ClockTime] -> [ClockTime] -> Bool
 outOfDate tgtimes dptimes = or (map (\t -> or (map ((<) t) dptimes)) tgtimes)
-
-
-compileCurry = compileModule_
 
 -------------------------------------------------------------------------------
 -- Error handling
diff --git a/src/CurryDeps.lhs b/src/CurryDeps.lhs
--- a/src/CurryDeps.lhs
+++ b/src/CurryDeps.lhs
@@ -13,74 +13,34 @@
 dependencies and to update programs composed of multiple modules.
 \begin{verbatim}
 
-> module CurryDeps where
+> module CurryDeps(Source(..),
+>                  deps, flattenDeps, sourceDeps, moduleDeps
+>                 ) where
 
 > import Data.List
+> import qualified Data.Map as Map
 > import Data.Maybe
 > import Control.Monad
 
-> import Error
-> import Ident
-> import Unlit
-> import CurrySyntax hiding(Interface(..))
-> import CurryParser(parseHeader)
-> import SCC
-> import Env
+> import Curry.Base.Ident
+> import Curry.Base.MessageMonad
 
+> import Curry.Syntax hiding(Interface(..))
+
+> import SCC
+> import Filenames
 > import PathUtils
 
 > data Source = Source FilePath [ModuleIdent]
 >             | Interface FilePath
 >             | Unknown
 >             deriving (Eq,Ord,Show)
-> type SourceEnv = Env ModuleIdent Source
-
-\end{verbatim}
-The module has two entry points. The function \texttt{buildScript}
-computes either a build or clean script for a module while
-\texttt{makeDepend} computes dependency rules for inclusion into a
-Makefile.
-\begin{verbatim}
-
-> buildScript :: Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool
->             -> [FilePath] -> [FilePath] -> Maybe FilePath -> FilePath 
->             -> IO [String]
-> buildScript clean debug linkAlways flat xml acy uacy
->             paths libraryPaths ofn fn =
->   do
->     mfn'      <- getCurryPath (paths ++ libraryPaths) fn
->     (fn',es1) <- return (maybe ("",["Error: missing module \"" ++ fn ++ "\""])
->                                (\x -> (x,[]))
->                                mfn')
->     (ms,es2)  <- fmap 
->                   (flattenDeps . sortDeps)
->                   (deps paths (filter (`notElem` paths) libraryPaths) emptyEnv fn')
->     es        <- return (es1 ++ es2)
->     when (null es)
->          (putStr 
->            (makeScript clean debug flat xml acy uacy linkAlways 
->                        (outputFile fn') fn ms))
->     return es
->   where outputFile fn
->           | takeExtension fn `elem` moduleExts ++ objectExts = Nothing
->           | otherwise = ofn `mplus` Just fn
->         makeScript clean = if clean then makeCleanScript else makeBuildScript
-
-> makeDepend :: [FilePath] -> [FilePath] -> Maybe FilePath -> [FilePath]
->            -> IO ()
-> makeDepend paths libraryPaths ofn ms =
->   do
->     flatDeps <- liftM (makeDeps True) (allDeps flat)
->     objectDeps <- liftM (makeDeps False) (allDeps nonFlat)
->     maybe putStr writeFile ofn (flatDeps ++ objectDeps)
->   where (flat,nonFlat) = partition (flatExt `isSuffixOf`) ms
->         allDeps = foldM (deps paths libraryPaths') emptyEnv
->         libraryPaths' = filter (`notElem` paths) libraryPaths
+> type SourceEnv = Map.Map ModuleIdent Source
 
 > deps :: [FilePath] -> [FilePath] -> SourceEnv -> FilePath -> IO SourceEnv
 > deps paths libraryPaths mEnv fn
 >   | e `elem` sourceExts = sourceDeps paths libraryPaths (mkMIdent [r]) mEnv fn
->   | e == icurryExt = return emptyEnv
+>   | e == icurryExt = return Map.empty
 >   | e `elem` objectExts = targetDeps paths libraryPaths mEnv r
 >   | otherwise = targetDeps paths libraryPaths mEnv fn
 >   where r = dropExtension fn
@@ -90,7 +50,7 @@
 >            -> IO SourceEnv
 > targetDeps paths libraryPaths mEnv fn =
 >   lookupFile [""] sourceExts fn >>=
->   maybe (return (bindEnv m Unknown mEnv)) (sourceDeps paths libraryPaths m mEnv)
+>   maybe (return (Map.insert m Unknown mEnv)) (sourceDeps paths libraryPaths m mEnv)
 >   where m = mkMIdent [fn]
 
 \end{verbatim}
@@ -108,12 +68,6 @@
 directories more than twice.
 \begin{verbatim}
 
-> lookupModule :: [FilePath] -> [FilePath] -> ModuleIdent
->              -> IO (Maybe FilePath)
-> lookupModule paths libraryPaths m
->     = lookupFile ("" : paths ++ libraryPaths) moduleExts fn
->     where fn = foldr1 catPath (moduleQualifiers m)
-
 \end{verbatim}
 In order to compute the dependency graph, source files for each module
 need to be looked up. When a source module is found, its header is
@@ -126,7 +80,7 @@
 > moduleDeps :: [FilePath] -> [FilePath] -> SourceEnv -> ModuleIdent
 >            -> IO SourceEnv
 > moduleDeps paths libraryPaths mEnv m =
->   case lookupEnv m mEnv of
+>   case Map.lookup m mEnv of
 >     Just _ -> return mEnv
 >     Nothing ->
 >       do
@@ -134,265 +88,55 @@
 >         case mbFn of
 >           Just fn
 >             | icurryExt `isSuffixOf` fn ->
->                 return (bindEnv m (Interface fn) mEnv)
+>                 return (Map.insert m (Interface fn) mEnv)
 >             | otherwise -> sourceDeps paths libraryPaths m mEnv fn
->           Nothing -> return (bindEnv m Unknown mEnv)
+>           Nothing -> return (Map.insert m Unknown mEnv)
 
 > sourceDeps :: [FilePath] -> [FilePath] -> ModuleIdent -> SourceEnv
 >            -> FilePath -> IO SourceEnv
 > sourceDeps paths libraryPaths m mEnv fn =
 >   do
 >     s <- readModule fn
->     case parseHeader fn (unlitLiterate fn s) of
->       Ok (Module m' _ ds) ->
+>     case fst $ runMsg $ parseHeader fn s of
+>       Right (Module m' _ ds) ->
 >         let ms = imports m' ds in
->         foldM (moduleDeps paths libraryPaths) (bindEnv m (Source fn ms) mEnv) ms
->       Error _ -> return (bindEnv m (Source fn []) mEnv)
+>         foldM (moduleDeps paths libraryPaths) (Map.insert m (Source fn ms) mEnv) ms
+>       Left _ -> return (Map.insert m (Source fn []) mEnv)
 
 > imports :: ModuleIdent -> [Decl] -> [ModuleIdent]
 > imports m ds = nub $
 >   [preludeMIdent | m /= preludeMIdent] ++ [m | ImportDecl _ m _ _ _ <- ds]
 
-> unlitLiterate :: FilePath -> String -> String
-> unlitLiterate fn
->   | lcurryExt `isSuffixOf` fn = snd . unlit fn
->   | otherwise = id
 
-\end{verbatim}
-It is quite straight forward to generate Makefile dependencies from
-the dependency environment. In order for these dependencies to work,
-the Makefile must include a rule
-\begin{verbatim}
-.SUFFIXES: .lcurry .curry .icurry
-.o.icurry: @echo interface $@ not found, remove $< and recompile; exit 1
-\end{verbatim}
-This dependency rule introduces an indirect dependency between a
-module and its interface. In particular, the interface may be updated
-when the module is recompiled and a new object file is generated but
-it does not matter if the interface is out-of-date with respect to the
-object code.
-\begin{verbatim}
 
-> makeDeps :: Bool -> SourceEnv -> String
-> makeDeps flat mEnv =
->   unlines (filter (not . null) (map (depsLine . snd) (envToList mEnv)))
->   where depsLine (Source fn ms) =
->           targetName fn ++ ": " ++ fn ++ " " ++
->           unwords (filter (not . null) (map interf ms))
->         depsLine (Interface _) = []
->         depsLine Unknown = []
->         interf m = maybe [] interfFile (lookupEnv m mEnv)
->         interfFile (Source fn _) = interfName fn
->         interfFile (Interface fn) = fn
->         interfFile Unknown = ""
->         targetName = if flat then flatName else objectName False
-
-\end{verbatim}
 If we want to compile the program instead of generating Makefile
 dependencies the environment has to be sorted topologically. Note
 that the dependency graph should not contain any cycles.
-\begin{verbatim}
 
-> sortDeps :: SourceEnv -> [[(ModuleIdent,Source)]]
-> sortDeps = scc (modules . fst) (imports . snd) . envToList
->   where modules m = [m]
->         imports (Source _ ms) = ms
->         imports (Interface _) = []
->         imports Unknown = []
-
-> flattenDeps :: [[(ModuleIdent,Source)]] -> ([(ModuleIdent,Source)],[String])
-> flattenDeps [] = ([],[])
-> flattenDeps (dep:deps) =
->   case dep of
->     [] -> (ms',es')
->     [m] -> (m:ms',es')
->     _ -> (ms',cyclicError (map fst dep) : es')
->   where (ms',es') = flattenDeps deps
-
-> cyclicError :: [ModuleIdent] -> String
-> cyclicError (m:ms) =
->   "Cylic import dependency between modules " ++ show m ++ rest ms
->   where rest [m] = " and " ++ show m
->         rest (m:ms) = ", " ++ show m ++ rest' ms
->         rest' [m] = ", and " ++ show m
->         rest' (m:ms) = ", " ++ show m ++ rest' ms
-
-\end{verbatim}
-The function \texttt{makeBuildScript} returns a shell script that
-rebuilds several program representations (e.g. interfaces, FlatCurry etc.)
-given a sorted list of module informations. The
-script uses the command \verb|compile| and \verb|link| to build
-programs and representations. They should be defined to reasonable values in the
-environment where the script is executed (e.g. compile=cyc
-The script deliberately uses
-the \verb|-e| shell option so that the script is terminated upon the
-first error. Unlike the original function \texttt{makeBuildScript} this
-modification uses the command "smake" to check the out-of-dateness
-of dependend program files.
-\begin{verbatim}
-
-> makeBuildScript :: Bool -> Bool -> Bool -> Bool -> Bool -> Bool 
->                 -> Maybe FilePath -> FilePath -> [(ModuleIdent,Source)] 
->                 -> String
-> makeBuildScript debug flat xml acy uacy linkAlways ofn fn mEnv =
->   unlines ("set -e" : (map (compCommands . snd) mEnv)
->                       ++ (maybe [] linkCommands ofn))
->   where 
->         compCommands (Source fn' ms)
->            | (acy || uacy) && dropExtension fn /= dropExtension fn'
->              = (smake ([flatName fn', flatIntName fn'])
->                       (fn' : catMaybes (map flatInt ms))
->                       "")
->                ++ " || (\\" --rm -f " ++ (interfName fn') ++ " && \\"
->                ++ unwords ["compile", "--flat", fn', "-o",
->                            flatName fn']
->                ++ ")"
->            | otherwise
->              = (smake (targetNames fn')
->                       (fn' : catMaybes (map flatInt ms))
->                       "")
->                ++ " || (\\" --rm -f " ++ (interfName fn')
->                ++ (compile fn') ++ ")"
->         compCommands (Interface _) = []
->         compCommands Unknown = []
->
->         linkCommands fn'
->           | linkAlways = [link fn' os]
->           | otherwise  = [smake [fn'] os "", " || \\", (link fn' os)]
->           where os = reverse (catMaybes (map (object . snd) mEnv))
->
->         smake ts ds rule
->            = "$CURRY_PATH/smake " 
->              ++ (unwords ts) ++ " : " 
->              ++ (unwords ds)
->              ++ (if null rule then "" else " : " ++ rule)
->
->         compile fn' = unwords ["compile", cFlag, fn', "-o", 
->                                head (targetNames fn')] 
->
->         cFlag | flat      = "--flat"
->               | xml       = "--xml"
->               | acy       = "--acy"
->               | uacy      = "--uacy"
->               | otherwise = "-c"
+> flattenDeps :: SourceEnv -> ([(ModuleIdent,Source)],[String])
+> flattenDeps = fdeps . sortDeps
+>     where
+>     sortDeps :: SourceEnv -> [[(ModuleIdent,Source)]]
+>     sortDeps = scc modules imports . Map.toList
 >
->         oGen fn' | flat || xml || acy || uacy = []
->                  | otherwise   = ["-o", head (targetNames fn')]
+>     modules (m, _) = [m]
 >
->         link fn' os = unwords ("link" : "-o" : fn' : os)
+>     imports (_,Source _ ms) = ms
+>     imports (_,Interface _) = []
+>     imports (_,Unknown) = []
 >
->         flatInt m =
->           case lookup m mEnv of
->             Just (Source fn' _) 
->	        -> Just (flatIntName fn')
->             Just (Interface fn') 
->	        -> Just (flatIntName (takeBaseName fn'))
->             Just Unknown 
->	        -> Nothing
->             _ -> Nothing
+>     fdeps :: [[(ModuleIdent,Source)]] -> ([(ModuleIdent,Source)],[String])
+>     fdeps = foldr checkdep ([], [])
+>     
+>     checkdep [] (ms', es')  = (ms',es')
+>     checkdep [m] (ms', es') = (m:ms',es')
+>     checkdep dep (ms', es') = (ms',cyclicError (map fst dep) : es')
 >
->         object (Source fn' _) = Just (head (targetNames fn'))
->         object (Interface _) = Nothing
->         object Unknown = Nothing
+>     cyclicError :: [ModuleIdent] -> String
+>     cyclicError (m:ms) =
+>         "Cylic import dependency between modules " ++ show m ++ rest ms
 >
->         targetNames fn' | flat      = [flatName fn', flatIntName fn']
->                         | xml       = [xmlName fn']
->                         | acy       = [acyName fn']
->                         | uacy      = [uacyName fn']
->                         | otherwise = [objectName debug fn']
-
-
-\end{verbatim}
-The function \texttt{makeCleanScript} returns a shell script that
-removes all compiled files for a module. The script uses the command
-\verb|remove| to delete the files. It should be defined to a
-reasonable value in the environment where the script is executed.
-\begin{verbatim}
-
-> makeCleanScript :: Bool -> Bool -> Bool -> Bool -> Bool -> Bool 
->                 -> Maybe FilePath -> FilePath -> [(ModuleIdent,Source)] 
->                 -> String
-> makeCleanScript debug flat xml acy uacy _ ofn _ mEnv =
->   unwords ("remove" : foldr files (maybe [] return ofn) (map snd mEnv))
->   where d = if debug then 2 else 0
->         files = if flat then flatFiles else nonFlatFiles
->         flatFiles (Source fn _) fs =
->           drop d [interfName fn,flatName fn] ++ fs
->         flatFiles (Interface _) fs = fs
->         flatFiles Unknown fs = fs
->         nonFlatFiles (Source fn _) fs =
->           drop d [interfName fn,objectName False fn,objectName True fn] ++
->           fs
->         nonFlatFiles (Interface _) fs = fs
->         nonFlatFiles Unknown fs = fs
-
-\end{verbatim}
-The function \verb|getCurryPath| searches in predefined paths
-for the corresponding \texttt{.curry} or \texttt{.lcurry} file, 
-if the given file name has no extension.
-\begin{verbatim}
-
-> getCurryPath :: [FilePath] -> FilePath -> IO (Maybe FilePath)
-> getCurryPath paths fn
->   = lookupFile filepaths exts fn
->  where
->  filepaths = "":paths'
->  fnext = takeExtension fn
->  exts | null fnext = sourceExts
->       | otherwise  = [fnext]
->  paths' | pathSeparator `elem` fn = []
->         | otherwise               = paths
-
-
-\end{verbatim}
-The following functions compute the name of the target file (e.g.
-interface file, flat curry file etc.)
-for a source module. Note that
-output files are always created in the same directory as the source
-file.
-\begin{verbatim}
-
-> interfName :: FilePath -> FilePath
-> interfName sfn = replaceExtension sfn icurryExt
-
-> flatName :: FilePath -> FilePath
-> flatName fn = replaceExtension fn flatExt
-
-> flatIntName :: FilePath -> FilePath
-> flatIntName fn = replaceExtension fn flatIntExt
-
-> xmlName :: FilePath -> FilePath
-> xmlName fn = replaceExtension fn xmlExt
-
-> acyName :: FilePath -> FilePath
-> acyName fn = replaceExtension fn acyExt
-
-> uacyName :: FilePath -> FilePath
-> uacyName fn = replaceExtension fn uacyExt
-
-> sourceRepName :: FilePath -> FilePath
-> sourceRepName fn = replaceExtension fn sourceRepExt
-
-> objectName :: Bool -> FilePath -> FilePath
-> objectName debug = name (if debug then debugExt else oExt)
->   where name ext fn = replaceExtension fn ext
-
-> curryExt, lcurryExt, icurryExt, oExt :: String
-> curryExt = ".curry"
-> lcurryExt = ".lcurry"
-> icurryExt = ".icurry"
-> flatExt = ".fcy"
-> flatIntExt = ".fint"
-> xmlExt = "_flat.xml"
-> acyExt = ".acy"
-> uacyExt = ".uacy"
-> sourceRepExt = ".cy"
-> oExt = ".o"
-> debugExt = ".d.o"
-
-> sourceExts, moduleExts, objectExts :: [String]
-> sourceExts = [curryExt,lcurryExt]
-> moduleExts = sourceExts ++ [icurryExt]
-> objectExts = [oExt]
-
-\end{verbatim}
+>     rest [m] = " and " ++ show m
+>     rest ms  = rest' ms
+>     rest' [m] = ", and " ++ show m
+>     rest' (m:ms) = ", " ++ show m ++ rest' ms
diff --git a/src/CurryEnv.hs b/src/CurryEnv.hs
--- a/src/CurryEnv.hs
+++ b/src/CurryEnv.hs
@@ -7,12 +7,16 @@
 -- November 2005,
 -- Martin Engelke (men@informatik.uni-kiel.de)
 --
-module CurryEnv (CurryEnv, 
-		 moduleId, exports, imports, interface, infixDecls,
-		 typeSynonyms, curryEnv) where
+module CurryEnv (CurryEnv(..), curryEnv) where
 
 import Data.Maybe
 
+import Curry.Base.Position
+import Curry.Base.Ident
+
+import Curry.Syntax
+
+import Types
 import Base
 
 
@@ -91,14 +95,14 @@
 -- Generate interface declarations for all type synonyms in the module.
 genTypeSyns :: TCEnv -> Module -> [IDecl]
 genTypeSyns tcEnv (Module mident _ decls)
-   = map (genTypeSynDecl mident tcEnv) (filter isTypeSyn decls)
+   = concatMap (genTypeSynDecl mident tcEnv) decls
 
 --
-genTypeSynDecl :: ModuleIdent -> TCEnv -> Decl -> IDecl
+genTypeSynDecl :: ModuleIdent -> TCEnv -> Decl -> [IDecl]
 genTypeSynDecl mid tcEnv (TypeDecl pos ident params texpr)
-   = genTypeDecl pos mid ident params tcEnv texpr
+   = [genTypeDecl pos mid ident params tcEnv texpr]
 genTypeSynDecl _ _ _ 
-   = internalError "@CurryInfo.genTypeSynDecl: illegal declaration"
+   = []
 
 --
 genTypeDecl :: Position -> ModuleIdent -> Ident -> [Ident] -> TCEnv
@@ -166,17 +170,3 @@
        [RenamingType qident' _ _] -> Just qident'
        [AliasType qident' _ _]    -> Just qident'
        _                          -> Nothing
-
---
-isTypeSyn :: Decl -> Bool
-isTypeSyn (TypeDecl _ _ _ texpr)
-   = case texpr of
-       RecordType _ _ -> False
-       _              -> True
-isTypeSyn _ = False
-
-
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-
-
diff --git a/src/CurryHtml.hs b/src/CurryHtml.hs
--- a/src/CurryHtml.hs
+++ b/src/CurryHtml.hs
@@ -1,11 +1,17 @@
-module CurryHtml(program2html,source2html) where
+module CurryHtml(source2html) where
 
-import SyntaxColoring
-import Ident
 import Data.Char hiding(Space)
-import CurryDeps(getCurryPath)
-import PathUtils (writeModule)
-       
+import Control.Exception
+
+import Curry.Base.Ident
+import Curry.Base.MessageMonad
+
+import SyntaxColoring
+import PathUtils (readModule, writeModule, getCurryPath)
+import Frontend
+
+
+
 --- translate source file into HTML file with syntaxcoloring
 --- @param outputfilename
 --- @param sourcefilename
@@ -21,8 +27,38 @@
         (if null outputfilename then writeModule output 
                                 else writeFile   output)
            (program2html modulname program)
-   
+             
+--- @param importpaths
+--- @param filename                  
+--- @return program
+filename2program :: [String] -> String -> IO Program
+filename2program paths filename
+    = do cont <- readModule filename
+         typingParseResult <- (catchError (typingParse paths filename  cont))
+         fullParseResult <- (catchError (fullParse paths filename  cont))
+         parseResult <- (catchError (return (parse filename cont)))
+         lexResult <- (catchError (return (Frontend.lex filename cont)))
+         return (genProgram cont (typingParseResult : fullParseResult : [parseResult]) lexResult)
+
+
+--- this function intercepts errors and converts it to Messages      
+--- @param a show-function for (Result a)                    
+--- @param a function that generates a (Result a)
+--- @return (Result a) without runtimeerrors   
+
+-- FIXME This is ugly. Avoid exceptions and report failure via MsgMonad instead! (hsi)
+catchError :: Show a =>IO (MsgMonad a) -> IO (MsgMonad a)
+catchError toDo = Control.Exception.catch (toDo >>= returnNF) handler 
+  where     
+    -- This refers to base3
+    handler (ErrorCall str) = return (failWith str)
+    handler  e = return (failWith (show e))  
+             
+    returnNF a = normalform a `seq` return a
+    normalform = length . show . runMsg
+                
        
+
 --- generates htmlcode with syntax highlighting            
 --- @param modulname
 --- @param a program
@@ -66,15 +102,11 @@
 code2class (TypeConstructor TypeDecla _) = "typeconstructor_typedecla"
 code2class (TypeConstructor TypeUse _) = "typeconstructor_typeuse"
 code2class (TypeConstructor TypeExport _) = "typeconstructor_typeexport"
-code2class (CodeError _ _) = "codeerror"
 code2class (CodeWarning _ _) = "codewarning"
 code2class (NotParsed _) = "notparsed"
 
 
 code2html :: Bool -> Code -> String    
-code2html _ code@(CodeError _ c) =
-      (spanTag (code2class code) 
-              (code2html False c))
 code2html ownClass code@(CodeWarning _ c) =
      (if ownClass then spanTag (code2class code) else id)
               (code2html False c)       
@@ -89,9 +121,8 @@
                       (htmlQuote (code2string c)) 
                                         
 spanTag :: String -> String -> String
-spanTag cl str
-   |null cl = str
-   | otherwise = "<span class=\""++ cl ++ "\">" ++ str ++ "</span>"
+spanTag [] str = str
+spanTag cl str = "<span class=\""++ cl ++ "\">" ++ str ++ "</span>"
 
 replace :: Char -> String -> String -> String
 replace old new = foldr (\ x -> if x == old then (new ++) else ([x]++)) ""
@@ -101,7 +132,7 @@
 
 addHtmlLink :: String -> QualIdent -> String
 addHtmlLink html qualIdent =
-   let (maybeModuleIdent,ident) = splitQualIdent qualIdent in   
+   let (maybeModuleIdent,ident) = (qualidMod qualIdent, qualidId qualIdent) in
    "<a href=\"" ++ 
    (maybe "" (\x -> show x ++ "_curry.html") maybeModuleIdent) ++ 
    "#"++ 
diff --git a/src/CurryLexer.lhs b/src/CurryLexer.lhs
deleted file mode 100644
--- a/src/CurryLexer.lhs
+++ /dev/null
@@ -1,630 +0,0 @@
-
-% $Id: CurryLexer.lhs,v 1.40 2004/03/04 22:39:12 wlux Exp $
-%
-% Copyright (c) 1999-2004, Wolfgang Lux
-% See LICENSE for the full license.
-%
-% Modified by Martin Engelke (men@informatik.uni-kiel.de)
-%
-\nwfilename{CurryLexer.lhs}
-\section{A Lexer for Curry}
-In this section a lexer for Curry is implemented.
-\begin{verbatim}
- 
-> module CurryLexer (lexFile,lexer, Token (..), Category(..), Attributes(..)) where
-
-> import Data.Char 
-> import Data.List
-> import qualified Data.Map as Map
-
-> import LexComb
-> import Position
-
-
-
-\end{verbatim}
-\paragraph{Tokens} Note that the equality and ordering instances of
-\texttt{Token} disregard the attributes.
-\begin{verbatim}
-
-> data Token = Token Category Attributes
-
-> instance Eq Token where
->   Token t1 _ == Token t2 _ = t1 == t2
-> instance Ord Token where
->   Token t1 _ `compare` Token t2 _ = t1 `compare` t2
-
-> data Category =
->   -- literals
->     CharTok | IntTok | FloatTok | IntegerTok | StringTok
->   -- identifiers
->   | Id | QId | Sym | QSym
->   -- punctuation symbols
->   | LeftParen | RightParen | Semicolon | LeftBrace | RightBrace
->   | LeftBracket | RightBracket | Comma | Underscore | Backquote
->   -- turn off layout (inserted by bbr)
->   | LeftBraceSemicolon
->   -- virtual punctation (inserted by layout)
->   | VSemicolon | VRightBrace
->   -- reserved identifiers
->   | KW_case | KW_choice | KW_data | KW_do | KW_else | KW_eval | KW_external
->   | KW_free | KW_if | KW_import | KW_in | KW_infix | KW_infixl | KW_infixr
->   | KW_let | KW_module | KW_newtype | KW_of | KW_rigid | KW_then | KW_type
->   | KW_where
->   -- reserved operators
->   | At | Colon | DotDot | DoubleColon | Equals | Backslash | Bar
->   | LeftArrow | RightArrow | Tilde | Binds
->   -- special identifiers
->   | Id_as | Id_ccall | Id_forall | Id_hiding | Id_interface | Id_primitive
->   | Id_qualified
->   -- special operators
->   | Sym_Dot | Sym_Minus | Sym_MinusDot
->   -- end-of-file token
->   | EOF
->   -- comments (only for full lexer) inserted by men & bbr
->   | LineComment | NestedComment 
->   deriving (Eq,Ord)
-
-\end{verbatim}
-There are different kinds of attributes associated with the tokens.
-Most attributes simply save the string corresponding to the token.
-However, for qualified identifiers, we also record the list of module
-qualifiers. The values corresponding to a literal token are properly
-converted already. To simplify the creation and extraction of
-attribute values we make use of records.
-\begin{verbatim}
-
-> data Attributes =
->     NoAttributes
->   | CharAttributes{ cval :: Char, original :: String}
->   | IntAttributes{ ival :: Int , original :: String}
->   | FloatAttributes{ fval :: Double, original :: String}
->   | IntegerAttributes{ intval :: Integer, original :: String}
->   | StringAttributes{ sval :: String, original :: String}
->   | IdentAttributes{ modul :: [String], sval :: String}
-
-> instance Show Attributes where
->   showsPrec _ NoAttributes = showChar '_'
->   showsPrec _ (CharAttributes cval _) = shows cval
->   showsPrec _ (IntAttributes ival _) = shows ival
->   showsPrec _ (FloatAttributes fval _) = shows fval
->   showsPrec _ (IntegerAttributes intval _) = shows intval
->   showsPrec _ (StringAttributes sval _) = shows sval
->   showsPrec _ (IdentAttributes mIdent ident) =
->     showString ("`" ++ concat (intersperse "." (mIdent ++ [ident])) ++ "'")
-
-\end{verbatim}
-The following functions can be used to construct tokens with
-specific attributes.
-\begin{verbatim}
-
-> tok :: Category -> Token
-> tok t = Token t NoAttributes
-
-> idTok :: Category -> [String] -> String -> Token
-> idTok t mIdent ident = Token t IdentAttributes{ modul = mIdent, sval = ident }
-
-> charTok :: Char -> String -> Token
-> charTok c o = Token CharTok CharAttributes{ cval = c, original = o }
-
-> intTok :: Int -> String -> Token
-> intTok base digits =
->   Token IntTok IntAttributes{ ival = convertIntegral base digits,
->                               original = digits}
-
-> floatTok :: String -> String -> Int -> String -> Token
-> floatTok mant frac exp rest =
->   Token FloatTok FloatAttributes{ fval = convertFloating mant frac exp, 
->                                   original = mant++"."++frac++rest}
- 
-> integerTok :: Integer -> String -> Token
-> integerTok base digits =
->   Token IntegerTok
->         IntegerAttributes{intval = (convertIntegral base digits) :: Integer,
->                           original = digits}
-
-> stringTok :: String -> String -> Token
-> stringTok cs o = Token StringTok StringAttributes{ sval = cs, original = o }
-
-> lineCommentTok :: String -> Token
-> lineCommentTok s = Token LineComment StringAttributes{ sval = s, original = s}
-
-> nestedCommentTok :: String -> Token
-> nestedCommentTok s = Token NestedComment StringAttributes{ sval = s, original = s }
-
-\end{verbatim}
-The \texttt{Show} instance of \texttt{Token} is designed to display
-all tokens in their source representation.
-\begin{verbatim}
-
-> instance Show Token where
->   showsPrec _ (Token Id a) = showString "identifier " . shows a
->   showsPrec _ (Token QId a) = showString "qualified identifier " . shows a
->   showsPrec _ (Token Sym a) = showString "operator " . shows a
->   showsPrec _ (Token QSym a) = showString "qualified operator " . shows a
->   showsPrec _ (Token IntTok a) = showString "integer " . shows a
->   showsPrec _ (Token FloatTok a) = showString "float " . shows a
->   showsPrec _ (Token CharTok a) = showString "character " . shows a
->   showsPrec _ (Token IntegerTok a) = showString "integer " . shows a
->   showsPrec _ (Token StringTok a) = showString "string " . shows a
->   showsPrec _ (Token LeftParen _) = showString "`('"
->   showsPrec _ (Token RightParen _) = showString "`)'"
->   showsPrec _ (Token Semicolon _) = showString "`;'"
->   showsPrec _ (Token LeftBrace _) = showString "`{'"
->   showsPrec _ (Token RightBrace _) = showString "`}'"
->   showsPrec _ (Token LeftBracket _) = showString "`['"
->   showsPrec _ (Token RightBracket _) = showString "`]'"
->   showsPrec _ (Token Comma _) = showString "`,'"
->   showsPrec _ (Token Underscore _) = showString "`_'"
->   showsPrec _ (Token Backquote _) = showString "``'"
->   showsPrec _ (Token VSemicolon _) =
->     showString "`;' (inserted due to layout)"
->   showsPrec _ (Token VRightBrace _) =
->     showString "`}' (inserted due to layout)"
->   showsPrec _ (Token At _) = showString "`@'"
->   showsPrec _ (Token Colon _) = showString "`:'"
->   showsPrec _ (Token DotDot _) = showString "`..'"
->   showsPrec _ (Token DoubleColon _) = showString "`::'"
->   showsPrec _ (Token Equals _) = showString "`='"
->   showsPrec _ (Token Backslash _) = showString "`\\'"
->   showsPrec _ (Token Bar _) = showString "`|'"
->   showsPrec _ (Token LeftArrow _) = showString "`<-'"
->   showsPrec _ (Token RightArrow _) = showString "`->'"
->   showsPrec _ (Token Tilde _) = showString "`~'"
->   showsPrec _ (Token Binds _) = showString "`:='"
->   showsPrec _ (Token Sym_Dot _) = showString "operator `.'"
->   showsPrec _ (Token Sym_Minus _) = showString "operator `-'"
->   showsPrec _ (Token Sym_MinusDot _) = showString "operator `-.'"
->   showsPrec _ (Token KW_case _) = showString "`case'"
->   showsPrec _ (Token KW_choice _) = showString "`choice'"
->   showsPrec _ (Token KW_data _) = showString "`data'"
->   showsPrec _ (Token KW_do _) = showString "`do'"
->   showsPrec _ (Token KW_else _) = showString "`else'"
->   showsPrec _ (Token KW_eval _) = showString "`eval'"
->   showsPrec _ (Token KW_external _) = showString "`external'"
->   showsPrec _ (Token KW_free _) = showString "`free'"
->   showsPrec _ (Token KW_if _) = showString "`if'"
->   showsPrec _ (Token KW_import _) = showString "`import'"
->   showsPrec _ (Token KW_in _) = showString "`in'"
->   showsPrec _ (Token KW_infix _) = showString "`infix'"
->   showsPrec _ (Token KW_infixl _) = showString "`infixl'"
->   showsPrec _ (Token KW_infixr _) = showString "`infixr'"
->   showsPrec _ (Token KW_let _) = showString "`let'"
->   showsPrec _ (Token KW_module _) = showString "`module'"
->   showsPrec _ (Token KW_newtype _) = showString "`newtype'"
->   showsPrec _ (Token KW_of _) = showString "`of'"
->   showsPrec _ (Token KW_rigid _) = showString "`rigid'"
->   showsPrec _ (Token KW_then _) = showString "`then'"
->   showsPrec _ (Token KW_type _) = showString "`type'"
->   showsPrec _ (Token KW_where _) = showString "`where'"
->   showsPrec _ (Token Id_as _) = showString "identifier `as'"
->   showsPrec _ (Token Id_ccall _) = showString "identifier `ccall'"
->   showsPrec _ (Token Id_forall _) = showString "identifier `forall'"
->   showsPrec _ (Token Id_hiding _) = showString "identifier `hiding'"
->   showsPrec _ (Token Id_interface _) = showString "identifier `interface'"
->   showsPrec _ (Token Id_primitive _) = showString "identifier `primitive'"
->   showsPrec _ (Token Id_qualified _) = showString "identifier `qualified'"
->   showsPrec _ (Token EOF _) = showString "<end-of-file>"
->   showsPrec _ (Token LineComment a) = shows a
->   showsPrec _ (Token NestedComment a) = shows a
-
-\end{verbatim}
-Tables for reserved operators and identifiers
-\begin{verbatim}
-
-> reserved_ops, reserved_and_special_ops :: Map.Map String Category
-> reserved_ops = Map.fromList [
->     ("@",  At),
->     ("::", DoubleColon),
->     ("..", DotDot),
->     ("=",  Equals),
->     ("\\", Backslash),
->     ("|",  Bar),
->     ("<-", LeftArrow),
->     ("->", RightArrow),
->     ("~",  Tilde),
->     (":=", Binds)
->   ]
-> reserved_and_special_ops = foldr (uncurry Map.insert) reserved_ops [
->     (":",  Colon),
->     (".",  Sym_Dot),
->     ("-",  Sym_Minus),
->     ("-.", Sym_MinusDot)
->   ]
-
-> reserved_ids, reserved_and_special_ids :: Map.Map String Category
-> reserved_ids = Map.fromList [
->     ("case",     KW_case),
->     ("choice",   KW_choice),
->     ("data",     KW_data),
->     ("do",       KW_do),
->     ("else",     KW_else),
->     ("eval",     KW_eval),
->     ("external", KW_external),
->     ("free",     KW_free),
->     ("if",       KW_if),
->     ("import",   KW_import),
->     ("in",       KW_in),
->     ("infix",    KW_infix),
->     ("infixl",   KW_infixl),
->     ("infixr",   KW_infixr),
->     ("let",      KW_let),
->     ("module",   KW_module),
->     ("newtype",  KW_newtype),
->     ("of",       KW_of),
->     ("rigid",    KW_rigid),
->     ("then",     KW_then),
->     ("type",     KW_type),
->     ("where",    KW_where)
->   ]
-> reserved_and_special_ids = foldr (uncurry Map.insert) reserved_ids [
->     ("as",        Id_as),
->     ("ccall",     Id_ccall),
->     ("forall",    Id_forall),
->     ("hiding",    Id_hiding),
->     ("interface", Id_interface),
->     ("primitive", Id_primitive),
->     ("qualified", Id_qualified)
->   ]
-
-\end{verbatim}
-Character classes
-\begin{verbatim}
-
-> isIdent, isSym, isOctit, isHexit :: Char -> Bool
-> isIdent c = isAlphaNum c || c `elem` "'_"
-> isSym c = c `elem` "~!@#$%^&*+-=<>:?./|\\" {-$-}
-> isOctit c = c >= '0' && c <= '7'
-> isHexit c = isDigit c || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f'
-
-inserted for full lexing (men&bbr)
-
-> isLineComment, isNestedComment :: String -> Bool
-> isLineComment ('-':'-':_) = True
-> isLineComment _ = False
-> isNestedComment ('{':'-':s) = True
-> isNestedComment _ = False
-
-
-\end{verbatim}
-Lexing functions
-\begin{verbatim}
-
-> type SuccessP a = Position -> Token -> P a
-> type FailP a = Position -> String -> P a
-
-> lexFile :: P [(Position,Token)]
-> lexFile = fullLexer tokens failP
->   where tokens p t@(Token c _)
->           | c == EOF = returnP [(p,t)]
->           | otherwise = lexFile `thenP` returnP . ((p,t):)
-
-> lexer :: SuccessP a -> FailP a -> P a
-> lexer success fail = skipBlanks
->   where -- skipBlanks moves past whitespace and comments
->         skipBlanks p [] bol = success p (tok EOF) p [] bol
->         skipBlanks p ('\t':s) bol = skipBlanks (tab p) s bol
->         skipBlanks p ('\n':s) bol = skipBlanks (nl p) s True
->         skipBlanks p ('-':'-':s) bol =
->           skipBlanks (nl p) (tail' (dropWhile (/= '\n') s)) True
->         skipBlanks p ('{':'-':s) bol =
->           nestedComment p skipBlanks fail (incr p 2) s bol
->         skipBlanks p (c:s) bol
->           | isSpace c = skipBlanks (next p) s bol
->           | otherwise =
->               (if bol then lexBOL else lexToken) success fail p (c:s) bol
->         tail' [] = []
->         tail' (_:tl) = tl
-
-> fullLexer :: SuccessP a -> FailP a -> P a
-> fullLexer success fail = skipBlanks
->   where -- skipBlanks moves past whitespace 
->         skipBlanks p [] bol = success p (tok EOF) p [] bol
->         skipBlanks p ('\t':s) bol = skipBlanks (tab p) s bol
->         skipBlanks p ('\n':s) bol = skipBlanks (nl p) s True
->         skipBlanks p s@('-':'-':_) bol = lexLineComment success p s bol
->         skipBlanks p s@('{':'-':_) bol =
->           lexNestedComment 0 id p success fail p s bol
->         skipBlanks p (c:s) bol
->           | isSpace c = skipBlanks (next p) s bol
->           | otherwise =
->               (if bol then lexBOL else lexToken) success fail p (c:s) bol
->         tail' [] = []
->         tail' (_:tl) = tl
-
-> lexLineComment :: SuccessP a -> P a
-> lexLineComment success p s = case break (=='\n') s of
->   (comment,rest) -> success p (lineCommentTok comment) (incr p (length comment)) rest
- 
-> lexNestedComment :: Int -> (String -> String) -> 
->                     Position -> SuccessP a -> FailP a -> P a
-> lexNestedComment 1 comment p0 success fail p ('-':'}':s) = 
->   success p0 (nestedCommentTok (comment "-}") ) (incr p 2) s 
-> lexNestedComment n comment p0 success fail p ('{':'-':s) = 
->   lexNestedComment (n+1) (comment . ("{-"++)) p0 success fail (incr p 2) s
-> lexNestedComment n comment p0 success fail p ('-':'}':s) = 
->   lexNestedComment (n-1) (comment . ("-}"++)) p0 success fail (incr p 2) s
-> lexNestedComment n comment p0 success fail p (c@'\t':s) = 
->   lexNestedComment n (comment . (c:)) p0 success fail (tab p) s
-> lexNestedComment n comment p0 success fail p (c@'\n':s) = 
->   lexNestedComment n (comment . (c:)) p0 success fail (nl p) s
-> lexNestedComment n comment p0 success fail p (c:s) = 
->   lexNestedComment n (comment . (c:)) p0 success fail (next p) s
-> lexNestedComment n comment p0 success fail p "" = 
->   fail p0 "Unterminated nested comment" p []
-
-> nestedComment :: Position -> P a -> FailP a -> P a
-> nestedComment p0 success fail p ('-':'}':s) = success (incr p 2) s
-> nestedComment p0 success fail p ('{':'-':s) =
->   nestedComment p (nestedComment p0 success fail) fail (incr p 2) s
-> nestedComment p0 success fail p ('\t':s) =
->   nestedComment p0 success fail (tab p) s
-> nestedComment p0 success fail p ('\n':s) =
->   nestedComment p0 success fail (nl p) s
-> nestedComment p0 success fail p (_:s) =
->   nestedComment p0 success fail (next p) s
-> nestedComment p0 success fail p [] =
->   fail p0 "Unterminated nested comment at end-of-file" p []
-
-
-> lexBOL :: SuccessP a -> FailP a -> P a
-> lexBOL success fail p s _ [] = lexToken success fail p s False []
-> lexBOL success fail p s _ ctxt@(n:rest)
->   | col < n = success p (tok VRightBrace) p s True rest
->   | col == n = success p (tok VSemicolon) p s False ctxt
->   | otherwise = lexToken success fail p s False ctxt
->   where col = column p
-
-> lexToken :: SuccessP a -> FailP a -> P a
-> lexToken success fail p [] = success p (tok EOF) p []
-> lexToken success fail p (c:s)
->   | c == '(' = token LeftParen
->   | c == ')' = token RightParen
->   | c == ',' = token Comma
->   | c == ';' = token Semicolon
->   | c == '[' = token LeftBracket
->   | c == ']' = token RightBracket
->   | c == '_' = token Underscore
->   | c == '`' = token Backquote
->   | c == '{' = lexLeftBrace (token LeftBrace) (next p) (success p) s 
->   | c == '}' = \bol -> token RightBrace bol . drop 1
->   | c == '\'' = lexChar p success fail (next p) s
->   | c == '\"' = lexString p success fail (next p) s
->   | isAlpha c = lexIdent (success p) p (c:s)
->   | isSym c = lexSym (success p) p (c:s)
->   | isDigit c = lexNumber (success p) p (c:s)
->   | otherwise = fail p ("Illegal character " ++ show c) p s
->   where token t = success p (tok t) (next p) s
-
-> lexIdent :: (Token -> P a) -> P a
-> lexIdent cont p s =
->   maybe (lexOptQual cont (token Id) [ident]) (cont . token)
->         (Map.lookup ident reserved_and_special_ids)
->         (incr p (length ident)) rest
->   where (ident,rest) = span isIdent s
->         token t = idTok t [] ident
-
-> lexSym :: (Token -> P a) -> P a
-> lexSym cont p s =
->   cont (idTok (maybe Sym id (Map.lookup sym reserved_and_special_ops)) [] sym)
->        (incr p (length sym)) rest
->   where (sym,rest) = span isSym s
-
-> lexLeftBrace leftBrace _ _       []    = leftBrace
-> lexLeftBrace leftBrace p cont (c:s) 
->   | c==';'    = cont (tok LeftBraceSemicolon) (next p) s
->   | otherwise = leftBrace
-
-\end{verbatim}
-{\em Note:} the function \texttt{lexOptQual} has been extended to provide
-the qualified use of the Prelude list operators and tuples.
-\begin{verbatim}
-
-> lexOptQual :: (Token -> P a) -> Token -> [String] -> P a
-> lexOptQual cont token mIdent p ('.':c:s)
->   | isAlpha c = lexQualIdent cont identCont mIdent (next p) (c:s)
->   | isSym c = lexQualSym cont identCont mIdent (next p) (c:s)
->   | c=='(' || c=='[' 
->     = lexQualPreludeSym cont token identCont mIdent (next p) (c:s)
->  where identCont _ _ = cont token p ('.':c:s)
-> lexOptQual cont token mIdent p s = cont token p s
-
-> lexQualIdent :: (Token -> P a) -> P a -> [String] -> P a
-> lexQualIdent cont identCont mIdent p s =
->   maybe (lexOptQual cont (idTok QId mIdent ident) (mIdent ++ [ident]))
->         (const identCont)
->         (Map.lookup ident reserved_ids)
->         (incr p (length ident)) rest
->   where (ident,rest) = span isIdent s
-
-> lexQualSym :: (Token -> P a) -> P a -> [String] -> P a
-> lexQualSym cont identCont mIdent p s =
->   maybe (cont (idTok QSym mIdent sym)) (const identCont)
->         (Map.lookup sym reserved_ops)
->         (incr p (length sym)) rest
->   where (sym,rest) = span isSym s
-
-
-> lexQualPreludeSym :: (Token -> P a) -> Token -> P a -> [String] -> P a
-> lexQualPreludeSym cont _ identCont mIdent p ('[':']':rest) =
->   cont (idTok QId mIdent "[]") (incr p 2) rest
-> lexQualPreludeSym cont _ identCont mIdent p ('(':rest)
->   | not (null rest') && head rest'==')' 
->   = cont (idTok QId mIdent ('(':tup++")")) (incr p (length tup+2)) (tail rest')
->   where (tup,rest') = span (==',') rest
-> lexQualPreludeSym cont token _ _ p s =  cont token p s
-
-
-\end{verbatim}
-{\em Note:} since Curry allows an unlimited range of integer numbers,
-read numbers must be converted to Haskell type \texttt{Integer}.
-\begin{verbatim}
-
-> lexNumber :: (Token -> P a) -> P a
-> lexNumber cont p ('0':c:s)
->   | c `elem` "oO" = lexOctal cont nullCont (incr p 2) s
->   | c `elem` "xX" = lexHexadecimal cont nullCont (incr p 2) s
->   where nullCont _ _ = cont (intTok 10 "0") (next p) (c:s)
-> lexNumber cont p s
->     = lexOptFraction cont (integerTok 10 digits) digits
->                      (incr p (length digits)) rest
->   where (digits,rest) = span isDigit s
->         num           = (read digits) :: Integer
-
-> lexOctal :: (Token -> P a) -> P a -> P a
-> lexOctal cont nullCont p s
->   | null digits = nullCont undefined undefined
->   | otherwise = cont (integerTok 8 digits) (incr p (length digits)) rest
->   where (digits,rest) = span isOctit s
-
-> lexHexadecimal :: (Token -> P a) -> P a -> P a
-> lexHexadecimal cont nullCont p s
->   | null digits = nullCont undefined undefined
->   | otherwise = cont (integerTok 16 digits) (incr p (length digits)) rest
->   where (digits,rest) = span isHexit s
-
-> lexOptFraction :: (Token -> P a) -> Token -> String -> P a
-> lexOptFraction cont _ mant p ('.':c:s)
->   | isDigit c = lexOptExponent cont (floatTok mant frac 0 "") mant frac
->                                (incr p (length frac+1)) rest
->   where (frac,rest) = span isDigit (c:s)
-> lexOptFraction cont token mant p (c:s)
->   | c `elem` "eE" = lexSignedExponent cont intCont mant "" [c] (next p) s
->   where intCont _ _ = cont token p (c:s)
-> lexOptFraction cont token _ p s = cont token p s
-
-> lexOptExponent :: (Token -> P a) -> Token -> String -> String -> P a
-> lexOptExponent cont token mant frac p (c:s)
->   | c `elem` "eE" = lexSignedExponent cont floatCont mant frac [c] (next p) s
->   where floatCont _ _ = cont token p (c:s)
-> lexOptExponent cont token mant frac p s = cont token p s
-
-> lexSignedExponent :: (Token -> P a) -> P a -> String -> String -> String -> P a
-> lexSignedExponent cont floatCont mant frac e p ('+':c:s)
->   | isDigit c = lexExponent cont mant frac (e++"+") id (next p) (c:s)
-> lexSignedExponent cont floatCont mant frac e p ('-':c:s)
->   | isDigit c = lexExponent cont mant frac (e++"-") negate (next p) (c:s)
-> lexSignedExponent cont floatCont mant frac e p (c:s)
->   | isDigit c = lexExponent cont mant frac e id p (c:s)
-> lexSignedExponent cont floatCont mant frac e p s = floatCont p s
-
-> lexExponent :: (Token -> P a) -> String -> String -> String -> (Int -> Int) -> P a
-> lexExponent cont mant frac e expSign p s =
->   cont (floatTok mant frac exp (e++digits)) (incr p (length digits)) rest
->   where (digits,rest) = span isDigit s
->         exp = expSign (convertIntegral 10 digits)
-
-> lexChar :: Position -> SuccessP a -> FailP a -> P a
-> lexChar p0 success fail p [] = fail p0 "Illegal character constant" p []
-> lexChar p0 success fail p (c:s)
->   | c == '\\' = lexEscape p (lexCharEnd p0 success fail) fail (next p) s
->   | c == '\n' = fail p0 "Illegal character constant" p (c:s)
->   | c == '\t' = lexCharEnd p0 success fail c "\t" (tab p) s
->   | otherwise = lexCharEnd p0 success fail c [c] (next p) s
-
-> lexCharEnd :: Position -> SuccessP a -> FailP a -> Char -> String -> P a
-> lexCharEnd p0 success fail c o p ('\'':s) = success p0 (charTok c o) (next p) s
-> lexCharEnd p0 success fail c o p s =
->   fail p0 "Improperly terminated character constant" p s
-
-> lexString :: Position -> SuccessP a -> FailP a -> P a
-> lexString p0 success fail = lexStringRest p0 success fail "" id
-
-> lexStringRest :: Position -> SuccessP a -> FailP a -> String -> (String -> String) -> P a
-> lexStringRest p0 success fail s0 so p [] = 
->   fail p0 "Improperly terminated string constant" p []
-> lexStringRest p0 success fail s0 so p (c:s)
->   | c == '\\' =
->       lexStringEscape p (lexStringRest p0 success fail) fail s0 so (next p) s
->   | c == '\"' = success p0 (stringTok (reverse s0) (so "")) (next p) s
->   | c == '\n' = fail p0 "Improperly terminated string constant" p []
->   | c == '\t' = lexStringRest p0 success fail (c:s0) (so . (c:)) (tab p) s
->   | otherwise = lexStringRest p0 success fail (c:s0) (so . (c:)) (next p) s
-
-> lexStringEscape ::  Position -> (String -> (String -> String) -> P a) -> FailP a -> 
->                                  String -> (String -> String) -> P a
-> lexStringEscape p0 success fail s0 so p [] = lexEscape p0 undefined fail p []
-> lexStringEscape p0 success fail s0 so p (c:s)
->   | c == '&' = success s0 (so . ("\\&"++)) (next p) s
->   | isSpace c = lexStringGap (success s0) fail so p (c:s)
->   | otherwise = lexEscape p0 (\ c' s' -> success (c':s0) (so . (s'++))) fail p (c:s)
-
-> lexStringGap :: ((String -> String) -> P a) -> FailP a -> (String -> String) -> P a
-> lexStringGap success fail so p [] = fail p "End of file in string gap" p []
-> lexStringGap success fail so p (c:s)
->   | c == '\\' = success (so . (c:)) (next p) s
->   | c == '\t' = lexStringGap success fail (so . (c:)) (tab p) s
->   | c == '\n' = lexStringGap success fail (so . (c:)) (nl p) s
->   | isSpace c = lexStringGap success fail (so . (c:)) (next p) s
->   | otherwise = fail p ("Illegal character in string gap " ++ show c) p s
-
-> lexEscape :: Position -> (Char -> String -> P a) -> FailP a -> P a
-> lexEscape p0 success fail p ('a':s) = success '\a' "\\a" (next p) s
-> lexEscape p0 success fail p ('b':s) = success '\b' "\\b" (next p) s
-> lexEscape p0 success fail p ('f':s) = success '\f' "\\f" (next p) s
-> lexEscape p0 success fail p ('n':s) = success '\n' "\\n" (next p) s
-> lexEscape p0 success fail p ('r':s) = success '\r' "\\r" (next p) s
-> lexEscape p0 success fail p ('t':s) = success '\t' "\\t" (next p) s
-> lexEscape p0 success fail p ('v':s) = success '\v' "\\v" (next p) s
-> lexEscape p0 success fail p ('\\':s) = success '\\' "\\\\" (next p) s
-> lexEscape p0 success fail p ('"':s) = success '\"' "\\\"" (next p) s
-> lexEscape p0 success fail p ('\'':s) = success '\'' "\\\'" (next p) s
-> lexEscape p0 success fail p ('^':c:s)
->   | isUpper c || c `elem` "@[\\]^_" =
->       success (chr (ord c `mod` 32)) ("\\^"++[c]) (incr p 2) s
-> lexEscape p0 success fail p ('o':c:s)
->   | isOctit c = numEscape p0 success fail 8 isOctit ("\\o"++) (next p) (c:s)
-> lexEscape p0 success fail p ('x':c:s)
->   | isHexit c = numEscape p0 success fail 16 isHexit ("\\x"++) (next p) (c:s)
-> lexEscape p0 success fail p (c:s)
->   | isDigit c = numEscape p0 success fail 10 isDigit ("\\"++) p (c:s)
-> lexEscape p0 success fail p s = asciiEscape p0 success fail p s
-
-> asciiEscape :: Position -> (Char -> String -> P a) -> FailP a -> P a
-> asciiEscape p0 success fail p ('N':'U':'L':s) = success '\NUL' "\\NUL" (incr p 3) s
-> asciiEscape p0 success fail p ('S':'O':'H':s) = success '\SOH' "\\SOH" (incr p 3) s
-> asciiEscape p0 success fail p ('S':'T':'X':s) = success '\STX' "\\STX" (incr p 3) s
-> asciiEscape p0 success fail p ('E':'T':'X':s) = success '\ETX' "\\ETX" (incr p 3) s
-> asciiEscape p0 success fail p ('E':'O':'T':s) = success '\EOT' "\\EOT" (incr p 3) s
-> asciiEscape p0 success fail p ('E':'N':'Q':s) = success '\ENQ' "\\ENQ" (incr p 3) s
-> asciiEscape p0 success fail p ('A':'C':'K':s) = success '\ACK' "\\ACK" (incr p 3) s 
-> asciiEscape p0 success fail p ('B':'E':'L':s) = success '\BEL' "\\BEL" (incr p 3) s
-> asciiEscape p0 success fail p ('B':'S':s) = success '\BS' "\\BS" (incr p 2) s
-> asciiEscape p0 success fail p ('H':'T':s) = success '\HT' "\\HT" (incr p 2) s
-> asciiEscape p0 success fail p ('L':'F':s) = success '\LF' "\\LF" (incr p 2) s
-> asciiEscape p0 success fail p ('V':'T':s) = success '\VT' "\\VT" (incr p 2) s
-> asciiEscape p0 success fail p ('F':'F':s) = success '\FF' "\\FF" (incr p 2) s
-> asciiEscape p0 success fail p ('C':'R':s) = success '\CR' "\\CR" (incr p 2) s
-> asciiEscape p0 success fail p ('S':'O':s) = success '\SO' "\\SO" (incr p 2) s
-> asciiEscape p0 success fail p ('S':'I':s) = success '\SI' "\\SI" (incr p 2) s
-> asciiEscape p0 success fail p ('D':'L':'E':s) = success '\DLE' "\\DLE" (incr p 3) s 
-> asciiEscape p0 success fail p ('D':'C':'1':s) = success '\DC1' "\\DC1" (incr p 3) s
-> asciiEscape p0 success fail p ('D':'C':'2':s) = success '\DC2' "\\DC2" (incr p 3) s
-> asciiEscape p0 success fail p ('D':'C':'3':s) = success '\DC3' "\\DC3" (incr p 3) s
-> asciiEscape p0 success fail p ('D':'C':'4':s) = success '\DC4' "\\DC4" (incr p 3) s
-> asciiEscape p0 success fail p ('N':'A':'K':s) = success '\NAK' "\\NAK" (incr p 3) s
-> asciiEscape p0 success fail p ('S':'Y':'N':s) = success '\SYN' "\\SYN" (incr p 3) s
-> asciiEscape p0 success fail p ('E':'T':'B':s) = success '\ETB' "\\ETB" (incr p 3) s
-> asciiEscape p0 success fail p ('C':'A':'N':s) = success '\CAN' "\\CAN" (incr p 3) s 
-> asciiEscape p0 success fail p ('E':'M':s) = success '\EM' "\\EM" (incr p 2) s
-> asciiEscape p0 success fail p ('S':'U':'B':s) = success '\SUB' "\\SUB" (incr p 3) s
-> asciiEscape p0 success fail p ('E':'S':'C':s) = success '\ESC' "\\ESC" (incr p 3) s
-> asciiEscape p0 success fail p ('F':'S':s) = success '\FS' "\\FS" (incr p 2) s
-> asciiEscape p0 success fail p ('G':'S':s) = success '\GS' "\\GS" (incr p 2) s
-> asciiEscape p0 success fail p ('R':'S':s) = success '\RS' "\\RS" (incr p 2) s
-> asciiEscape p0 success fail p ('U':'S':s) = success '\US' "\\US" (incr p 2) s
-> asciiEscape p0 success fail p ('S':'P':s) = success '\SP' "\\SP" (incr p 2) s
-> asciiEscape p0 success fail p ('D':'E':'L':s) = success '\DEL' "\\DEL" (incr p 3) s
-> asciiEscape p0 success fail p s = fail p0 "Illegal escape sequence" p s
-
-> numEscape :: Position -> (Char -> String -> P a) -> FailP a -> Int
->           -> (Char -> Bool) -> (String -> String) -> P a
-> numEscape p0 success fail b isDigit so p s
->   | n >= min && n <= max = success (chr n) (so digits) (incr p (length digits)) rest
->   | otherwise = fail p0 "Numeric escape out-of-range" p s
->   where (digits,rest) = span isDigit s
->         n = convertIntegral b digits
->         min = ord minBound
->         max = ord maxBound
-
-\end{verbatim}
diff --git a/src/CurryPP.lhs b/src/CurryPP.lhs
deleted file mode 100644
--- a/src/CurryPP.lhs
+++ /dev/null
@@ -1,369 +0,0 @@
-
-% $Id: CurryPP.lhs,v 1.50 2004/02/15 22:10:27 wlux Exp $
-%
-% Copyright (c) 1999-2004, Wolfgang Lux
-% See LICENSE for the full license.
-%
-% Modified by Martin Engelke (men@informatik.uni-kiel.de)
-%
-\nwfilename{CurryPP.lhs}
-\section{A Pretty Printer for Curry}\label{sec:CurryPP}
-This module implements a pretty printer for Curry expressions. It was
-derived from the Haskell pretty printer provided in Simon Marlow's
-Haskell parser.
-\begin{verbatim}
-
-> module CurryPP(module CurryPP, Doc) where
-> import Ident
-> import CurrySyntax
-> import Pretty
-
-\end{verbatim}
-Pretty print a module
-\begin{verbatim}
-
-> ppModule :: Module -> Doc
-> ppModule (Module m es ds) = ppModuleHeader m es $$ ppBlock ds
-
-\end{verbatim}
-Module header
-\begin{verbatim}
-
-> ppModuleHeader :: ModuleIdent -> Maybe ExportSpec -> Doc
-> ppModuleHeader m es =
->   text "module" <+> ppMIdent m <+> maybePP ppExportSpec es <+> text "where"
-
-> ppExportSpec :: ExportSpec -> Doc
-> ppExportSpec (Exporting _ es) = parenList (map ppExport es)
-
-> ppExport :: Export -> Doc
-> ppExport (Export x) = ppQIdent x
-> ppExport (ExportTypeWith tc cs) = ppQIdent tc <> parenList (map ppIdent cs)
-> ppExport (ExportTypeAll tc) = ppQIdent tc <> text "(..)"
-> ppExport (ExportModule m) = text "module" <+> ppMIdent m
-
-\end{verbatim}
-Declarations
-\begin{verbatim}
-
-> ppBlock :: [Decl] -> Doc
-> ppBlock = vcat . map ppDecl
-
-> ppDecl :: Decl -> Doc
-> ppDecl (ImportDecl _ m q asM is) =
->   text "import" <+> ppQualified q <+> ppMIdent m <+> maybePP ppAs asM
->                 <+> maybePP ppImportSpec is
->   where ppQualified q = if q then text "qualified" else empty
->         ppAs m = text "as" <+> ppMIdent m
-> ppDecl (InfixDecl _ fix p ops) = ppPrec fix p <+> list (map ppInfixOp ops)
-> ppDecl (DataDecl _ tc tvs cs) =
->   sep (ppTypeDeclLhs "data" tc tvs :
->        map indent (zipWith (<+>) (equals : repeat vbar) (map ppConstr cs)))
-> ppDecl (NewtypeDecl _ tc tvs nc) =
->   sep [ppTypeDeclLhs "newtype" tc tvs <+> equals,indent (ppNewConstr nc)]
-> ppDecl (TypeDecl _ tc tvs ty) =
->   sep [ppTypeDeclLhs "type" tc tvs <+> equals,indent (ppTypeExpr 0 ty)]
-> ppDecl (TypeSig _ fs ty) =
->   list (map ppIdent fs) <+> text "::" <+> ppTypeExpr 0 ty
-> ppDecl (EvalAnnot _ fs ev) =
->   list (map ppIdent fs) <+> text "eval" <+> ppEval ev
->   where ppEval EvalRigid = text "rigid"
->         ppEval EvalChoice = text "choice"
-> ppDecl (FunctionDecl _ _ eqs) = vcat (map ppEquation eqs)
-> ppDecl (ExternalDecl p cc impent f ty) =
->   sep [text "external" <+> ppCallConv cc <+> maybePP (text . show) impent,
->        indent (ppDecl (TypeSig p [f] ty))]
->   where ppCallConv CallConvPrimitive = text "primitive"
->         ppCallConv CallConvCCall = text "ccall"
-> ppDecl (FlatExternalDecl _ fs) = list (map ppIdent fs) <+> text "external"
-> ppDecl (PatternDecl _ t rhs) = ppRule (ppConstrTerm 0 t) equals rhs
-> ppDecl (ExtraVariables _ vs) = list (map ppIdent vs) <+> text "free"
-
-> ppImportSpec :: ImportSpec -> Doc
-> ppImportSpec (Importing _ is) = parenList (map ppImport is)
-> ppImportSpec (Hiding _ is) = text "hiding" <+> parenList (map ppImport is)
-
-> ppImport :: Import -> Doc
-> ppImport (Import x) = ppIdent x
-> ppImport (ImportTypeWith tc cs) = ppIdent tc <> parenList (map ppIdent cs)
-> ppImport (ImportTypeAll tc) = ppIdent tc <> text "(..)"
-
-> ppPrec :: Infix -> Integer -> Doc
-> ppPrec fix p = ppAssoc fix <+> ppPrio p
->   where ppAssoc InfixL = text "infixl"
->         ppAssoc InfixR = text "infixr"
->         ppAssoc Infix = text "infix"
->         ppPrio p = if p < 0 then empty else integer p
-
-> ppTypeDeclLhs :: String -> Ident -> [Ident] -> Doc
-> ppTypeDeclLhs kw tc tvs = text kw <+> ppIdent tc <+> hsep (map ppIdent tvs)
-
-> ppConstr :: ConstrDecl -> Doc
-> ppConstr (ConstrDecl _ tvs c tys) =
->   sep [ppExistVars tvs,ppIdent c <+> fsep (map (ppTypeExpr 2) tys)]
-> ppConstr (ConOpDecl _ tvs ty1 op ty2) =
->   sep [ppExistVars tvs,ppTypeExpr 1 ty1,ppInfixOp op <+> ppTypeExpr 1 ty2]
-
-> ppNewConstr :: NewConstrDecl -> Doc
-> ppNewConstr (NewConstrDecl _ tvs c ty) =
->   sep [ppExistVars tvs,ppIdent c <+> ppTypeExpr 2 ty]
-
-> ppExistVars :: [Ident] -> Doc
-> ppExistVars tvs
->   | null tvs = empty
->   | otherwise = text "forall" <+> hsep (map ppIdent tvs) <+> char '.'
-
-> ppEquation :: Equation -> Doc
-> ppEquation (Equation _ lhs rhs) = ppRule (ppLhs lhs) equals rhs
-
-> ppLhs :: Lhs -> Doc
-> ppLhs (FunLhs f ts) = ppIdent f <+> fsep (map (ppConstrTerm 2) ts)
-> ppLhs (OpLhs t1 f t2) =
->   ppConstrTerm 1 t1 <+> ppInfixOp f <+> ppConstrTerm 1 t2
-> ppLhs (ApLhs lhs ts) = parens (ppLhs lhs) <+> fsep (map (ppConstrTerm 2) ts)
-
-> ppRule :: Doc -> Doc -> Rhs -> Doc
-> ppRule lhs eq (SimpleRhs _ e ds) =
->   sep [lhs <+> eq,indent (ppExpr 0 e)] $$ ppLocalDefs ds
-> ppRule lhs eq (GuardedRhs es ds) =
->   sep [lhs,indent (vcat (map (ppCondExpr eq) es))] $$ ppLocalDefs ds
-
-> ppLocalDefs :: [Decl] -> Doc
-> ppLocalDefs ds
->   | null ds = empty
->   | otherwise = indent (text "where" <+> ppBlock ds)
-
-\end{verbatim}
-Interfaces
-\begin{verbatim}
-
-> ppInterface :: Interface -> Doc
-> ppInterface (Interface m ds) =
->   text "interface" <+> ppMIdent m <+> text "where" <+> lbrace
->     $$ vcat (punctuate semi (map ppIDecl ds)) $$ rbrace
-
-> ppIDecl :: IDecl -> Doc
-> ppIDecl (IImportDecl _ m) = text "import" <+> ppMIdent m
-> ppIDecl (IInfixDecl _ fix p op) = ppPrec fix p <+> ppQInfixOp op
-> ppIDecl (HidingDataDecl _ tc tvs) =
->   text "hiding" <+> ppITypeDeclLhs "data" (qualify tc) tvs
-> ppIDecl (IDataDecl _ tc tvs cs) =
->   sep (ppITypeDeclLhs "data" tc tvs :
->        map indent (zipWith (<+>) (equals : repeat vbar) (map ppIConstr cs)))
->   where ppIConstr = maybe (char '_') ppConstr
-> ppIDecl (INewtypeDecl _ tc tvs nc) =
->   sep [ppITypeDeclLhs "newtype" tc tvs <+> equals,indent (ppNewConstr nc)]
-> ppIDecl (ITypeDecl _ tc tvs ty) =
->   sep [ppITypeDeclLhs "type" tc tvs <+> equals,indent (ppTypeExpr 0 ty)]
-> ppIDecl (IFunctionDecl _ f _ ty) = ppQIdent f <+> text "::" <+> ppTypeExpr 0 ty
-
-> ppITypeDeclLhs :: String -> QualIdent -> [Ident] -> Doc
-> ppITypeDeclLhs kw tc tvs = text kw <+> ppQIdent tc <+> hsep (map ppIdent tvs)
-
-\end{verbatim}
-Types
-\begin{verbatim}
-
-> ppTypeExpr :: Int -> TypeExpr -> Doc
-> ppTypeExpr p (ConstructorType tc tys) =
->   parenExp (p > 1 && not (null tys))
->            (ppQIdent tc <+> fsep (map (ppTypeExpr 2) tys))
-> ppTypeExpr _ (VariableType tv) = ppIdent tv
-> ppTypeExpr _ (TupleType tys) = parenList (map (ppTypeExpr 0) tys)
-> ppTypeExpr _ (ListType ty) = brackets (ppTypeExpr 0 ty)
-> ppTypeExpr p (ArrowType ty1 ty2) =
->   parenExp (p > 0) (fsep (ppArrowType (ArrowType ty1 ty2)))
->   where ppArrowType (ArrowType ty1 ty2) =
->           ppTypeExpr 1 ty1 <+> rarrow : ppArrowType ty2
->         ppArrowType ty = [ppTypeExpr 0 ty]
-> ppTypeExpr p (RecordType fs rty) = 
->   braces (list (map ppTypedField fs) 
->           <> maybe empty (\ty -> space <> char '|' <+> ppTypeExpr 0 ty) rty)
->   where
->   ppTypedField (ls,ty) = 
->     list (map ppIdent ls) <> text "::" <> ppTypeExpr 0 ty
-
-\end{verbatim}
-Literals
-\begin{verbatim}
-
-> ppLiteral :: Literal -> Doc
-> ppLiteral (Char _ c)   = text (show c)
-> ppLiteral (Int _ i)    = integer i
-> ppLiteral (Float _ f)  = double f
-> ppLiteral (String _ s) = text (show s)
-
-\end{verbatim}
-Patterns
-\begin{verbatim}
-
-> ppConstrTerm :: Int -> ConstrTerm -> Doc
-> ppConstrTerm p (LiteralPattern l) =
->   parenExp (p > 1 && isNegative l) (ppLiteral l)
->   where isNegative (Char _ _)   = False
->         isNegative (Int _ i)    = i < 0
->         isNegative (Float _ f)  = f < 0.0
->         isNegative (String _ _) = False
-> ppConstrTerm p (NegativePattern op l) =
->   parenExp (p > 1) (ppInfixOp op <> ppLiteral l)
-> ppConstrTerm _ (VariablePattern v) = ppIdent v
-> ppConstrTerm p (ConstructorPattern c ts) =
->   parenExp (p > 1 && not (null ts))
->            (ppQIdent c <+> fsep (map (ppConstrTerm 2) ts))
-> ppConstrTerm p (InfixPattern t1 c t2) =
->   parenExp (p > 0)
->            (sep [ppConstrTerm 1 t1 <+> ppQInfixOp c,
->                  indent (ppConstrTerm 0 t2)])
-> ppConstrTerm _ (ParenPattern t) = parens (ppConstrTerm 0 t)
-> ppConstrTerm _ (TuplePattern _ ts) = parenList (map (ppConstrTerm 0) ts)
-> ppConstrTerm _ (ListPattern _ ts) = bracketList (map (ppConstrTerm 0) ts)
-> ppConstrTerm _ (AsPattern v t) = ppIdent v <> char '@' <> ppConstrTerm 2 t
-> ppConstrTerm _ (LazyPattern _ t) = char '~' <> ppConstrTerm 2 t
-> ppConstrTerm p (FunctionPattern f ts) =
->   parenExp (p > 1 && not (null ts))
->            (ppQIdent f <+> fsep (map (ppConstrTerm 2) ts))
-> ppConstrTerm p (InfixFuncPattern t1 f t2) =
->   parenExp (p > 0)
->            (sep [ppConstrTerm 1 t1 <+> ppQInfixOp f,
->                  indent (ppConstrTerm 0 t2)])
-> ppConstrTerm p (RecordPattern fs rt) =
->   braces (list (map ppFieldPatt fs)
->          <> (maybe empty (\t -> space <> char '|' <+> ppConstrTerm 0 t) rt))
-
-> ppFieldPatt :: Field ConstrTerm -> Doc
-> ppFieldPatt (Field _ l t) = ppIdent l <> equals <> ppConstrTerm 0 t
-
-\end{verbatim}
-Expressions
-\begin{verbatim}
-
-> ppCondExpr :: Doc -> CondExpr -> Doc
-> ppCondExpr eq (CondExpr _ g e) =
->   vbar <+> sep [ppExpr 0 g <+> eq,indent (ppExpr 0 e)]
-
-> ppExpr :: Int -> Expression -> Doc
-> ppExpr _ (Literal l) = ppLiteral l
-> ppExpr _ (Variable v) = ppQIdent v
-> ppExpr _ (Constructor c) = ppQIdent c
-> ppExpr _ (Paren e) = parens (ppExpr 0 e)
-> ppExpr p (Typed e ty) =
->   parenExp (p > 0) (ppExpr 0 e <+> text "::" <+> ppTypeExpr 0 ty)
-> ppExpr _ (Tuple _ es) = parenList (map (ppExpr 0) es)
-> ppExpr _ (List _ es) = bracketList (map (ppExpr 0) es)
-> ppExpr _ (ListCompr _ e qs) =
->   brackets (ppExpr 0 e <+> vbar <+> list (map ppStmt qs))
-> ppExpr _ (EnumFrom e) = brackets (ppExpr 0 e <+> text "..")
-> ppExpr _ (EnumFromThen e1 e2) =
->   brackets (ppExpr 0 e1 <> comma <+> ppExpr 0 e2 <+> text "..")
-> ppExpr _ (EnumFromTo e1 e2) =
->   brackets (ppExpr 0 e1 <+> text ".." <+> ppExpr 0 e2)
-> ppExpr _ (EnumFromThenTo e1 e2 e3) =
->   brackets (ppExpr 0 e1 <> comma <+> ppExpr 0 e2
->               <+> text ".." <+> ppExpr 0 e3)
-> ppExpr p (UnaryMinus op e) = parenExp (p > 1) (ppInfixOp op <> ppExpr 1 e)
-> ppExpr p (Apply e1 e2) =
->   parenExp (p > 1) (sep [ppExpr 1 e1,indent (ppExpr 2 e2)])
-> ppExpr p (InfixApply e1 op e2) =
->   parenExp (p > 0) (sep [ppExpr 1 e1 <+> ppQInfixOp (opName op),
->                          indent (ppExpr 1 e2)])
-> ppExpr _ (LeftSection e op) = parens (ppExpr 1 e <+> ppQInfixOp (opName op))
-> ppExpr _ (RightSection op e) = parens (ppQInfixOp (opName op) <+> ppExpr 1 e)
-> ppExpr p (Lambda _ t e) =
->   parenExp (p > 0)
->            (sep [backsl <> fsep (map (ppConstrTerm 2) t) <+> rarrow,
->                  indent (ppExpr 0 e)])
-> ppExpr p (Let ds e) =
->   parenExp (p > 0)
->            (sep [text "let" <+> ppBlock ds <+> text "in",ppExpr 0 e])
-> ppExpr p (Do sts e) =
->   parenExp (p > 0) (text "do" <+> (vcat (map ppStmt sts) $$ ppExpr 0 e))
-> ppExpr p (IfThenElse _ e1 e2 e3) =
->   parenExp (p > 0)
->            (text "if" <+>
->             sep [ppExpr 0 e1,
->                  text "then" <+> ppExpr 0 e2,
->                  text "else" <+> ppExpr 0 e3])
-> ppExpr p (Case _ e alts) =
->   parenExp (p > 0)
->            (text "case" <+> ppExpr 0 e <+> text "of" $$
->             indent (vcat (map ppAlt alts)))
-> ppExpr p (RecordConstr fs) =
->   braces (list (map (ppFieldExpr equals) fs))
-> ppExpr p (RecordSelection e l) =
->   parenExp (p > 0)
->            (ppExpr 1 e <+> text "->" <+> ppIdent l)
-> ppExpr p (RecordUpdate fs e) =
->   braces (list (map (ppFieldExpr (text ":=")) fs)
->          <+> char '|' <+> ppExpr 0 e)
-
-> ppStmt :: Statement -> Doc
-> ppStmt (StmtExpr _ e) = ppExpr 0 e
-> ppStmt (StmtBind _ t e) = sep [ppConstrTerm 0 t <+> larrow,indent (ppExpr 0 e)]
-> ppStmt (StmtDecl ds) = text "let" <+> ppBlock ds
-
-> ppAlt :: Alt -> Doc
-> ppAlt (Alt _ t rhs) = ppRule (ppConstrTerm 0 t) rarrow rhs
-
-> ppFieldExpr :: Doc -> Field Expression -> Doc
-> ppFieldExpr comb (Field _ l e) = ppIdent l <> comb <> ppExpr 0 e
-
-> ppOp :: InfixOp -> Doc
-> ppOp (InfixOp op) = ppQInfixOp op
-> ppOp (InfixConstr op) = ppQInfixOp op
-
-\end{verbatim}
-Goals
-\begin{verbatim}
-
-> ppGoal :: Goal -> Doc
-> ppGoal (Goal _ e ds) = sep [ppExpr 0 e,indent (ppLocalDefs ds)]
-
-\end{verbatim}
-Names
-\begin{verbatim}
-
-> ppIdent :: Ident -> Doc
-> ppIdent x = parenExp (isInfixOp x) (text (name x))
-
-> ppQIdent :: QualIdent -> Doc
-> ppQIdent x = parenExp (isQInfixOp x) (text (qualName x))
-
-> ppInfixOp :: Ident -> Doc
-> ppInfixOp x = backQuoteExp (not (isInfixOp x)) (text (name x))
-
-> ppQInfixOp :: QualIdent -> Doc
-> ppQInfixOp x = backQuoteExp (not (isQInfixOp x)) (text (qualName x))
-
-> ppMIdent :: ModuleIdent -> Doc
-> ppMIdent m = text (moduleName m)
-
-\end{verbatim}
-Print printing utilities
-\begin{verbatim}
-
-> indent :: Doc -> Doc
-> indent = nest 2
-
-> maybePP :: (a -> Doc) -> Maybe a -> Doc
-> maybePP pp = maybe empty pp
-
-> parenExp :: Bool -> Doc -> Doc
-> parenExp b doc = if b then parens doc else doc
-
-> backQuoteExp :: Bool -> Doc -> Doc
-> backQuoteExp b doc = if b then backQuote <> doc <> backQuote else doc
-
-> list, parenList, bracketList, braceList :: [Doc] -> Doc
-> list = fsep . punctuate comma
-> parenList = parens . list
-> bracketList = brackets . list
-> braceList = braces . list
-
-> backQuote,backsl,vbar,rarrow,larrow :: Doc
-> backQuote = char '`'
-> backsl = char '\\'
-> vbar = char '|'
-> rarrow = text "->"
-> larrow = text "<-"
-
-\end{verbatim}
diff --git a/src/CurryParser.lhs b/src/CurryParser.lhs
deleted file mode 100644
--- a/src/CurryParser.lhs
+++ /dev/null
@@ -1,818 +0,0 @@
-
-% $Id: CurryParser.lhs,v 1.75 2004/02/15 23:11:28 wlux Exp $
-%
-% Copyright (c) 1999-2004, Wolfgang Lux
-% See LICENSE for the full license.
-%
-% Modified by Martin Engelke (men@informatik.uni-kiel.de)
-%
-\nwfilename{CurryParser.lhs}
-\section{A Parser for Curry}
-The Curry parser is implemented using the (mostly) LL(1) parsing
-combinators described in appendix~\ref{sec:ll-parsecomb}.
-\begin{verbatim}
-
-> module CurryParser where
-> import Ident
-> import Position
-> import Error
-> import LLParseComb
-> import CurrySyntax
-> import CurryLexer
-
-> instance Symbol Token where
->   isEOF (Token c _) = c == EOF
-
-\end{verbatim}
-\paragraph{Modules}
-\begin{verbatim}
-
-> parseSource :: Bool -> FilePath -> String -> Error Module
-> parseSource flat path mod = 
->    fmap addSrcRefs (applyParser (parseModule flat) lexer path mod)
-
-> parseHeader :: FilePath -> String -> Error Module
-> parseHeader = prefixParser (moduleHeader <*->
->                             (leftBrace `opt` undefined) <*>
->                             many (importDecl <*-> many semicolon))
->                            lexer
-
-> parseModule :: Bool -> Parser Token Module a
-> parseModule flat = moduleHeader <*> decls flat
-
-> moduleHeader :: Parser Token ([Decl] -> Module) a
-> moduleHeader = Module <$-> token KW_module
->                       <*> (mIdent <?> "module name expected")
->                       <*> ((Just <$> exportSpec) `opt` Nothing)
->                       <*-> (token KW_where <?> "where expected")
->          `opt` Module mainMIdent Nothing
-
-> exportSpec :: Parser Token ExportSpec a
-> exportSpec = Exporting <$> position <*> parens (export `sepBy` comma)
-
-> export :: Parser Token Export a
-> export = qtycon <**> (parens spec `opt` Export)
->      <|> Export <$> qfun <\> qtycon
->      <|> ExportModule <$-> token KW_module <*> mIdent
->   where spec = ExportTypeAll <$-> token DotDot
->            <|> flip ExportTypeWith <$> con `sepBy` comma
-
-\end{verbatim}
-\paragraph{Interfaces}
-Since this modified version of MCC uses FlatCurry interfaces instead of
-".icurry" files, a separate parser is not required any longer.
-\begin{verbatim}
-
-> --parseInterface :: FilePath -> String -> Error Interface
-> --parseInterface fn s = applyParser parseIface lexer fn s
-
-> --parseIface :: Parser Token Interface a
-> --parseIface = Interface <$-> token Id_interface
-> --                       <*> (mIdent <?> "module name expected")
-> --                       <*-> (token KW_where <?> "where expected")
-> --                       <*> braces intfDecls
-
-\end{verbatim}
-\paragraph{Goals}
-\begin{verbatim}
-
-> parseGoal :: String -> Error Goal
-> parseGoal s = applyParser goal lexer "" s
-
-> goal :: Parser Token Goal a
-> goal = Goal <$> position <*> expr False <*> localDefs False
-
-\end{verbatim}
-\paragraph{Declarations}
-\begin{verbatim}
-
-> decls :: Bool -> Parser Token [Decl] a
-> decls flat = layout (globalDecls flat)
-
-> globalDecls :: Bool -> Parser Token [Decl] a
-> globalDecls flat =
->       (:) <$> importDecl <*> (semicolon <-*> globalDecls flat `opt` [])
->   <|> topDecl flat `sepBy` semicolon
-
-> topDecl :: Bool -> Parser Token Decl a
-> topDecl flat
->   | flat = infixDecl <|> dataDecl flat <|> typeDecl <|> functionDecl flat
->   | otherwise = infixDecl
->             <|> dataDecl flat <|> newtypeDecl <|> typeDecl
->             <|> functionDecl flat <|> externalDecl
-
-> localDefs :: Bool -> Parser Token [Decl] a
-> localDefs flat = token KW_where <-*> layout (valueDecls flat)
->            `opt` []
-
-> valueDecls :: Bool -> Parser Token [Decl] a
-> valueDecls flat = localDecl flat `sepBy` semicolon
->   where localDecl flat
->           | flat = infixDecl <|> valueDecl flat
->           | otherwise = infixDecl <|> valueDecl flat <|> externalDecl
-
-> importDecl :: Parser Token Decl a
-> importDecl =
->   flip . ImportDecl <$> position <*-> token KW_import 
->                     <*> (True <$-> token Id_qualified `opt` False)
->                     <*> mIdent
->                     <*> (Just <$-> token Id_as <*> mIdent `opt` Nothing)
->                     <*> (Just <$> importSpec `opt` Nothing)
-
-> importSpec :: Parser Token ImportSpec a
-> importSpec = position <**> (Hiding <$-> token Id_hiding `opt` Importing)
->                       <*> parens (spec `sepBy` comma)
->   where spec = tycon <**> (parens constrs `opt` Import)
->            <|> Import <$> fun <\> tycon
->         constrs = ImportTypeAll <$-> token DotDot
->               <|> flip ImportTypeWith <$> con `sepBy` comma
-
-> infixDecl :: Parser Token Decl a
-> infixDecl = infixDeclLhs InfixDecl <*> funop `sepBy1` comma
-
-> infixDeclLhs :: (Position -> Infix -> Integer -> a) -> Parser Token a b
-> infixDeclLhs f = f <$> position <*> tokenOps infixKW <*> integer
->   where infixKW = [(KW_infix,Infix),(KW_infixl,InfixL),(KW_infixr,InfixR)]
-
-> dataDecl :: Bool -> Parser Token Decl a
-> dataDecl flat = typeDeclLhs DataDecl KW_data <*> constrs
->   where constrs = equals <-*> constrDecl flat `sepBy1` bar
->             `opt` []
-
-> newtypeDecl :: Parser Token Decl a
-> newtypeDecl =
->   typeDeclLhs NewtypeDecl KW_newtype <*-> equals <*> newConstrDecl
-
-> typeDecl :: Parser Token Decl a
-> typeDecl = typeDeclLhs TypeDecl KW_type <*-> equals <*> typeDeclRhs --type0
-
-> typeDeclLhs :: (Position -> Ident -> [Ident] -> a) -> Category
->             -> Parser Token a b
-> typeDeclLhs f kw = f <$> position <*-> token kw <*> tycon <*> many typeVar
->   where typeVar = tyvar <|> anonId <$-> token Underscore
-
-> typeDeclRhs :: Parser Token TypeExpr a
-> typeDeclRhs = type0
->	        <|> (flip RecordType) Nothing
->		   <$> (layoutOff <-*> braces (labelDecls `sepBy` comma))
-
-> labelDecls = (,) <$> labId `sepBy1` comma <*-> token DoubleColon <*> type0
-
-> constrDecl :: Bool -> Parser Token ConstrDecl a
-> constrDecl flat = position <**> (existVars <**> constr)
->   where constr = conId <**> identDecl
->              <|> leftParen <-*> parenDecl
->              <|> type1 <\> conId <\> leftParen <**> opDecl
->         identDecl = many type2 <**> (conType <$> opDecl `opt` conDecl)
->         parenDecl = conOpDeclPrefix 
->	              <$> conSym <*-> rightParen <*> type2 <*> type2
->                 <|> tupleType <*-> rightParen <**> opDecl
->         opDecl = conOpDecl <$> conop <*> type1
->         conType f tys c = f (ConstructorType (qualify c) tys)
->         conDecl tys c tvs p = ConstrDecl p tvs c tys
->         conOpDecl op ty2 ty1 tvs p = ConOpDecl p tvs ty1 op ty2
->         conOpDeclPrefix op ty1 ty2 tvs p = ConOpDecl p tvs ty1 op ty2
-
-> newConstrDecl :: Parser Token NewConstrDecl a
-> newConstrDecl =
->   NewConstrDecl <$> position <*> existVars <*> con <*> type2
-
-> existVars :: Parser Token [Ident] a
-> {-
-> existVars flat
->   | flat = succeed []
->   | otherwise = token Id_forall <-*> many1 tyvar <*-> dot `opt` []
-> -}
-> existVars = succeed []
-
-> functionDecl :: Bool -> Parser Token Decl a
-> functionDecl flat = position <**> decl
->   where decl = fun `sepBy1` comma <**> funListDecl flat
->           <|?> funDecl <$> lhs <*> declRhs flat
->         lhs = (\f -> (f,FunLhs f [])) <$> fun
->          <|?> funLhs
-
-> valueDecl :: Bool -> Parser Token Decl a
-> valueDecl flat = position <**> decl
->   where decl = var `sepBy1` comma <**> valListDecl flat
->           <|?> valDecl <$> constrTerm0 <*> declRhs flat
->           <|?> funDecl <$> curriedLhs <*> declRhs flat
->         valDecl t@(ConstructorPattern c ts)
->           | not (isConstrId c) = funDecl (f,FunLhs f ts)
->           where f = unqualify c
->         valDecl t = opDecl id t
->         opDecl f (InfixPattern t1 op t2)
->           | isConstrId op = opDecl (f . InfixPattern t1 op) t2
->           | otherwise = funDecl (op',OpLhs (f t1) op' t2)
->           where op' = unqualify op
->         opDecl f t = patDecl (f t)
->         isConstrId c = c == qConsId || isQualified c || isQTupleId c
-
-> funDecl :: (Ident,Lhs) -> Rhs -> Position -> Decl
-> funDecl (f,lhs) rhs p = FunctionDecl p f [Equation p lhs rhs]
-
-> patDecl :: ConstrTerm -> Rhs -> Position -> Decl
-> patDecl t rhs p = PatternDecl p t rhs
-
-> funListDecl :: Bool -> Parser Token ([Ident] -> Position -> Decl) a
-> funListDecl flat
->   | flat = typeSig <$-> token DoubleColon <*> type0
->        <|> evalAnnot <$-> token KW_eval <*> tokenOps evalKW
->        <|> externalDecl <$-> token KW_external
->   | otherwise = typeSig <$-> token DoubleColon <*> type0
->             <|> evalAnnot <$-> token KW_eval <*> tokenOps evalKW
->   where typeSig ty vs p = TypeSig p vs ty
->         evalAnnot ev vs p = EvalAnnot p vs ev
->         evalKW = [(KW_rigid,EvalRigid),(KW_choice,EvalChoice)]
->         externalDecl vs p = FlatExternalDecl p vs
-
-> valListDecl :: Bool -> Parser Token ([Ident] -> Position -> Decl) a
-> valListDecl flat = funListDecl flat <|> extraVars <$-> token KW_free
->   where extraVars vs p = ExtraVariables p vs
-
-> funLhs :: Parser Token (Ident,Lhs) a
-> funLhs = funLhs <$> fun <*> many1 constrTerm2
->     <|?> flip ($ id) <$> constrTerm1 <*> opLhs'
->     <|?> curriedLhs
->   where opLhs' = opLhs <$> funSym <*> constrTerm0
->              <|> infixPat <$> gConSym <\> funSym <*> constrTerm1 <*> opLhs'
->              <|> backquote <-*> opIdLhs
->         opIdLhs = opLhs <$> funId <*-> checkBackquote <*> constrTerm0
->               <|> infixPat <$> qConId <\> funId <*-> backquote <*> constrTerm1
->                            <*> opLhs'
->         funLhs f ts = (f,FunLhs f ts)
->         opLhs op t2 f t1 = (op,OpLhs (f t1) op t2)
->         infixPat op t2 f g t1 = f (g . InfixPattern t1 op) t2
-
-> curriedLhs :: Parser Token (Ident,Lhs) a
-> curriedLhs = apLhs <$> parens funLhs <*> many1 constrTerm2
->   where apLhs (f,lhs) ts = (f,ApLhs lhs ts)
-
-> declRhs :: Bool -> Parser Token Rhs a
-> declRhs flat = rhs flat equals
-
-> rhs :: Bool -> Parser Token a b -> Parser Token Rhs b
-> rhs flat eq = rhsExpr <*> localDefs flat
->   where rhsExpr = SimpleRhs <$-> eq <*> position <*> expr flat
->               <|> GuardedRhs <$> many1 (condExpr flat eq)
-
-> externalDecl :: Parser Token Decl a
-> externalDecl =
->   ExternalDecl <$> position <*-> token KW_external
->                <*> callConv <*> (Just <$> string `opt` Nothing)
->                <*> fun <*-> token DoubleColon <*> type0
->   where callConv = CallConvPrimitive <$-> token Id_primitive
->                <|> CallConvCCall <$-> token Id_ccall
->                <?> "Unsupported calling convention"
-
-\end{verbatim}
-\paragraph{Interface declarations}
-\begin{verbatim}
-
-> --intfDecls :: Parser Token [IDecl] a
-> --intfDecls = (:) <$> iImportDecl <*> (semicolon <-*> intfDecls `opt` [])
-> --        <|> intfDecl `sepBy` semicolon
-
-> --intfDecl :: Parser Token IDecl a
-> --intfDecl = iInfixDecl
-> --       <|> iHidingDecl <|> iDataDecl <|> iNewtypeDecl <|> iTypeDecl
-> --       <|> iFunctionDecl <\> token Id_hiding
-
-> --iImportDecl :: Parser Token IDecl a
-> --iImportDecl = IImportDecl <$> position <*-> token KW_import <*> mIdent
-
-> --iInfixDecl :: Parser Token IDecl a
-> --iInfixDecl = infixDeclLhs IInfixDecl <*> qfunop
-
-> --iHidingDecl :: Parser Token IDecl a
-> --iHidingDecl = position <*-> token Id_hiding <**> (dataDecl <|> funcDecl)
-> --  where dataDecl = hiddenData <$-> token KW_data <*> tycon <*> many tyvar
-> --        funcDecl = hidingFunc <$-> token DoubleColon <*> type0
-> --        hiddenData tc tvs p = HidingDataDecl p tc tvs
-> --        hidingFunc ty p = IFunctionDecl p hidingId ty
-> --        hidingId = qualify (mkIdent "hiding")
-
-> --iDataDecl :: Parser Token IDecl a
-> --iDataDecl = iTypeDeclLhs IDataDecl KW_data <*> constrs
-> --  where constrs = equals <-*> iConstrDecl `sepBy1` bar
-> --            `opt` []
-> --        iConstrDecl = Just <$> constrDecl False <\> token Underscore
-> --                  <|> Nothing <$-> token Underscore
-
-> --iNewtypeDecl :: Parser Token IDecl a
-> --iNewtypeDecl =
-> --  iTypeDeclLhs INewtypeDecl KW_newtype <*-> equals <*> newConstrDecl
-
-> --iTypeDecl :: Parser Token IDecl a
-> --iTypeDecl = iTypeDeclLhs ITypeDecl KW_type <*-> equals <*> type0
-
-> --iTypeDeclLhs :: (Position -> QualIdent -> [Ident] -> a) -> Category
-> --             -> Parser Token a b
-> --iTypeDeclLhs f kw = f <$> position <*-> token kw <*> qtycon <*> many tyvar
-
-> --iFunctionDecl :: Parser Token IDecl a
-> --iFunctionDecl = IFunctionDecl <$> position <*> qfun <*-> token DoubleColon
-> --                              <*> type0
-
-\end{verbatim}
-\paragraph{Types}
-\begin{verbatim}
-
-> type0 :: Parser Token TypeExpr a
-> type0 = type1 `chainr1` (ArrowType <$-> token RightArrow)
-
-> type1 :: Parser Token TypeExpr a
-> type1 = ConstructorType <$> qtycon <*> many type2
->     <|> type2 <\> qtycon
-
-> type2 :: Parser Token TypeExpr a
-> type2 = anonType <|> identType <|> parenType <|> listType
-
-> anonType :: Parser Token TypeExpr a
-> anonType = VariableType anonId <$-> token Underscore
-
-> identType :: Parser Token TypeExpr a
-> identType = VariableType <$> tyvar
->         <|> flip ConstructorType [] <$> qtycon <\> tyvar
-
-> parenType :: Parser Token TypeExpr a
-> parenType = parens tupleType
-
-> tupleType :: Parser Token TypeExpr a
-> tupleType = type0 <??> (tuple <$> many1 (comma <-*> type0))
->       `opt` TupleType []
->   where tuple tys ty = TupleType (ty:tys)
-
-> listType :: Parser Token TypeExpr a
-> listType = ListType <$> brackets type0
-
-\end{verbatim}
-\paragraph{Literals}
-\begin{verbatim}
-
-> literal :: Parser Token Literal a
-> literal = mk Char   <$> char
->       <|> mkInt     <$> integer
->       <|> mk Float  <$> float
->       <|> mk String <$> string
-
-\end{verbatim}
-\paragraph{Patterns}
-\begin{verbatim}
-
-> constrTerm0 :: Parser Token ConstrTerm a
-> constrTerm0 = constrTerm1 `chainr1` (flip InfixPattern <$> gconop)
-
-> constrTerm1 :: Parser Token ConstrTerm a
-> constrTerm1 = varId <**> identPattern
->	    <|> ConstructorPattern <$> qConId <\> varId <*> many constrTerm2
->           <|> minus <**> negNum
->           <|> fminus <**> negFloat
->           <|> leftParen <-*> parenPattern
->           <|> constrTerm2 <\> qConId <\> leftParen
->   where identPattern = optAsPattern
->                    <|> conPattern <$> many1 constrTerm2
->         parenPattern = minus <**> minusPattern negNum
->                    <|> fminus <**> minusPattern negFloat
->                    <|> gconPattern
->                    <|> funSym <\> minus <\> fminus <*-> rightParen
->                                                    <**> identPattern
->                    <|> parenTuplePattern <\> minus <\> fminus <*-> rightParen
->         minusPattern p = rightParen <-*> identPattern
->                      <|> parenMinusPattern p <*-> rightParen
->         gconPattern = ConstructorPattern <$> gconId <*-> rightParen
->                                          <*> many constrTerm2
->         conPattern ts = flip ConstructorPattern ts . qualify
-
-> constrTerm2 :: Parser Token ConstrTerm a
-> constrTerm2 = literalPattern <|> anonPattern <|> identPattern
->           <|> parenPattern <|> listPattern <|> lazyPattern
->	    <|> recordPattern
-
-> literalPattern :: Parser Token ConstrTerm a
-> literalPattern = LiteralPattern <$> literal
-
-> anonPattern :: Parser Token ConstrTerm a
-> anonPattern = VariablePattern anonId <$-> token Underscore
-
-> identPattern :: Parser Token ConstrTerm a
-> identPattern = varId <**> optAsPattern
->            <|> flip ConstructorPattern [] <$> qConId <\> varId
-
-> parenPattern :: Parser Token ConstrTerm a
-> parenPattern = leftParen <-*> parenPattern
->   where parenPattern = minus <**> minusPattern negNum
->                    <|> fminus <**> minusPattern negFloat
->                    <|> flip ConstructorPattern [] <$> gconId <*-> rightParen
->                    <|> funSym <\> minus <\> fminus <*-> rightParen
->                                                    <**> optAsPattern
->                    <|> parenTuplePattern <\> minus <\> fminus <*-> rightParen
->         minusPattern p = rightParen <-*> optAsPattern
->                      <|> parenMinusPattern p <*-> rightParen
-
-> listPattern :: Parser Token ConstrTerm a
-> listPattern = mk' ListPattern <$> brackets (constrTerm0 `sepBy` comma)
-
-> lazyPattern :: Parser Token ConstrTerm a
-> lazyPattern = mk LazyPattern <$-> token Tilde <*> constrTerm2
-
-> recordPattern :: Parser Token ConstrTerm a
-> recordPattern = layoutOff <-*> braces content
->   where
->   content = RecordPattern <$> fields <*> record
->   fields = fieldPatt `sepBy` comma
->   fieldPatt = Field <$> position <*> labId <*-> checkEquals <*> constrTerm0
->   record = Just <$-> checkBar <*> constrTerm2 `opt` Nothing
-
-\end{verbatim}
-Partial patterns used in the combinators above, but also for parsing
-the left-hand side of a declaration.
-\begin{verbatim}
-
-> gconId :: Parser Token QualIdent a
-> gconId = colon <|> tupleCommas
-
-> negNum,negFloat :: Parser Token (Ident -> ConstrTerm) a
-> negNum = flip NegativePattern 
->          <$> (mkInt <$> integer <|> mk Float <$> float)
-> negFloat = flip NegativePattern . mk Float 
->            <$> (fromIntegral <$> integer <|> float)
-
-> optAsPattern :: Parser Token (Ident -> ConstrTerm) a
-> optAsPattern = flip AsPattern <$-> token At <*> constrTerm2
->          `opt` VariablePattern
-
-> optInfixPattern :: Parser Token (ConstrTerm -> ConstrTerm) a
-> optInfixPattern = infixPat <$> gconop <*> constrTerm0
->             `opt` id
->   where infixPat op t2 t1 = InfixPattern t1 op t2
-
-> optTuplePattern :: Parser Token (ConstrTerm -> ConstrTerm) a
-> optTuplePattern = tuple <$> many1 (comma <-*> constrTerm0)
->             `opt` ParenPattern
->   where tuple ts t = mk TuplePattern (t:ts)
-
-> parenMinusPattern :: Parser Token (Ident -> ConstrTerm) a
->                   -> Parser Token (Ident -> ConstrTerm) a
-> parenMinusPattern p = p <.> optInfixPattern <.> optTuplePattern
-
-> parenTuplePattern :: Parser Token ConstrTerm a
-> parenTuplePattern = constrTerm0 <**> optTuplePattern
->               `opt` mk TuplePattern []
-
-\end{verbatim}
-\paragraph{Expressions}
-\begin{verbatim}
-
-> condExpr :: Bool -> Parser Token a b -> Parser Token CondExpr b
-> condExpr flat eq =
->   CondExpr <$> position <*-> bar <*> expr0 flat <*-> eq <*> expr flat
-
-> expr :: Bool -> Parser Token Expression a
-> expr flat = expr0 flat <??> (flip Typed <$-> token DoubleColon <*> type0)
-
-> expr0 :: Bool -> Parser Token Expression a
-> expr0 flat = expr1 flat `chainr1` (flip InfixApply <$> infixOp)
-
-> expr1 :: Bool -> Parser Token Expression a
-> expr1 flat = UnaryMinus <$> (minus <|> fminus) <*> expr2 flat
->          <|> expr2 flat
-
-> expr2 :: Bool -> Parser Token Expression a
-> expr2 flat = lambdaExpr flat <|> letExpr flat <|> doExpr flat
->          <|> ifExpr flat <|> caseExpr flat
->          <|> expr3 flat <**> applicOrSelect
->   where
->   applicOrSelect = flip RecordSelection 
->	                  <$-> (token RightArrow <?> "-> expected")
->			  <*> labId
->		 <|?> (\es e -> foldl1 Apply (e:es))
->		          <$> many (expr3 flat) 
-
-> expr3 :: Bool -> Parser Token Expression a
-> expr3 flat = expr3' 
->   where
->   expr3' = constant <|> variable <|> parenExpr flat
->        <|> listExpr flat <|> recordExpr flat
-
-> constant :: Parser Token Expression a
-> constant = Literal <$> literal
-
-> variable :: Parser Token Expression a
-> variable = Variable <$> qFunId
-
-> parenExpr :: Bool -> Parser Token Expression a
-> parenExpr flat = parens pExpr
->   where pExpr = (minus <|> fminus) <**> minusOrTuple
->             <|> Constructor <$> tupleCommas
->             <|> leftSectionOrTuple <\> minus <\> fminus
->             <|> opOrRightSection <\> minus <\> fminus
->           `opt` mk Tuple []
->         minusOrTuple = flip UnaryMinus <$> expr1 flat <.> infixOrTuple
->                  `opt` Variable . qualify
->         leftSectionOrTuple = expr1 flat <**> infixOrTuple
->         infixOrTuple = ($ id) <$> infixOrTuple'
->         infixOrTuple' = infixOp <**> leftSectionOrExp
->                     <|> (.) <$> (optType <.> tupleExpr)
->         leftSectionOrExp = expr1 flat <**> (infixApp <$> infixOrTuple')
->                      `opt` leftSection
->         optType = flip Typed <$-> token DoubleColon <*> type0
->             `opt` id
->         tupleExpr = tuple <$> many1 (comma <-*> expr flat)
->               `opt` Paren
->         opOrRightSection = qFunSym <**> optRightSection
->                        <|> colon <**> optCRightSection
->                        <|> infixOp <\> colon <\> qFunSym <**> rightSection
->         optRightSection = (. InfixOp) <$> rightSection `opt` Variable
->         optCRightSection = (. InfixConstr) <$> rightSection `opt` Constructor
->         rightSection = flip RightSection <$> expr0 flat
->         infixApp f e2 op g e1 = f (g . InfixApply e1 op) e2
->         leftSection op f e = LeftSection (f e) op
->         tuple es e = mk Tuple (e:es)
-
-> infixOp :: Parser Token InfixOp a
-> infixOp = InfixOp <$> qfunop
->       <|> InfixConstr <$> colon
-
-> listExpr :: Bool -> Parser Token Expression a
-> listExpr flat = brackets (elements `opt` mk' List [])
->   where elements = expr flat <**> rest
->         rest = comprehension
->            <|> enumeration (flip EnumFromTo) EnumFrom
->            <|> comma <-*> expr flat <**>
->                (enumeration (flip3 EnumFromThenTo) (flip EnumFromThen)
->                <|> list <$> many (comma <-*> expr flat))
->          `opt` (\e -> mk' List [e])
->         comprehension = flip (mk ListCompr) <$-> bar <*> quals flat
->         enumeration enumTo enum =
->           token DotDot <-*> (enumTo <$> expr flat `opt` enum)
->         list es e2 e1 = mk' List (e1:e2:es)
->         flip3 f x y z = f z y x
-
-> recordExpr :: Bool -> Parser Token Expression a
-> recordExpr flat = layoutOff <-*> braces content
->   where content = RecordConstr <$> fieldConstr `sepBy` comma
->	            <|?> RecordUpdate <$> fieldUpdate `sepBy` comma
->		                      <*-> checkBar <*> expr flat
->	  fieldConstr = Field <$> position <*> labId 
->		              <*-> checkEquals <*> expr flat
->	  fieldUpdate = Field <$> position <*> labId 
->		              <*-> checkBinds <*> expr flat
-
-> lambdaExpr :: Bool -> Parser Token Expression a
-> lambdaExpr flat =
->   mk Lambda <$-> token Backslash <*> many1 constrTerm2
->          <*-> (token RightArrow <?> "-> expected") <*> expr flat
-
-> letExpr :: Bool -> Parser Token Expression a
-> letExpr flat = Let <$-> token KW_let <*> layout (valueDecls flat)
->                    <*-> (token KW_in <?> "in expected") <*> expr flat
-
-> doExpr :: Bool -> Parser Token Expression a
-> doExpr flat = uncurry Do <$-> token KW_do <*> layout (stmts flat)
-
-> ifExpr :: Bool -> Parser Token Expression a
-> ifExpr flat =
->   mk IfThenElse <$-> token KW_if <*> expr flat
->              <*-> (token KW_then <?> "then expected") <*> expr flat
->              <*-> (token KW_else <?> "else expected") <*> expr flat
-
-> caseExpr :: Bool -> Parser Token Expression a
-> caseExpr flat = mk Case <$-> token KW_case <*> expr flat
->                 <*-> (token KW_of <?> "of expected") <*> layout (alts flat)
-
-> alts :: Bool -> Parser Token [Alt] a
-> alts flat = alt flat `sepBy1` semicolon
-
-> alt :: Bool -> Parser Token Alt a
-> alt flat = Alt <$> position <*> constrTerm0
->                <*> rhs flat (token RightArrow <?> "-> expected")
-
-\end{verbatim}
-\paragraph{Statements in list comprehensions and \texttt{do} expressions}
-Parsing statements is a bit difficult because the syntax of patterns
-and expressions largely overlaps. The parser will first try to
-recognize the prefix \emph{Pattern}~\texttt{<-} of a binding statement
-and if this fails fall back into parsing an expression statement. In
-addition, we have to be prepared that the sequence
-\texttt{let}~\emph{LocalDefs} can be either a let-statement or the
-prefix of a let expression.
-\begin{verbatim}
-
-> stmts :: Bool -> Parser Token ([Statement],Expression) a
-> stmts flat = stmt flat (reqStmts flat) (optStmts flat)
-
-> reqStmts :: Bool -> Parser Token (Statement -> ([Statement],Expression)) a
-> reqStmts flat = (\(sts,e) st -> (st : sts,e)) <$-> semicolon <*> stmts flat
-
-> optStmts :: Bool -> Parser Token (Expression -> ([Statement],Expression)) a
-> optStmts flat = succeed (mk StmtExpr) <.> reqStmts flat
->           `opt` (,) []
-
-> quals :: Bool -> Parser Token [Statement] a
-> quals flat = stmt flat (succeed id) (succeed $ mk StmtExpr) `sepBy1` comma
-
-> stmt :: Bool -> Parser Token (Statement -> a) b
->      -> Parser Token (Expression -> a) b -> Parser Token a b
-> stmt flat stmtCont exprCont = letStmt flat stmtCont exprCont
->                           <|> exprOrBindStmt flat stmtCont exprCont
-
-> letStmt :: Bool -> Parser Token (Statement -> a) b
->         -> Parser Token (Expression -> a) b -> Parser Token a b
-> letStmt flat stmtCont exprCont =
->   token KW_let <-*> layout (valueDecls flat) <**> optExpr
->   where optExpr = flip Let <$-> token KW_in <*> expr flat <.> exprCont
->               <|> succeed StmtDecl <.> stmtCont
-
-> exprOrBindStmt :: Bool -> Parser Token (Statement -> a) b
->                -> Parser Token (Expression -> a) b
->                -> Parser Token a b
-> exprOrBindStmt flat stmtCont exprCont =
->        mk StmtBind <$> constrTerm0 <*-> leftArrow <*> expr flat <**> stmtCont
->   <|?> expr flat <\> token KW_let <**> exprCont
-
-\end{verbatim}
-\paragraph{Literals, identifiers, and (infix) operators}
-\begin{verbatim}
-
-> char :: Parser Token Char a
-> char = cval <$> token CharTok
-
-> int, checkInt :: Parser Token Int a
-> int = ival <$> token IntTok
-> checkInt = int <?> "integer number expected"
-
-> float, checkFloat :: Parser Token Double a
-> float = fval <$> token FloatTok
-> checkFloat = float <?> "floating point number expected"
-
-> integer, checkInteger :: Parser Token Integer a
-> integer = intval <$> token IntegerTok
-> checkInteger = integer <?> "integer number expected"
-
-> string :: Parser Token String a
-> string = sval <$> token StringTok
-
-> tycon, tyvar :: Parser Token Ident a
-> tycon = conId
-> tyvar = varId
-
-> qtycon :: Parser Token QualIdent a
-> qtycon = qConId
-
-> varId, funId, conId, labId :: Parser Token Ident a
-> varId = ident
-> funId = ident
-> conId = ident
-> labId = renameLabel <$> ident
-
-> funSym, conSym :: Parser Token Ident a
-> funSym = sym
-> conSym = sym
-
-> var, fun, con :: Parser Token Ident a
-> var = varId <|> parens (funSym <?> "operator symbol expected")
-> fun = funId <|> parens (funSym <?> "operator symbol expected")
-> con = conId <|> parens (conSym <?> "operator symbol expected")
-
-> funop, conop :: Parser Token Ident a
-> funop = funSym <|> backquotes (funId <?> "operator name expected")
-> conop = conSym <|> backquotes (conId <?> "operator name expected")
-
-> qFunId, qConId, qLabId :: Parser Token QualIdent a
-> qFunId = qIdent
-> qConId = qIdent
-> qLabId = qIdent
-
-> qFunSym, qConSym :: Parser Token QualIdent a
-> qFunSym = qSym
-> qConSym = qSym
-> gConSym = qConSym <|> colon
-
-> qfun, qcon :: Parser Token QualIdent a
-> qfun = qFunId <|> parens (qFunSym <?> "operator symbol expected")
-> qcon = qConId <|> parens (qConSym <?> "operator symbol expected")
-
-> qfunop, qconop, gconop :: Parser Token QualIdent a
-> qfunop = qFunSym <|> backquotes (qFunId <?> "operator name expected")
-> qconop = qConSym <|> backquotes (qConId <?> "operator name expected")
-> gconop = gConSym <|> backquotes (qConId <?> "operator name expected")
-
-> ident :: Parser Token Ident a
-> ident = (\ pos t -> mkIdentPosition pos $ sval t) <$> position <*> 
->        tokens [Id,Id_as,Id_ccall,Id_forall,Id_hiding,
->                Id_interface,Id_primitive,Id_qualified]
-
-> qIdent :: Parser Token QualIdent a
-> qIdent = qualify <$> ident <|> mkQIdent <$> position <*> token QId
->   where mkQIdent p a = qualifyWith (mkMIdent (modul a)) 
->                                    (mkIdentPosition p (sval a))
-
-> mIdent :: Parser Token ModuleIdent a
-> mIdent = mIdent <$> position <*> 
->      tokens [Id,QId,Id_as,Id_ccall,Id_forall,Id_hiding,
->              Id_interface,Id_primitive,Id_qualified]
->   where mIdent p a = addPositionModuleIdent p $ 
->                      mkMIdent (modul a ++ [sval a])
-
-> sym :: Parser Token Ident a
-> sym = (\ pos t -> mkIdentPosition pos $ sval t) <$> position <*> 
->       tokens [Sym,Sym_Dot,Sym_Minus,Sym_MinusDot]
-
-> qSym :: Parser Token QualIdent a
-> qSym = qualify <$> sym <|> mkQIdent <$> position <*> token QSym
->   where mkQIdent p a = qualifyWith (mkMIdent (modul a)) 
->                                    (mkIdentPosition p (sval a))
-
-> colon :: Parser Token QualIdent a
-> colon = (\ p _ -> qualify $ addPositionIdent p consId) <$> 
->         position <*> token Colon
-
-> minus :: Parser Token Ident a
-> minus = (\ p _ -> addPositionIdent p minusId) <$> 
->         position <*> token Sym_Minus
-
-> fminus :: Parser Token Ident a
-> fminus = (\ p _ -> addPositionIdent p fminusId) <$> 
->         position <*> token Sym_MinusDot
-
-> tupleCommas :: Parser Token QualIdent a
-> tupleCommas = (\ p str -> qualify $
->                           addPositionIdent p (tupleId $ 
->                                               (1 + ) $ 
->                                               length str))
->               <$> position <*> many1 comma
-
-\end{verbatim}
-\paragraph{Layout}
-\begin{verbatim}
-
-> layout :: Parser Token a b -> Parser Token a b
-> layout p = layoutOff <-*> bracket leftBraceSemicolon p rightBrace
->        <|> layoutOn <-*> p <*-> (token VRightBrace <|> layoutEnd)
-
-\end{verbatim}
-\paragraph{More combinators}
-\begin{verbatim}
-
-> braces, brackets, parens, backquotes :: Parser Token a b -> Parser Token a b
-> braces p = bracket leftBrace p rightBrace
-> brackets p = bracket leftBracket p rightBracket
-> parens p = bracket leftParen p rightParen
-> backquotes p = bracket backquote p checkBackquote
-
-\end{verbatim}
-\paragraph{Simple token parsers}
-\begin{verbatim}
-
-> token :: Category -> Parser Token Attributes a
-> token c = attr <$> symbol (Token c NoAttributes)
->   where attr (Token _ a) = a
-
-> tokens :: [Category] -> Parser Token Attributes a
-> tokens cs = foldr1 (<|>) (map token cs)
-
-> tokenOps :: [(Category,a)] -> Parser Token a b
-> tokenOps cs = ops [(Token c NoAttributes,x) | (c,x) <- cs]
-
-> dot, comma, semicolon, bar, equals, binds :: Parser Token Attributes a
-> dot = token Sym_Dot
-> comma = token Comma
-> semicolon = token Semicolon <|> token VSemicolon
-> bar = token Bar
-> equals = token Equals
-> binds = token Binds
-
-> checkBar, checkEquals, checkBinds :: Parser Token Attributes a
-> checkBar = bar <?> "| expected"
-> checkEquals = equals <?> "= expected"
-> checkBinds = binds <?> ":= expected"
-
-> backquote, checkBackquote :: Parser Token Attributes a
-> backquote = token Backquote
-> checkBackquote = backquote <?> "backquote (`) expected"
-
-> leftParen, rightParen :: Parser Token Attributes a
-> leftParen = token LeftParen
-> rightParen = token RightParen
-
-> leftBracket, rightBracket :: Parser Token Attributes a
-> leftBracket = token LeftBracket
-> rightBracket = token RightBracket
-
-> leftBrace, leftBraceSemicolon, rightBrace :: Parser Token Attributes a
-> leftBrace = token LeftBrace
-> leftBraceSemicolon = token LeftBraceSemicolon
-> rightBrace = token RightBrace
-
-> leftArrow :: Parser Token Attributes a
-> leftArrow = token LeftArrow
-
-\end{verbatim}
-\paragraph{Ident}
-\begin{verbatim}
-
-> mkIdentPosition :: Position -> String -> Ident
-> mkIdentPosition pos str = addPositionIdent pos $ mkIdent str
-
-\end{verbatim}
diff --git a/src/CurrySyntax.lhs b/src/CurrySyntax.lhs
deleted file mode 100644
--- a/src/CurrySyntax.lhs
+++ /dev/null
@@ -1,323 +0,0 @@
-> {-# LANGUAGE DeriveDataTypeable #-}
-
-% $Id: CurrySyntax.lhs,v 1.43 2004/02/15 22:10:31 wlux Exp $
-%
-% Copyright (c) 1999-2004, Wolfgang Lux
-% See LICENSE for the full license.
-%
-% Modified by Martin Engelke (men@informatik.uni-kiel.de)
-%
-\nwfilename{CurrySyntax.lhs}
-\section{The Parse Tree}
-This module provides the necessary data structures to maintain the
-parsed representation of a Curry program.
-
-\em{Note:} this modified version uses haskell type \texttt{Integer}
-instead of \texttt{Int} for representing integer values. This allows
-an unlimited range of integer constants in Curry programs.
-\begin{verbatim}
-
-> module CurrySyntax where
-> import Ident
-> import Position
-> import Data.Generics
-> import Control.Monad.State
-
-\end{verbatim}
-\paragraph{Modules}
-\begin{verbatim}
-
-> data Module = Module ModuleIdent (Maybe ExportSpec) [Decl] 
->  deriving (Eq,Show,Read,Typeable,Data)
-
-> data ExportSpec = Exporting Position [Export] deriving (Eq,Show,Read,Typeable,Data)
-> data Export =
->     Export         QualIdent                  -- f/T
->   | ExportTypeWith QualIdent [Ident]          -- T(C1,...,Cn)
->   | ExportTypeAll  QualIdent                  -- T(..)
->   | ExportModule   ModuleIdent
->   deriving (Eq,Show,Read,Typeable,Data)
-
-\end{verbatim}
-\paragraph{Module declarations}
-\begin{verbatim}
-
-> data ImportSpec =
->     Importing Position [Import]
->   | Hiding Position [Import]
->   deriving (Eq,Show,Read,Typeable,Data)
-> data Import =
->     Import         Ident            -- f/T
->   | ImportTypeWith Ident [Ident]    -- T(C1,...,Cn)
->   | ImportTypeAll  Ident            -- T(..)
->   deriving (Eq,Show,Read,Typeable,Data)
-
-> data Decl =
->     ImportDecl Position ModuleIdent Qualified (Maybe ModuleIdent)
->                (Maybe ImportSpec)
->   | InfixDecl Position Infix Integer [Ident]
->   | DataDecl Position Ident [Ident] [ConstrDecl]
->   | NewtypeDecl Position Ident [Ident] NewConstrDecl
->   | TypeDecl Position Ident [Ident] TypeExpr
->   | TypeSig Position [Ident] TypeExpr
->   | EvalAnnot Position [Ident] EvalAnnotation
->   | FunctionDecl Position Ident [Equation]
->   | ExternalDecl Position CallConv (Maybe String) Ident TypeExpr
->   | FlatExternalDecl Position [Ident]
->   | PatternDecl Position ConstrTerm Rhs
->   | ExtraVariables Position [Ident]
->   deriving (Eq,Show,Read,Typeable,Data)
-
-> data ConstrDecl =
->     ConstrDecl Position [Ident] Ident [TypeExpr]
->   | ConOpDecl Position [Ident] TypeExpr Ident TypeExpr
->   deriving (Eq,Show,Read,Typeable,Data)
-> data NewConstrDecl =
->   NewConstrDecl Position [Ident] Ident TypeExpr
->   deriving (Eq,Show,Read,Typeable,Data)
-
-> type Qualified = Bool
-> data Infix = InfixL | InfixR | Infix deriving (Eq,Show,Read,Typeable,Data)
-> data EvalAnnotation = EvalRigid | EvalChoice deriving (Eq,Show,Read,Typeable,Data)
-> data CallConv = CallConvPrimitive | CallConvCCall deriving (Eq,Show,Read,Typeable,Data)
-
-\end{verbatim}
-\paragraph{Module interfaces}
-Interface declarations are restricted to type declarations and signatures. 
-Note that an interface function declaration additionaly contains the 
-function arity (= number of parameters) in order to generate
-correct FlatCurry function applications.
-\begin{verbatim}
-
-> data Interface = Interface ModuleIdent [IDecl] deriving (Eq,Show,Read,Typeable,Data)
-
-> data IDecl =
->     IImportDecl Position ModuleIdent
->   | IInfixDecl Position Infix Integer QualIdent
->   | HidingDataDecl Position Ident [Ident] 
->   | IDataDecl Position QualIdent [Ident] [Maybe ConstrDecl]
->   | INewtypeDecl Position QualIdent [Ident] NewConstrDecl
->   | ITypeDecl Position QualIdent [Ident] TypeExpr
->   | IFunctionDecl Position QualIdent Int TypeExpr
->   deriving (Eq,Show,Read,Typeable,Data)
-
-\end{verbatim}
-\paragraph{Types}
-\begin{verbatim}
-
-> data TypeExpr =
->     ConstructorType QualIdent [TypeExpr]
->   | VariableType Ident
->   | TupleType [TypeExpr]
->   | ListType TypeExpr
->   | ArrowType TypeExpr TypeExpr
->   | RecordType [([Ident],TypeExpr)] (Maybe TypeExpr) 
->     -- {l1 :: t1,...,ln :: tn | r}
->   deriving (Eq,Show,Read,Typeable,Data)
-
-\end{verbatim}
-\paragraph{Functions}
-\begin{verbatim}
-
-> data Equation = Equation Position Lhs Rhs deriving (Eq,Show,Read,Typeable,Data)
-> data Lhs =
->     FunLhs Ident [ConstrTerm]
->   | OpLhs ConstrTerm Ident ConstrTerm
->   | ApLhs Lhs [ConstrTerm]
->   deriving (Eq,Show,Read,Typeable,Data)
-> data Rhs =
->     SimpleRhs Position Expression [Decl]
->   | GuardedRhs [CondExpr] [Decl]
->   deriving (Eq,Show,Read,Typeable,Data)
-> data CondExpr = CondExpr Position Expression Expression deriving (Eq,Show,Read,Typeable,Data)
-
-> flatLhs :: Lhs -> (Ident,[ConstrTerm])
-> flatLhs lhs = flat lhs []
->   where flat (FunLhs f ts) ts' = (f,ts ++ ts')
->         flat (OpLhs t1 op t2) ts = (op,t1:t2:ts)
->         flat (ApLhs lhs ts) ts' = flat lhs (ts ++ ts')
-
-\end{verbatim}
-\paragraph{Literals} The \texttt{Ident} argument of an \texttt{Int}
-literal is used for supporting ad-hoc polymorphism on integer
-numbers. An integer literal can be used either as an integer number or
-as a floating-point number depending on its context. The compiler uses
-the identifier of the \texttt{Int} literal for maintaining its type.
-\begin{verbatim}
-
-> data Literal =
->     Char SrcRef Char                         -- should be Int to handle Unicode
->   | Int Ident Integer
->   | Float SrcRef Double
->   | String SrcRef String                     -- should be [Int] to handle Unicode
->   deriving (Eq,Show,Read,Typeable,Data)
-
-> mk' :: ([SrcRef] -> a) -> a
-> mk' = ($[])
-
-> mk :: (SrcRef -> a) -> a
-> mk = ($noRef)
-
-> mkInt :: Integer -> Literal
-> mkInt i = mk (\r -> Int (addPositionIdent (AST  r) anonId) i) 
-
-\end{verbatim}
-\paragraph{Patterns}
-\begin{verbatim}
-
-> data ConstrTerm =
->     LiteralPattern Literal
->   | NegativePattern Ident Literal
->   | VariablePattern Ident
->   | ConstructorPattern QualIdent [ConstrTerm]
->   | InfixPattern ConstrTerm QualIdent ConstrTerm
->   | ParenPattern ConstrTerm
->   | TuplePattern SrcRef [ConstrTerm]
->   | ListPattern [SrcRef] [ConstrTerm]
->   | AsPattern Ident ConstrTerm
->   | LazyPattern SrcRef ConstrTerm
->   | FunctionPattern QualIdent [ConstrTerm]
->   | InfixFuncPattern ConstrTerm QualIdent ConstrTerm
->   | RecordPattern [Field ConstrTerm] (Maybe ConstrTerm)  
->         -- {l1 = p1, ..., ln = pn}  oder {l1 = p1, ..., ln = pn | p}
->   deriving (Eq,Show,Read,Typeable,Data)
-
-\end{verbatim}
-\paragraph{Expressions}
-\begin{verbatim}
-
-> data Expression =
->     Literal Literal
->   | Variable QualIdent
->   | Constructor QualIdent
->   | Paren Expression
->   | Typed Expression TypeExpr
->   | Tuple SrcRef [Expression]
->   | List [SrcRef] [Expression]
->   | ListCompr SrcRef Expression [Statement] -- the ref corresponds to the main list  
->   | EnumFrom Expression
->   | EnumFromThen Expression Expression
->   | EnumFromTo Expression Expression
->   | EnumFromThenTo Expression Expression Expression
->   | UnaryMinus Ident Expression
->   | Apply Expression Expression
->   | InfixApply Expression InfixOp Expression
->   | LeftSection Expression InfixOp
->   | RightSection InfixOp Expression
->   | Lambda SrcRef [ConstrTerm] Expression
->   | Let [Decl] Expression
->   | Do [Statement] Expression
->   | IfThenElse SrcRef Expression Expression Expression
->   | Case SrcRef Expression [Alt]
->   | RecordConstr [Field Expression]            -- {l1 = e1,...,ln = en}
->   | RecordSelection Expression Ident           -- e -> l
->   | RecordUpdate [Field Expression] Expression -- {l1 := e1,...,ln := en | e}
->   deriving (Eq,Show,Read,Typeable,Data)
-
-> data InfixOp = InfixOp QualIdent | InfixConstr QualIdent deriving (Eq,Show,Read,Typeable,Data)
-
-> data Statement =
->     StmtExpr SrcRef Expression
->   | StmtDecl [Decl]
->   | StmtBind SrcRef ConstrTerm Expression
->   deriving (Eq,Show,Read,Typeable,Data)
-
-> data Alt = Alt Position ConstrTerm Rhs deriving (Eq,Show,Read,Typeable,Data)
-
-> data Field a = Field Position Ident a deriving (Eq, Show,Read,Typeable,Data)
-
-> fieldLabel :: Field a -> Ident
-> fieldLabel (Field _ l _) = l
-
-> fieldTerm :: Field a -> a
-> fieldTerm (Field _ _ t) = t
-
-> field2Tuple :: Field a -> (Ident,a)
-> field2Tuple (Field _ l t) = (l,t)
-
-> opName :: InfixOp -> QualIdent
-> opName (InfixOp op) = op
-> opName (InfixConstr c) = c
-
-\end{verbatim}
-\paragraph{Goals}
-A goal is equivalent to an unconditional right hand side of an equation.
-\begin{verbatim}
-
-> data Goal = Goal Position Expression [Decl] deriving (Eq,Show,Read,Typeable,Data)
-
-\end{verbatim}
-
-> instance SrcRefOf ConstrTerm where
->   srcRefOf (LiteralPattern l) = srcRefOf l
->   srcRefOf (NegativePattern i _) = srcRefOf i
->   srcRefOf (VariablePattern i) = srcRefOf i
->   srcRefOf (ConstructorPattern i _) = srcRefOf i
->   srcRefOf (InfixPattern _ i _) = srcRefOf i
->   srcRefOf (ParenPattern c) = srcRefOf c
->   srcRefOf (TuplePattern s _) = s
->   srcRefOf (ListPattern s _) = error "list pattern has several source refs"
->   srcRefOf (AsPattern i _) = srcRefOf i
->   srcRefOf (LazyPattern s _) = s
->   srcRefOf (FunctionPattern i _) = srcRefOf i
->   srcRefOf (InfixFuncPattern _ i _) = srcRefOf i
-
-> instance SrcRefOf CurrySyntax.Literal where
->   srcRefOf (Char s _)   = s
->   srcRefOf (Int i _)    = srcRefOf i
->   srcRefOf (Float s _)  = s
->   srcRefOf (String s _) = s
-
----------------------------
--- add source references
----------------------------
-
-> type M a = a -> State Int a
-> 
-> addSrcRefs :: Module -> Module
-> addSrcRefs x = evalState (addRef x) 0
->   where 
->     addRef :: Data a' => M a' 
->     addRef = down `extM` addRefPos   
->                   `extM` addRefSrc   
->                   `extM` addRefIdent
->                   `extM` addRefListPat
->                   `extM` addRefListExp
->       where
->         down :: Data a' => M a'
->         down = gmapM addRef
-> 
->         addRefPos :: M [SrcRef]
->         addRefPos _ = liftM (:[]) next
-> 
->         addRefSrc :: M SrcRef
->         addRefSrc _ = next
-> 
->         addRefIdent :: M Ident
->         addRefIdent ident = liftM (flip addRefId ident) next
->
->         addRefListPat :: M ConstrTerm
->         addRefListPat (ListPattern _ ts) = do
->           liftM (uncurry ListPattern) (addRefList ts)
->         addRefListPat ct = gmapM addRef ct
->   
->         addRefListExp :: M Expression
->         addRefListExp (List _ ts) = do
->           liftM (uncurry List) (addRefList ts)
->         addRefListExp ct = gmapM addRef ct
->   
->         addRefList :: Data a' => [a'] -> State Int ([SrcRef],[a'])
->         addRefList ts = do
->           i <- next
->           let add t = do t' <- addRef t;j <- next; return (j,t')
->           ists <- sequence (map add ts)
->           let (is,ts') = unzip ists
->           return (i:is,ts')
->          
->         current,next :: State Int SrcRef
->         current = liftM (SrcRef . (:[])) get
->
->         next = do
->           i <- get
->           put $! i+1
->           return (SrcRef [i])
diff --git a/src/Desugar.lhs b/src/Desugar.lhs
--- a/src/Desugar.lhs
+++ b/src/Desugar.lhs
@@ -1,4 +1,3 @@
-
 % $Id: Desugar.lhs,v 1.42 2004/02/15 22:10:32 wlux Exp $
 %
 % Copyright (c) 2001-2004, Wolfgang Lux
@@ -60,19 +59,25 @@
 all names must be properly qualified before calling this module.}
 \begin{verbatim}
 
-> module Desugar(desugar,desugarGoal) where
+> module Desugar(desugar) where
 
 > import Data.Maybe
-> import Control.Monad
+> import Control.Arrow(second)
+> import Control.Monad.State as S
 > import Data.List
 
+> import Curry.Base.Position
+> import Curry.Base.Ident
+> import Curry.Syntax.Utils
+> import Curry.Syntax
+
+> import Types
 > import Base
-> import Combined
 > import Typing
 > import Utils
-> import Ident
 
 
+
 posE = undefined
 
 \end{verbatim}
@@ -84,10 +89,10 @@
 variables.
 \begin{verbatim}
 
-> type DesugarState a = StateT ValueEnv (St Int) a
+> type DesugarState a = S.StateT ValueEnv (S.State Int) a
 
 > run :: DesugarState a -> ValueEnv -> a
-> run m tyEnv = runSt (callSt m tyEnv) 1
+> run m tyEnv = S.evalState (S.evalStateT m tyEnv) 1
 
 \end{verbatim}
 The desugaring phase keeps only the type, function, and value
@@ -115,90 +120,12 @@
 >     dss <- mapM (desugarRecordDecl m tcEnv) ds
 >     let ds' = concat dss
 >     ds'' <- desugarDeclGroup m tcEnv ds'
->     tyEnv' <- fetchSt
+>     tyEnv' <- S.get
 >     return (filter isTypeDecl ds' ++ ds'', tyEnv')
 
 \end{verbatim}
-While a goal of type \texttt{IO \_} is executed directly by the
-runtime system, all other goals are evaluated under an interactive
-top-level which displays the solutions of the goal and in particular
-the bindings of the free variables. For this reason, the free
-variables declared in the \texttt{where} clause of a goal are
-translated into free variables of the goal. In addition, the goal
-is transformed into a first order expression by performing a
-unification with another variable. Thus, a goal
-\begin{quote}
- \emph{expr}
- \texttt{where} $v_1$,\dots,$v_n$ \texttt{free}; \emph{decls}
-\end{quote}
-where no free variable declarations occur in \emph{decls} is
-translated into the function
-\begin{quote}
-  \emph{f} $v_0$ $v_1$ \dots{} $v_n$ \texttt{=}
-    $v_0$ \texttt{=:=} \emph{expr}
-    \texttt{where} \emph{decls}
-\end{quote}
-where $v_0$ is a fresh variable.
 
-\textbf{Note:} The debugger assumes that the goal is always a nullary
-function. This means that we must not $\eta$-expand functional goal
-expressions. In order to avoid the $\eta$-expansion we cheat a little
-bit here and change the type of the goal into $\forall\alpha.\alpha$
-if it really has a functional type.
 
-\ToDo{Fix the debugger to handle functional goals so that this
-hack is no longer needed.}
-\begin{verbatim}
-
-> desugarGoal :: Bool -> ValueEnv -> TCEnv -> ModuleIdent -> Ident -> Goal
->             -> (Maybe [Ident],Module,ValueEnv)
-> desugarGoal debug tyEnv tcEnv m g (Goal p e ds)
->   | debug || isIO ty =
->       desugarGoalIO tyEnv tcEnv p m g (Let ds e)
->         (if debug && arrowArity ty > 0 then typeVar 0 else ty)
->   | otherwise = desugarGoal' tyEnv tcEnv p m g vs e' ty
->   where ty = typeOf tyEnv e
->         (vs,e') = liftGoalVars (if null ds then e else Let ds e)
->         isIO (TypeConstructor tc [_]) = tc == qIOId
->         isIO _ = False
-
-> desugarGoalIO :: ValueEnv -> TCEnv -> Position -> ModuleIdent -> Ident
->               -> Expression -> Type -> (Maybe [Ident],Module,ValueEnv)
-> desugarGoalIO tyEnv tcEnv p m g e ty =
->   (Nothing,
->    Module m Nothing [goalDecl p g [] e'],
->    bindFun m g (polyType ty) tyEnv')
->   where (e',tyEnv') = run (desugarGoalExpr m tcEnv e) tyEnv
-
-> desugarGoal' :: ValueEnv -> TCEnv -> Position -> ModuleIdent -> Ident -> [Ident]
->              -> Expression -> Type -> (Maybe [Ident],Module,ValueEnv)
-> desugarGoal' tyEnv tcEnv p m g vs e ty =
->   (Just vs',
->    Module m Nothing [goalDecl p g (v0:vs') (apply prelUnif [mkVar v0,e'])],
->    bindFun m v0 (monoType ty) (bindFun m g (polyType ty') tyEnv'))
->   where (e',tyEnv') = run (desugarGoalExpr m tcEnv e) tyEnv
->         v0 = anonId
->         vs' = filter (`elem` qfv m e') vs
->         ty' = TypeArrow ty (foldr (TypeArrow . typeOf tyEnv) successType vs')
-
-> goalDecl :: Position -> Ident -> [Ident] -> Expression -> Decl
-> goalDecl p g vs e = funDecl p g (map VariablePattern vs) e
-
-> desugarGoalExpr :: ModuleIdent -> TCEnv -> Expression
->                 -> DesugarState (Expression,ValueEnv)
-> desugarGoalExpr m tcEnv e =
->   do
->     e' <- desugarExpr m tcEnv (first "") e
->     tyEnv' <- fetchSt
->     return (e',tyEnv')
-
-> liftGoalVars :: Expression -> ([Ident],Expression)
-> liftGoalVars (Let ds e) =
->   (concat [vs | ExtraVariables _ vs <- vds],Let ds' e)
->   where (vds,ds') = partition isExtraVariables ds
-> liftGoalVars e = ([],e)
-
-\end{verbatim}
 Within a declaration group, all type signatures and evaluation
 annotations are discarded. First, the patterns occurring in the left
 hand sides are desugared. Due to lazy patterns this may add further
@@ -219,7 +146,7 @@
 >     return (PatternDecl p t' rhs : concat dss')
 > desugarDeclLhs m tcEnv (FlatExternalDecl p fs) =
 >   do
->     tyEnv <- fetchSt
+>     tyEnv <- S.get
 >     return (map (externalDecl tyEnv p) fs)
 >   where externalDecl tyEnv p f =
 >           ExternalDecl p CallConvPrimitive (Just (name f)) f
@@ -243,7 +170,7 @@
 > desugarDeclRhs :: ModuleIdent -> TCEnv -> Decl -> DesugarState Decl
 > desugarDeclRhs m tcEnv (FunctionDecl p f eqs) =
 >   do
->     tyEnv <- fetchSt
+>     tyEnv <- S.get
 >     let ty =  (flip typeOf (Variable (qual f))) tyEnv
 >     liftM (FunctionDecl p f) 
 >	    (mapM (desugarEquation m tcEnv (arrowArgs ty)) eqs)
@@ -278,7 +205,7 @@
 
 > desugarLiteral :: Literal -> DesugarState (Either Literal ([SrcRef],[Literal]))
 > desugarLiteral (Char p c) = return (Left (Char p c))
-> desugarLiteral (Int v i)  = liftM (Left . fixType) fetchSt
+> desugarLiteral (Int v i)  = liftM (Left . fixType) S.get
 >   where 
 >    fixType tyEnv
 >      | typeOf tyEnv v == floatType 
@@ -312,12 +239,12 @@
 > desugarTerm _ _ _ ds (VariablePattern v) = return (ds,VariablePattern v)
 > desugarTerm m tcEnv p ds (ConstructorPattern c [t]) =
 >   do
->     tyEnv <- fetchSt
->     liftM (if isNewtypeConstr tyEnv c then id else apSnd (constrPat c))
+>     tyEnv <- S.get
+>     liftM (if isNewtypeConstr tyEnv c then id else second (constrPat c))
 >           (desugarTerm m tcEnv p ds t)
 >   where constrPat c t = ConstructorPattern c [t]
 > desugarTerm m tcEnv p ds (ConstructorPattern c ts) =
->   liftM (apSnd (ConstructorPattern c)) (mapAccumM (desugarTerm m tcEnv p) ds ts)
+>   liftM (second (ConstructorPattern c)) (mapAccumM (desugarTerm m tcEnv p) ds ts)
 > desugarTerm m tcEnv p ds (InfixPattern t1 op t2) =
 >   desugarTerm m tcEnv p ds (ConstructorPattern op [t1,t2])
 > desugarTerm m tcEnv p ds (ParenPattern t) = desugarTerm m tcEnv p ds t
@@ -326,7 +253,7 @@
 >   where tupleConstr ts = addRef pos $ 
 >                          if null ts then qUnitId else qTupleId (length ts)
 > desugarTerm m tcEnv p ds (ListPattern pos ts) =
->   liftM (apSnd (desugarList pos cons nil)) (mapAccumM (desugarTerm m tcEnv p) ds ts)
+>   liftM (second (desugarList pos cons nil)) (mapAccumM (desugarTerm m tcEnv p) ds ts)
 >   where nil  p' = ConstructorPattern (addRef p' qNilId) []
 >         cons p' t ts = ConstructorPattern (addRef p' qConsId) [t,ts]
 
@@ -334,13 +261,13 @@
 >   liftM (desugarAs p v) (desugarTerm m tcEnv p ds t)
 > desugarTerm m tcEnv p ds (LazyPattern pos t) = desugarLazy pos m p ds t
 > desugarTerm m tcEnv p ds (FunctionPattern f ts) =
->   liftM (apSnd (FunctionPattern f)) (mapAccumM (desugarTerm m tcEnv p) ds ts)
+>   liftM (second (FunctionPattern f)) (mapAccumM (desugarTerm m tcEnv p) ds ts)
 > desugarTerm m tcEnv p ds (InfixFuncPattern t1 f t2) =
 >   desugarTerm m tcEnv p ds (FunctionPattern f [t1,t2])
 > desugarTerm m tcEnv p ds (RecordPattern fs _)
 >   | null fs = internalError "desugarTerm: empty record"
 >   | otherwise =
->     do tyEnv <- fetchSt 
+>     do tyEnv <- S.get 
 >	 case (lookupValue (fieldLabel (head fs)) tyEnv) of
 >          [Label _ r _] -> 
 >            desugarRecordPattern m tcEnv p ds (map field2Tuple fs) r
@@ -363,7 +290,7 @@
 >     LazyPattern pos t' -> desugarLazy pos m p ds t'
 >     _ ->
 >       do
->         v0 <- fetchSt >>= freshIdent m "_#lazy" . monoType . flip typeOf t
+>         v0 <- S.get >>= freshIdent m "_#lazy" . monoType . flip typeOf t
 >         let v' = addPositionIdent (AST pos) v0
 >         return (patDecl p{ast=pos} t (mkVar v') : ds,VariablePattern v')
 
@@ -381,7 +308,7 @@
 > desugarRhs :: ModuleIdent -> TCEnv -> Position -> Rhs -> DesugarState Rhs
 > desugarRhs m tcEnv p rhs =
 >   do
->     tyEnv <- fetchSt
+>     tyEnv <- S.get
 >     e' <- desugarExpr m tcEnv p (expandRhs tyEnv prelFailed rhs)
 >     return (SimpleRhs p e' [])
 
@@ -431,7 +358,7 @@
 >   liftM (apply prelEnumFromThenTo) (mapM (desugarExpr m tcEnv p) [e1,e2,e3])
 > desugarExpr m tcEnv p (UnaryMinus op e) =
 >   do
->     tyEnv <- fetchSt
+>     tyEnv <- S.get
 >     liftM (Apply (unaryMinus op (typeOf tyEnv e))) (desugarExpr m tcEnv p e)
 >   where unaryMinus op ty
 >           | op == minusId =
@@ -440,7 +367,7 @@
 >           | otherwise = internalError "unaryMinus"
 > desugarExpr m tcEnv p (Apply (Constructor c) e) =
 >   do
->     tyEnv <- fetchSt
+>     tyEnv <- S.get
 >     liftM (if isNewtypeConstr tyEnv c then id else (Apply (Constructor c)))
 >           (desugarExpr m tcEnv p e)
 > desugarExpr m tcEnv p (Apply e1 e2) =
@@ -466,7 +393,7 @@
 >     return (Apply (Apply prelFlip op') e')
 > desugarExpr m tcEnv p exp@(Lambda r ts e) =
 >   do
->     f <- fetchSt >>=
+>     f <- S.get >>=
 >          freshIdent m "_#lambda" . polyType . flip typeOf exp
 >     desugarExpr m tcEnv p (Let [funDecl (AST r) f ts e] (mkVar f))
 > desugarExpr m tcEnv p (Let ds e) =
@@ -490,9 +417,9 @@
 >   | otherwise =
 >       do
 >         e' <- desugarExpr m tcEnv p e
->         v <- fetchSt >>= freshIdent m "_#case" . monoType . flip typeOf e
+>         v <- S.get >>= freshIdent m "_#case" . monoType . flip typeOf e
 >         alts' <- mapM (desugarAltLhs m tcEnv) alts
->         tyEnv <- fetchSt
+>         tyEnv <- S.get
 >         alts'' <- mapM (desugarAltRhs m tcEnv)
 >                        (map (expandAlt tyEnv v) (init (tails alts')))
 >         return (mkCase m v e' alts'')
@@ -504,12 +431,12 @@
 >   | otherwise =
 >       do let l = fieldLabel (head fs)
 >	       fs' = map field2Tuple fs
->          tyEnv <- fetchSt
+>          tyEnv <- S.get
 >	   case (lookupValue l tyEnv) of
 >            [Label l' r _] -> desugarRecordConstr m tcEnv p r fs'
 >            _  -> internalError "desugarExpr: illegal record construction"
 > desugarExpr m tcEnv p (RecordSelection e l) =
->   do tyEnv <- fetchSt
+>   do tyEnv <- S.get
 >      case (lookupValue l tyEnv) of
 >        [Label _ r _] -> desugarRecordSelection m tcEnv p r l e
 >        _ -> internalError "desugarExpr: illegal record selection"
@@ -518,7 +445,7 @@
 >   | otherwise =
 >       do let l = fieldLabel (head fs)
 >	       fs' = map field2Tuple fs
->          tyEnv <- fetchSt
+>          tyEnv <- S.get
 >	   case (lookupValue l tyEnv) of
 >            [Label _ r _] -> desugarRecordUpdate m tcEnv p r rexpr fs'
 >            _  -> internalError "desugarExpr: illegal record update"
@@ -582,14 +509,14 @@
 > desugarRecordDecl m tcEnv (TypeDecl p r vs (RecordType fss _)) =
 >   case (qualLookupTC r' tcEnv) of
 >     [AliasType _ n (TypeRecord fs' _)] ->
->       do tyEnv <- fetchSt
+>       do tyEnv <- S.get
 >	   let tys = concatMap (\ (ls,ty) -> replicate (length ls) ty) fss
 >	       --tys' = map (elimRecordTypes tyEnv) tys
 >	       rdecl = DataDecl p r vs [ConstrDecl p [] r tys]
 >	       rty' = TypeConstructor r' (map TypeVariable [0 .. n-1])
 >              rcts' = ForAllExist 0 n (foldr TypeArrow rty' (map snd fs'))
 >	   rfuncs <- mapM (genRecordFuncs m tcEnv p r' rty' (map fst fs')) fs'
->	   updateSt_ (bindGlobalInfo DataConstructor m r rcts')
+>	   S.modify (bindGlobalInfo DataConstructor m r rcts')
 >          return (rdecl:(concat rfuncs))
 >     _ -> internalError "desugarRecordDecl: no record"
 >   where r' = qualifyWith m r
@@ -637,7 +564,7 @@
 > elimFunctionPattern m p [] = return ([],[])
 > elimFunctionPattern m p (t:ts)
 >    | containsFunctionPattern t
->      = do tyEnv <- fetchSt
+>      = do tyEnv <- S.get
 >	    ident <- freshIdent m "_#funpatt" (monoType (typeOf tyEnv t))
 >	    (ts',its') <- elimFunctionPattern m p ts
 >           return ((VariablePattern ident):ts', (ident,t):its')
@@ -734,7 +661,7 @@
 >              (updId, updFunc) = genUpdateFunc m p r ls l
 >	       selType = polyType (TypeArrow rty ty)
 >	       updType = polyType (TypeArrow rty (TypeArrow ty rty))
->	   updateSt_ (bindFun m selId selType . bindFun m updId updType)
+>	   S.modify (bindFun m selId selType . bindFun m updId updType)
 >	   return [selFunc,updFunc]
 >     _ -> internalError "genRecordFuncs: wrong type"
 
@@ -805,7 +732,7 @@
 >   | isVarPattern t = desugarExpr m tcEnv p (qualExpr t e l)
 >   | otherwise =
 >       do
->         tyEnv <- fetchSt
+>         tyEnv <- S.get
 >         v0 <- freshIdent m "_#var" (monoType (typeOf tyEnv t))
 >         l0 <- freshIdent m "_#var" (monoType (typeOf tyEnv e))
 >         let v  = addRefId refBind v0
@@ -835,8 +762,8 @@
 > freshIdent :: ModuleIdent -> String -> TypeScheme -> DesugarState Ident
 > freshIdent m prefix ty =
 >   do
->     x <- liftM (mkName prefix) (liftSt (updateSt (1 +)))
->     updateSt_ (bindFun m x ty)
+>     x <- liftM (mkName prefix) (S.lift (S.modify succ >> S.get))
+>     S.modify (bindFun m x ty)
 >     return x
 >   where mkName pre n = mkIdent (pre ++ show n)
 
@@ -844,7 +771,6 @@
 Prelude entities
 \begin{verbatim}
 
-> prelUnif = Variable $ preludeIdent "=:="
 > prelBind = prel ">>="
 > prelBind_ = prel ">>"
 > prelFlip = Variable $ preludeIdent "flip"
@@ -867,7 +793,7 @@
 
 > truePattern = ConstructorPattern qTrueId []
 > falsePattern = ConstructorPattern qFalseId []
-> successPattern = ConstructorPattern (qualify successId) []
+
 
 > preludeIdent :: String -> QualIdent
 > preludeIdent = qualifyWith preludeMIdent . mkIdent
diff --git a/src/Env.lhs b/src/Env.lhs
deleted file mode 100644
--- a/src/Env.lhs
+++ /dev/null
@@ -1,55 +0,0 @@
-% -*- LaTeX -*-
-% $Id: Env.lhs,v 1.9 2002/12/20 15:07:56 lux Exp $
-%
-% Copyright (c) 2002, Wolfgang Lux
-% See LICENSE for the full license.
-%
-\nwfilename{Env.lhs}
-\section{Environments}
-The module \texttt{Env} implements environments. An environment
-$\rho = \left\{x_1\mapsto t_1,\dots,x_n\mapsto t_n\right\}$ is a
-finite mapping from (finitely many) variables $x_1,\dots,x_n$ to
-some kind of expression or term. For any environment we have the
-following definitions:
-\begin{displaymath}
-  \begin{array}{l}
-    \rho(x) = \left\{\begin{array}{ll}
-        t_i&\mbox{if $x=x_i$}\\
-        \bot&\mbox{otherwise}\end{array}\right. \\
-    \mathop{{\mathcal D}om}(\rho) = \left\{x_1,\dots,x_n\right\} \\
-    \mathop{{\mathcal C}odom}(\rho) = \left\{t_1,\dots,t_n\right\}
-  \end{array}
-\end{displaymath}
-
-Unfortunately we cannot define \texttt{Env} as a \texttt{newtype}
-because of a bug in the nhc compiler.
-\begin{verbatim}
-
-> module Env where
-
-> import qualified Data.Map as Map
-
-> newtype Env a b = Env (Map.Map a b) deriving Show
-
-> emptyEnv :: Ord a => Env a b
-> emptyEnv = Env Map.empty
-
-> envToList :: Ord v => Env v e -> [(v,e)]
-> envToList (Env rho) = Map.toList rho
-
-> bindEnv :: Ord v => v -> e -> Env v e -> Env v e
-> bindEnv v e (Env rho) = Env (Map.insert v e rho)
-
-> unbindEnv :: Ord v => v -> Env v e -> Env v e
-> unbindEnv v (Env rho) = Env (Map.delete v rho)
-
-> lookupEnv :: Ord v => v -> Env v e -> Maybe e
-> lookupEnv v (Env rho) = Map.lookup v rho
-
-> envSize :: Ord v => Env v e -> Int
-> envSize (Env rho) = Map.size rho
-
-> instance Ord a => Functor (Env a) where
->   fmap f (Env rho) = Env (fmap f rho)
-
-\end{verbatim}
diff --git a/src/Error.lhs b/src/Error.lhs
deleted file mode 100644
--- a/src/Error.lhs
+++ /dev/null
@@ -1,35 +0,0 @@
-% -*- LaTeX -*-
-% $Id: Error.lhs,v 1.1 2003/05/07 22:38:42 wlux Exp $
-%
-% Copyright (c) 2003, Wolfgang Lux
-% See LICENSE for the full license.
-%
-\nwfilename{Error.lhs}
-\section{Errors}\label{sec:error}
-The \texttt{Error} type is used for describing the result of a
-computation that can fail. In contrast to the standard \texttt{Maybe}
-type, its \texttt{Error} case provides for an error message that
-describes the failure.
-\begin{verbatim}
-
-> module Error where
-> import Control.Monad
-
-> data Error a = Ok a | Error String deriving (Eq,Ord,Show)
-
-> instance Functor Error where
->   fmap f (Ok x) = Ok (f x)
->   fmap f (Error e) = Error e
-
-> instance Monad Error where
->   return x = Ok x
->   fail s = Error s
->   Ok x >>= f = f x
->   Error e >>= _ = Error e
-
-> ok :: Error a -> a
-> ok (Ok x) = x
-> ok (Error e) = error e
-
-
-\end{verbatim}
diff --git a/src/Eval.lhs b/src/Eval.lhs
--- a/src/Eval.lhs
+++ b/src/Eval.lhs
@@ -11,24 +11,24 @@
 happens already while checking the definitions of the module.
 \begin{verbatim}
 
-> module Eval(evalEnv,evalEnvGoal) where
+> module Eval(evalEnv) where
+
+> import qualified Data.Map as Map
+
+> import Curry.Syntax
 > import Base
-> import Env
 
+
 \end{verbatim}
 The function \texttt{evalEnv} collects all evaluation annotations of
 the module by traversing the syntax tree.
 \begin{verbatim}
 
 > evalEnv :: [Decl] -> EvalEnv
-> evalEnv = foldr collectAnnotsDecl emptyEnv
-
-> evalEnvGoal :: Goal -> EvalEnv
-> evalEnvGoal (Goal _ e ds) =
->   collectAnnotsExpr e (foldr collectAnnotsDecl emptyEnv ds)
+> evalEnv = foldr collectAnnotsDecl Map.empty
 
 > collectAnnotsDecl :: Decl -> EvalEnv -> EvalEnv
-> collectAnnotsDecl (EvalAnnot _ fs ev) env = foldr (flip bindEval ev) env fs
+> collectAnnotsDecl (EvalAnnot _ fs ev) env = foldr (flip Map.insert ev) env fs
 > collectAnnotsDecl (FunctionDecl _ _ eqs) env = foldr collectAnnotsEqn env eqs
 > collectAnnotsDecl (PatternDecl _ _ rhs) env = collectAnnotsRhs rhs env
 > collectAnnotsDecl _ env = env
diff --git a/src/Exports.lhs b/src/Exports.lhs
--- a/src/Exports.lhs
+++ b/src/Exports.lhs
@@ -19,6 +19,10 @@
 > import qualified Data.Set as Set
 > import qualified Data.Map as Map
 
+> import Curry.Syntax
+> import Types
+> import Curry.Base.Position
+> import Curry.Base.Ident
 > import Base
 > import TopEnv
 
@@ -40,7 +44,7 @@
 >     Linear ->
 >       case linear ([c | ExportTypeWith _ cs <- es', c <- cs] ++
 >                    [unqualify f | Export f <- es']) of
->         Linear -> Module m (Just (Exporting noPos es')) ds
+>         Linear -> Module m (Just (Exporting NoPos es')) ds
 >         NonLinear v -> errorAt' (ambiguousExportValue v)
 >     NonLinear tc -> errorAt' (ambiguousExportType tc) 
 >   where ms = Set.fromList [fromMaybe m asM | ImportDecl _ m _ asM _ <- ds]
@@ -197,7 +201,7 @@
 > exportInterface :: Module -> PEnv -> TCEnv -> ValueEnv -> Interface
 > exportInterface (Module m (Just (Exporting _ es)) _) pEnv tcEnv tyEnv =
 >   Interface m (imports ++ precs ++ hidden ++ ds)
->   where imports = map (IImportDecl noPos) (usedModules ds)
+>   where imports = map (IImportDecl NoPos) (usedModules ds)
 >         precs = foldr (infixDecl m pEnv) [] es
 >         hidden = map (hiddenTypeDecl m tcEnv) (hiddenTypes ds)
 >         ds = foldr (typeDecl m tcEnv) (foldr (funDecl m tyEnv) [] es) es
@@ -206,7 +210,7 @@
 > infixDecl :: ModuleIdent -> PEnv -> Export -> [IDecl] -> [IDecl]
 > infixDecl m pEnv (Export f) ds = iInfixDecl m pEnv f ds
 > infixDecl m pEnv (ExportTypeWith tc cs) ds =
->   foldr (iInfixDecl m pEnv . qualifyLike (fst (splitQualIdent tc))) ds cs
+>   foldr (iInfixDecl m pEnv . qualifyLike (qualidMod tc)) ds cs
 >   where qualifyLike = maybe qualify qualifyWith
 
 > iInfixDecl :: ModuleIdent -> PEnv -> QualIdent -> [IDecl] -> [IDecl]
@@ -214,7 +218,7 @@
 >   case qualLookupP op pEnv of
 >     [] -> ds
 >     [PrecInfo _ (OpPrec fix pr)] ->
->       IInfixDecl noPos fix pr (qualUnqualify m op) : ds
+>       IInfixDecl NoPos fix pr (qualUnqualify m op) : ds
 >     _ -> internalError "infixDecl"
 
 > typeDecl :: ModuleIdent -> TCEnv -> Export -> [IDecl] -> [IDecl]
@@ -226,7 +230,7 @@
 >          (constrDecls m (drop n nameSupply) cs cs') : ds
 >     [RenamingType tc n (Data c n' ty)]
 >       | c `elem` cs ->
->           iTypeDecl INewtypeDecl m tc n (NewConstrDecl noPos tvs c ty') : ds
+>           iTypeDecl INewtypeDecl m tc n (NewConstrDecl NoPos tvs c ty') : ds
 >       | otherwise -> iTypeDecl IDataDecl m tc n [] : ds
 >       where tvs = take n' (drop n nameSupply)
 >             ty' = fromQualType m ty
@@ -240,7 +244,7 @@
 
 > iTypeDecl :: (Position -> QualIdent -> [Ident] -> a -> IDecl)
 >            -> ModuleIdent -> QualIdent -> Int -> a -> IDecl
-> iTypeDecl f m tc n = f noPos (qualUnqualify m tc) (take n nameSupply)
+> iTypeDecl f m tc n = f NoPos (qualUnqualify m tc) (take n nameSupply)
 
 > constrDecls :: ModuleIdent -> [Ident] -> [Ident] -> [Maybe (Data [Type])]
 >             -> [Maybe ConstrDecl]
@@ -253,14 +257,14 @@
 
 > iConstrDecl :: [Ident] -> Ident -> [TypeExpr] -> ConstrDecl
 > iConstrDecl tvs op [ty1,ty2]
->   | isInfixOp op = ConOpDecl noPos tvs ty1 op ty2
-> iConstrDecl tvs c tys = ConstrDecl noPos tvs c tys
+>   | isInfixOp op = ConOpDecl NoPos tvs ty1 op ty2
+> iConstrDecl tvs c tys = ConstrDecl NoPos tvs c tys
 
 > funDecl :: ModuleIdent -> ValueEnv -> Export -> [IDecl] -> [IDecl]
 > funDecl m tyEnv (Export f) ds =
 >   case qualLookupValue f tyEnv of
 >     [Value _ (ForAll _ ty)] ->
->       IFunctionDecl noPos (qualUnqualify m f) (arrowArity ty) 
+>       IFunctionDecl NoPos (qualUnqualify m f) (arrowArity ty) 
 >		  (fromQualType m ty) : ds
 >     _ -> internalError ("funDecl: " ++ show f)
 > funDecl _ _ (ExportTypeWith _ _) ds = ds
@@ -286,9 +290,8 @@
 \begin{verbatim}
 
 > usedModules :: [IDecl] -> [ModuleIdent]
-> usedModules ds = nub (catMaybes (map modul (foldr identsDecl [] ds)))
+> usedModules ds = nub (catMaybes (map qualidMod (foldr identsDecl [] ds)))
 >   where nub = Set.toList . Set.fromList
->         modul = fst . splitQualIdent
 
 > identsDecl :: IDecl -> [QualIdent] -> [QualIdent]
 > identsDecl (IDataDecl _ tc _ cs) xs =
@@ -329,7 +332,7 @@
 >     [RenamingType _ n _] -> hidingDataDecl tc n
 >     _ ->  internalError "hiddenTypeDecl"
 >   where hidingDataDecl tc n =
->           HidingDataDecl noPos (unqualify tc) (take n nameSupply)
+>           HidingDataDecl NoPos (unqualify tc) (take n nameSupply)
 
 > hiddenTypes :: [IDecl] -> [QualIdent]
 > hiddenTypes ds = [tc | tc <- Set.toList tcs, not (isQualified tc)]
diff --git a/src/ExtendedFlat.hs b/src/ExtendedFlat.hs
deleted file mode 100644
--- a/src/ExtendedFlat.hs
+++ /dev/null
@@ -1,517 +0,0 @@
-------------------------------------------------------------------------------
---- Library to support meta-programming in Curry.
----
---- This library contains a definition for representing FlatCurry programs
---- in Haskell (type "Prog").
----
---- @author Michael Hanus
---- @version September 2003
----
---- Version for Haskell (slightly modified):
----  December 2004, Martin Engelke (men@informatik.uni-kiel.de)
----
---- Added part calls for constructors, Bernd Brassel, August 2005
---- Added source references, Bernd Brassel, May 2009
-------------------------------------------------------------------------------
-
-{-# LANGUAGE DeriveDataTypeable, RankNTypes #-}
-
-module ExtendedFlat (SrcRef,Prog(..), QName(..), Visibility(..),
-                  TVarIndex, TypeDecl(..), ConsDecl(..), TypeExpr(..),
-                  OpDecl(..), Fixity(..),
-                  VarIndex(..), 
-                  FuncDecl(..), Rule(..), 
-                  CaseType(..), CombType(..), Expr(..), BranchExpr(..),
-                  Pattern(..), Literal(..), 
-		  readFlatCurry, readFlatInterface, readFlat, 
-		  writeFlatCurry,writeExtendedFlat,gshowsPrec,
-                  qnOf,mkQName,
-                  mkIdx,idxOf) where
-
-import PathUtils (writeModule,maybeReadModule)
-import Data.List(intersperse)
-import Control.Monad (liftM)
-import Data.Generics hiding (Fixity)
-import Position (SrcRef)
-import System.FilePath
-
-
-------------------------------------------------------------------------------
--- Definition of data types for representing FlatCurry programs:
--- =============================================================
-
---- Data type for representing a Curry module in the intermediate form.
---- A value of this data type has the form
---- <CODE>
----  (Prog modname imports typedecls functions opdecls translation_table)
---- </CODE>
---- where modname: name of this module,
----       imports: list of modules names that are imported,
----       typedecls, opdecls, functions, translation of type names
----       and constructor/function names: see below
-
-data Prog = Prog String [String] [TypeDecl] [FuncDecl] [OpDecl] 
-	    deriving (Read, Show, Eq,Data,Typeable)
-
-
--------------------------------------------------------------------------
---- The data type for representing qualified names.
---- In FlatCurry all names are qualified to avoid name clashes.
---- The first component is the module name and the second component the
---- unqualified name as it occurs in the source program.
---- The additional information about source references and types should
---- be invisible for the normal usage of QName.
--------------------------------------------------------------------------
-
-data QName = QName {srcRef      :: Maybe SrcRef,
-                    typeofQName :: Maybe TypeExpr,
-                    modName     :: String,
-                    localName   :: String} deriving (Data,Typeable)
-
-
-app_prec = 10
-hi_prec  = app_prec+1
-
-instance Read QName where
-  readsPrec d r = 
-       [ (mkQName nm,s) | (nm,s) <- readsPrec d r ]
-    ++ readParen (d > app_prec) 
-                 (\r' -> [ (QName ref typ n m,res) 
-                               | ("QName",s0) <- lex r',
-                                 (ref,s1) <- readsPrec hi_prec s0,
-                                 (typ,s2) <- readsPrec hi_prec s1,
-                                 (n,s3)   <- readsPrec hi_prec s2,
-                                 (m,res)  <- readsPrec hi_prec s3 ]) r
-    
-
-instance Show QName where
-  showsPrec d (QName r t m n)= 
-    showParen (d > app_prec) $ showString "QName " .
-                     showsPrec hi_prec r . showChar ' ' .
-                     showsPrec hi_prec t . showChar ' ' .
-                     showsPrec hi_prec m . showChar ' ' .
-                     showsPrec hi_prec n
-
-instance Eq QName where (==) = onName (==)
-instance Ord QName where compare = onName compare
-
-mkQName :: (String,String) -> QName
-mkQName = uncurry (QName Nothing Nothing)
-
-qnOf :: QName -> (String,String) 
-qnOf QName{modName=m,localName=n} = (m,n)
-
-onName :: ((String,String) -> (String,String) -> a) -> QName -> QName -> a
-onName f QName{modName=m,localName=l} QName{modName=m',localName=l'} =
-  f (m,l) (m',l')
-
-
--------------------------------------------------------------------------
---- The data type for representing variable names.
---- The additional information should
---- be invisible for the normal usage of VarIndex.
--------------------------------------------------------------------------
-
-data VarIndex = VarIndex {
-                    typeofVar :: Maybe TypeExpr,
-                    index     :: Int
-                } deriving (Data,Typeable)
-
-onIndex :: (Int -> a) -> VarIndex -> a
-onIndex f VarIndex{index=i} = f i
-
-(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
-f .: g = \x -> f . g x
-
-onIndexes :: (Int -> Int -> a) -> VarIndex -> VarIndex -> a
-onIndexes = onIndex .: onIndex
-
-mkIdx :: Int -> VarIndex
-mkIdx = VarIndex Nothing
-
-idxOf :: VarIndex -> Int
-idxOf VarIndex{index=i}= i
-
-instance Read VarIndex where
-  readsPrec d r = 
-       [ (mkIdx i,s) | (i,s) <- readsPrec d r ]
-    ++ readParen (d > app_prec) 
-                 (\r' -> [ (VarIndex typ i,res) 
-                         | ("VarIndex",s0) <- lex r',
-                           (typ,s1) <- readsPrec hi_prec s0,
-                           (i,res)  <- readsPrec hi_prec s1]) r
-    
-
-instance Show VarIndex where
-  showsPrec d (VarIndex t i)= 
-    showParen (d > app_prec) $ showString "VarIndex " .
-                     showsPrec hi_prec t . showChar ' ' .
-                     showsPrec hi_prec i
-
-
-instance Eq VarIndex where (==) = onIndexes (==)
-instance Ord VarIndex where compare = onIndexes compare
-
-instance Num VarIndex where
-  (+) = mkIdx .: onIndexes (+)
-  (*) = mkIdx .: onIndexes (*)
-  (-) = mkIdx .: onIndexes (-)
-  abs = mkIdx .  onIndex abs
-  signum = mkIdx .  onIndex signum
-  fromInteger = mkIdx . fromInteger
-
-------------------------------------------------------------
---- Data type to specify the visibility of various entities.
-------------------------------------------------------------
-
-data Visibility = Public    -- public (exported) entity
-                | Private   -- private entity
-		deriving (Read, Show, Eq,Data,Typeable)
-
---- The data type for representing type variables.
---- They are represented by (TVar i) where i is a type variable index.
-
-type TVarIndex = Int
-
---- Data type for representing definitions of algebraic data types.
---- <PRE>
---- A data type definition of the form
----
---- data t x1...xn = ...| c t1....tkc |...
----
---- is represented by the FlatCurry term
----
---- (Type t [i1,...,in] [...(Cons c kc [t1,...,tkc])...])
----
---- where each ij is the index of the type variable xj
----
---- Note: the type variable indices are unique inside each type declaration
----       and are usually numbered from 0
----
---- Thus, a data type declaration consists of the name of the data type,
---- a list of type parameters and a list of constructor declarations.
---- </PRE>
-
-data TypeDecl = Type    QName Visibility [TVarIndex] [ConsDecl]
-              | TypeSyn QName Visibility [TVarIndex] TypeExpr
-	      deriving (Read, Show, Eq,Data,Typeable)
-
---- A constructor declaration consists of the name and arity of the
---- constructor and a list of the argument types of the constructor.
-
-data ConsDecl = Cons QName Int Visibility [TypeExpr]
-	      deriving (Read, Show, Eq,Data,Typeable)
-
-
---- Data type for type expressions.
---- A type expression is either a type variable, a function type,
---- or a type constructor application.
----
---- Note: the names of the predefined type constructors are
----       "Int", "Float", "Bool", "Char", "IO", "Success",
----       "()" (unit type), "(,...,)" (tuple types), "[]" (list type)
-
-data TypeExpr =
-     TVar TVarIndex                 -- type variable
-   | FuncType TypeExpr TypeExpr     -- function type t1->t2
-   | TCons QName [TypeExpr]         -- type constructor application
-   deriving (Read, Show, Eq,Data,Typeable)            --    TCons module name typeargs
-
-
---- Data type for operator declarations.
---- An operator declaration "fix p n" in Curry corresponds to the
---- FlatCurry term (Op n fix p).
---- Note: the constructor definition of 'Op' differs from the original
---- PAKCS definition using Haskell type 'Integer' instead of 'Int'
---- for representing the precedence. 
-
-data OpDecl = Op QName Fixity Integer deriving (Read, Show, Eq,Data,Typeable)
-
---- Data types for the different choices for the fixity of an operator.
-
-data Fixity = InfixOp | InfixlOp | InfixrOp deriving (Read, Show, Eq,Data,Typeable)
-
-
---- Data type for representing object variables.
---- Object variables occurring in expressions are represented by (Var i)
---- where i is a variable index.
-
---- Data type for representing function declarations.
---- <PRE>
---- A function declaration in FlatCurry is a term of the form
----
----  (Func name arity type (Rule [i_1,...,i_arity] e))
----
---- and represents the function "name" with definition
----
----   name :: type
----   name x_1...x_arity = e
----
---- where each i_j is the index of the variable x_j
----
---- Note: the variable indices are unique inside each function declaration
----       and are usually numbered from 0
----
---- External functions are represented as (Func name arity type (External s))
---- where s is the external name associated to this function.
----
---- Thus, a function declaration consists of the name, arity, type, and rule.
---- </PRE>
-
-data FuncDecl = Func QName Int Visibility TypeExpr Rule
-	      deriving (Read, Show, Eq,Data,Typeable)
-
-
---- A rule is either a list of formal parameters together with an expression
---- or an "External" tag.
-
-data Rule = Rule [VarIndex] Expr
-          | External String
-	  deriving (Read, Show, Eq,Data,Typeable)
-
---- Data type for classifying case expressions.
---- Case expressions can be either flexible or rigid in Curry.
-
-data CaseType = Rigid | Flex deriving (Read, Show, Eq,Data,Typeable)
-
---- Data type for classifying combinations
---- (i.e., a function/constructor applied to some arguments).
---- @cons FuncCall     - a call to a function all arguments are provided
---- @cons ConsCall     - a call with a constructor at the top,
----                      all arguments are provided
---- @cons FuncPartCall - a partial call to a function
----                      (i.e., not all arguments are provided) 
----                      where the parameter is the number of
----                      missing arguments
---- @cons ConsPartCall - a partial call to a constructor along with 
----                      number of missing arguments
-
-data CombType = FuncCall 
-              | ConsCall 
-              | FuncPartCall Int 
-              | ConsPartCall Int deriving (Read, Show, Eq,Data,Typeable)
-
---- Data type for representing expressions.
----
---- Remarks:
---- <PRE>
---- 1. if-then-else expressions are represented as function calls:
----      (if e1 then e2 else e3)
----    is represented as
----      (Comb FuncCall ("Prelude","if_then_else") [e1,e2,e3])
---- 
---- 2. Higher order applications are represented as calls to the (external)
----    function "apply". For instance, the rule
----      app f x = f x
----    is represented as
----      (Rule  [0,1] (Comb FuncCall ("Prelude","apply") [Var 0, Var 1]))
---- 
---- 3. A conditional rule is represented as a call to an external function
----    "cond" where the first argument is the condition (a constraint).
----    For instance, the rule
----      equal2 x | x=:=2 = success
----    is represented as
----      (Rule [0]
----            (Comb FuncCall ("Prelude","cond")
----                  [Comb FuncCall ("Prelude","=:=") [Var 0, Lit (Intc 2)],
----                   Comb FuncCall ("Prelude","success") []]))
---- 
---- 4. Functions with evaluation annotation "choice" are represented
----    by a rule whose right-hand side is enclosed in a call to the
----    external function "Prelude.commit".
----    Furthermore, all rules of the original definition must be
----    represented by conditional expressions (i.e., (cond [c,e]))
----    after pattern matching.
----    Example:
---- 
----       m eval choice
----       m [] y = y
----       m x [] = x
---- 
----    is translated into (note that the conditional branches can be also
----    wrapped with Free declarations in general):
---- 
----       Rule [0,1]
----            (Comb FuncCall ("Prelude","commit")
----              [Or (Case Rigid (Var 0)
----                     [(Pattern ("Prelude","[]") []
----                         (Comb FuncCall ("Prelude","cond")
----                               [Comb FuncCall ("Prelude","success") [],
----                                Var 1]))] )
----                  (Case Rigid (Var 1)
----                     [(Pattern ("Prelude","[]") []
----                         (Comb FuncCall ("Prelude","cond")
----                               [Comb FuncCall ("Prelude","success") [],
----                                Var 0]))] )])
---- 
----    Operational meaning of (Prelude.commit e):
----    evaluate e with local search spaces and commit to the first
----    (Comb FuncCall ("Prelude","cond") [c,ge]) in e whose constraint c
----    is satisfied
---- </PRE>
---- @cons Var - variable (represented by unique index)
---- @cons Lit - literal (Integer/Float/Char constant)
---- @cons Comb - application (f e1 ... en) of function/constructor f
----              with n<=arity(f)
---- @cons Free - introduction of free local variables
---- @cons Or - disjunction of two expressions (used to translate rules
----            with overlapping left-hand sides)
---- @cons Case - case distinction (rigid or flex)
-
-data Expr = Var VarIndex 
-          | Lit Literal
-          | Comb CombType QName [Expr]
-          | Free [VarIndex] Expr
-          | Let [(VarIndex,Expr)] Expr
-          | Or Expr Expr
-          | Case SrcRef CaseType Expr [BranchExpr]
-	  deriving (Read, Show, Eq,Data,Typeable)
-
-
---- Data type for representing branches in a case expression.
---- <PRE>
---- Branches "(m.c x1...xn) -> e" in case expressions are represented as
----
----   (Branch (Pattern (m,c) [i1,...,in]) e)
----
---- where each ij is the index of the pattern variable xj, or as
----
----   (Branch (LPattern (Intc i)) e)
----
---- for integers as branch patterns (similarly for other literals
---- like float or character constants).
---- </PRE>
-
-data BranchExpr = Branch Pattern Expr deriving (Read, Show, Eq,Data,Typeable)
-
---- Data type for representing patterns in case expressions.
-
-data Pattern = Pattern QName [VarIndex]
-             | LPattern Literal
-	     deriving (Read, Show, Eq,Data,Typeable)
-
---- Data type for representing literals occurring in an expression
---- or case branch. It is either an integer, a float, or a character constant.
---- Note: the constructor definition of 'Intc' differs from the original
---- PAKCS definition. It uses Haskell type 'Integer' instead of 'Int'
---- to provide an unlimited range of integer numbers. Furthermore
---- float values are represented with Haskell type 'Double' instead of
---- 'Float'.
-
-data Literal = Intc   SrcRef Integer
-             | Floatc SrcRef Double
-             | Charc  SrcRef Char
-	     deriving (Read, Show, Eq,Data,Typeable)
-
-
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-
--- Reads a FlatCurry file (extension ".fcy") and returns the corresponding
--- FlatCurry program term (type 'Prog') as a value of type 'Maybe'.
-readFlatCurry :: FilePath -> IO (Maybe Prog)
-readFlatCurry fn 
-   = do let filename = genFlatFilename ".fcy" fn
-        readFlat filename
-
--- Reads a FlatInterface file (extension ".fint") and returns the
--- corresponding term (type 'Prog') as a value of type 'Maybe'.
-readFlatInterface :: String -> IO (Maybe Prog)
-readFlatInterface fn
-   = do let filename = genFlatFilename ".fint" fn
-        readFlat filename
-
--- Reads a Flat file and returns the corresponding term (type 'Prog') as
--- a value of type 'Maybe'.
-readFlat :: FilePath -> IO (Maybe Prog)
-readFlat = liftM (fmap read) . maybeReadModule
-  
--- Writes a FlatCurry program term into a file.
-writeFlatCurry :: String -> Prog -> IO ()
-writeFlatCurry filename prog
-   = writeModule filename (showFlatCurry' False prog)
-
--- Writes a FlatCurry program term with source references into a file.
-writeExtendedFlat :: String -> Prog -> IO ()
-writeExtendedFlat filename prog =
-  writeModule (replaceExtension filename ".efc") (showFlatCurry' True prog)
-
--- Shows FlatCurry program in a more nicely way.
-showFlatCurry :: Prog -> String
-showFlatCurry (Prog mname imps types funcs ops) =
-  "Prog "++show mname++"\n "++
-  show imps ++"\n ["++
-  concat (intersperse ",\n  " (map (\t->show t) types)) ++"]\n ["++
-  concat (intersperse ",\n  " (map (\f->show f) funcs)) ++"]\n "++
-  show ops ++"\n"
-  
-
--- Add the extension 'ext' to the filename 'fn' if it doesn't
--- already exist.
-genFlatFilename :: String -> FilePath -> FilePath
-genFlatFilename ext fn
-   | drop (length fn - length ext) fn == ext
-     = fn
-   | otherwise
-     = fn ++ ext
-
-showFlatCurry' :: Bool -> Prog -> String
-showFlatCurry' b x = gshowsPrec b False x ""
-
-gshowsPrec :: Data a => Bool -> Bool -> a -> ShowS
-gshowsPrec showType d = 
-  genericShowsPrec d `ext1Q` showsList
-                     `ext2Q` showsTuple
-                     `extQ`  (const id :: SrcRef -> ShowS)
-                     `extQ`  (const id :: [SrcRef] -> ShowS)
-                     `extQ`  (shows :: String -> ShowS)
-                     `extQ`  (shows :: Char -> ShowS)
-                     `extQ`  showsQName d
-                     `extQ`  showsVarIndex d
-                                      
-      where
-        showsQName :: Bool -> QName -> ShowS
-        showsQName d qn@QName{modName=m,localName=n,typeofQName=t} = 
-          if showType then showParen d (shows qn{srcRef=Nothing})
-                      else shows (m,n)
-
-        showsVarIndex :: Bool -> VarIndex -> ShowS
-        showsVarIndex d v@VarIndex{index=i} = 
-          if showType then showParen d (shows v)
-                      else shows i
-
-        genericShowsPrec :: Data a => Bool -> a -> ShowS
-        genericShowsPrec d t = let args = intersperse (showChar ' ') $
-                                          gmapQ (gshowsPrec showType True) t in
-                               showParen (d && not (null args)) $
-                               showString (showConstr (toConstr t)) .
-                               (if null args then id else showChar ' ') .
-                               foldr (.) id args
-
-        showsList :: Data a => [a] -> ShowS
-        showsList xs = showChar '[' . 
-                       foldr (.) (showChar ']') 
-                             (intersperse (showChar ',') $ 
-                              map (gshowsPrec showType False) xs)
-                       
-
-        showsTuple :: (Data a,Data b) => (a,b) -> ShowS
-        showsTuple (x,y) = showChar '(' . 
-                           gshowsPrec showType False x . 
-                           showChar ',' .
-                           gshowsPrec showType False y .
-                           showChar ')' 
-
-
-newtype Q r a = Q (a -> r)
- 
-ext2Q :: (Data d, Typeable2 t) => (d -> q) -> 
-   (forall d1 d2. (Data d1, Data d2) => t d1 d2 -> q) -> d -> q
-ext2Q def ext arg =
-   case dataCast2 (Q ext) of
-     Just (Q ext') -> ext' arg
-     Nothing       -> def arg
-
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-
diff --git a/src/Frontend.hs b/src/Frontend.hs
--- a/src/Frontend.hs
+++ b/src/Frontend.hs
@@ -7,37 +7,27 @@
 -- December 2005,
 -- Martin Engelke (men@informatik.uni-kiel.de)
 --
-module Frontend (lex, parse, fullParse, typingParse, abstractIO, flatIO,
-		 Result(..), Message(..)
-		)where
+module Frontend (lex, parse, fullParse, typingParse)where
 
-import Data.List
 import Data.Maybe
-import Control.Monad
+import qualified Data.Map as Map
+import Control.Monad.Writer
+import Control.Monad.Error
 import Prelude hiding (lex)
 
 import Modules
 import CurryBuilder
 import CurryCompilerOpts
-import CurryParser
-import CurryLexer
-import GenAbstractCurry
-import GenFlatCurry
-import CaseCompletion
-import CurryDeps hiding (unlitLiterate)
-import qualified CurrySyntax as CS
-import qualified AbstractCurry as ACY
-import qualified ExtendedFlat as FCY
-import qualified Error as Err
-import CompilerResults
-import Message
-import CurryEnv
-import Unlit
-import Ident
-import Position
-import PathUtils
-import Env
+import Curry.Base.MessageMonad
+import qualified Curry.Syntax as CS
+import Curry.Syntax.Lexer
 
+import CurryDeps
+import Curry.Base.Ident
+import Curry.Base.Position
+import Filenames
+import PathUtils
+import Base(ModuleEnv)
 
 -------------------------------------------------------------------------------
 -------------------------------------------------------------------------------
@@ -45,18 +35,15 @@
 -- Returns the result of a lexical analysis of the source program 'src'.
 -- The result is a list of tuples consisting of a position and a token
 -- (see Modules "Position" and "CurryLexer")
-lex :: FilePath -> String -> Result [(Position,Token)]
-lex fn src = genToks (lexFile (first fn) src False [])
+lex :: FilePath -> String -> MsgMonad [(Position,Token)]
+lex fn src = lexFile (first fn) src False []
 
 
 -- Returns the result of a syntactical analysis of the source program 'src'.
 -- The result is the syntax tree of the program (type 'Module'; see Module
 -- "CurrySyntax").
-parse :: FilePath -> String -> Result CS.Module
-parse fn src = let (err, src') = unlitLiterate fn src
-	       in  if null err
-		   then genCurrySyntax fn (parseSource True fn src')
-		   else Failure [message_ Error err]
+parse :: FilePath -> String -> MsgMonad CS.Module
+parse fn src = CS.parseModule True fn src >>= genCurrySyntax fn
 
 
 -- Returns the syntax tree of the source program 'src' (type 'Module'; see
@@ -65,26 +52,25 @@
 -- searches for standard Curry libraries in the path defined in the
 -- environment variable "PAKCSLIBPATH". Additional search paths can
 -- be defined using the argument 'paths'.
-fullParse :: [FilePath] -> FilePath -> String -> IO (Result CS.Module)
-fullParse paths fn src =
-  genFullCurrySyntax simpleCheckModule paths	fn (parse fn src)
+fullParse :: [FilePath] -> FilePath -> String -> IO (MsgMonad CS.Module)
+fullParse paths fn src = -- liftM msgmonad2result $
+                         genFullCurrySyntax simpleCheckModule paths fn (parse fn src)
 
 -- Behaves like 'fullParse', but Returns the syntax tree of the source 
 -- program 'src' (type 'Module'; see Module "CurrySyntax") after inferring 
 -- the types of identifiers.
-typingParse :: [FilePath] -> FilePath -> String -> IO (Result CS.Module)
-typingParse paths fn src = 
-  genFullCurrySyntax checkModule paths fn (parse fn src)
+typingParse :: [FilePath] -> FilePath -> String -> IO (MsgMonad CS.Module)
+typingParse paths fn src = genFullCurrySyntax checkModule paths fn (parse fn src)
 
+{-
 -- Compiles the source programm 'src' to an AbstractCurry program.
 -- 'fullParse' always searches for standard Curry libraries in the path 
 -- defined in the environment variable "PAKCSLIBPATH". Additional search 
 -- paths can be defined using the argument 'paths'.
 -- Notes: Due to the lack of error handling in the current version of the
 -- front end, this function may fail when an error occurs
-abstractIO :: [FilePath] -> FilePath -> String -> IO (Result ACY.CurryProg)
-abstractIO paths fn src = 
-  genAbstractIO paths fn (parse fn src)
+abstractIO :: [FilePath] -> FilePath -> String -> IO (MsgMonad ACY.CurryProg)
+abstractIO paths fn src = genAbstractIO paths fn (parse fn src)
 
 -- Compiles the source program 'src' to a FlatCurry program.
 -- 'fullParse' always searches for standard Curry libraries in the path 
@@ -92,17 +78,9 @@
 -- paths can be defined using the argument 'paths'.
 -- Note: Due to the lack of error handling in the current version of the
 -- front end, this function may fail when an error occurs
-flatIO :: [FilePath] -> FilePath -> String -> IO (Result FCY.Prog)
-flatIO paths fn src = 
-  genFlatIO paths fn (parse fn src)
-
-
--------------------------------------------------------------------------------
--- Result handling
-
-data Result a = Result [Message] a | Failure [Message] deriving Show
-
--- See module "Message":
+flatIO :: [FilePath] -> FilePath -> String -> IO (MsgMonad FCY.Prog)
+flatIO paths fn src = genFlatIO paths fn (parse fn src)
+-}
 
 -------------------------------------------------------------------------------
 -------------------------------------------------------------------------------
@@ -118,52 +96,45 @@
 
 
 --
-genToks :: Err.Error [(Position,Token)] -> Result [(Position,Token)]
-genToks (Err.Ok toks)   = Result [] toks
-genToks (Err.Error err) = Failure [message_ Error err]
-
-
---
-genCurrySyntax :: FilePath -> Err.Error CS.Module -> Result (CS.Module)
-genCurrySyntax fn (Err.Ok mod)
-   = let mod'@(CS.Module mid _ _) = patchModuleId fn (importPrelude fn mod)
-     in  if isValidModuleId fn mid
-	 then Result [] mod'
-	 else Failure [message_ Error (err_invalidModuleName mid)]
-genCurrySyntax _ (Err.Error err)
-   = Failure [message_ Error err]
+genCurrySyntax :: FilePath -> CS.Module -> MsgMonad (CS.Module)
+genCurrySyntax fn mod
+    = let mod'@(CS.Module mid _ _) = patchModuleId fn (importPrelude fn mod)
+      in if isValidModuleId fn mid
+	 then return mod'
+	 else failWith $ err_invalidModuleName mid
 
 
 --
-genFullCurrySyntax check paths fn (Result msgs mod)
-   = do errs <- makeInterfaces paths mod
-	if null errs
-	   then do mEnv <- loadInterfaces paths mod
-		   (_, _, _, mod', _, msgs') <- check (opts paths) mEnv mod
-		   return (Result (msgs ++ msgs') mod')
-	   else return (Failure (msgs ++ map (message_ Error) errs))
-genFullCurrySyntax _ _ _ (Failure msgs) = return (Failure msgs)
+genFullCurrySyntax :: (Options -> Base.ModuleEnv -> CS.Module -> IO (t1, t2, t3, CS.Module, t4, [WarnMsg]))
+                   -> [FilePath] -> t -> MsgMonad CS.Module -> IO (MsgMonad CS.Module)
+genFullCurrySyntax check paths fn m
+   = runMsgIO m $ \mod -> do errs <- makeInterfaces paths mod
+	                     if null errs
+	                       then do mEnv <- loadInterfaces paths mod
+		                       (_, _, _, mod', _, msgs') <- check (opts paths) mEnv mod
+		                       return (tell msgs' >> return  mod')
+	                       else return (failWith (head errs))
 
 
---
-genAbstractIO :: [FilePath] -> FilePath -> Result CS.Module
-	      -> IO (Result ACY.CurryProg)
-genAbstractIO paths fn (Result msgs mod)
-   = do errs <- makeInterfaces paths mod
+{-
+genAbstractIO :: [FilePath] -> FilePath -> MsgMonad CS.Module
+	      -> IO (MsgMonad ACY.CurryProg)
+genAbstractIO paths fn m
+   = runMsgIO m $ \mod ->
+     do errs <- makeInterfaces paths mod
 	if null errs
 	   then do mEnv <- loadInterfaces paths mod
 		   (tyEnv, tcEnv, _, mod', _, msgs')
 		       <- simpleCheckModule (opts paths) mEnv mod
-		   return (Result (msgs ++ msgs') 
-			          (genTypedAbstract tyEnv tcEnv mod'))
-	   else return (Failure (msgs ++ map (message_ Error) errs))
-genAbstractIO _ _ (Failure msgs) = return (Failure msgs)
+		   return (tell msgs' >> return (genTypedAbstract tyEnv tcEnv mod'))
+	   else return (failWith $ head errs)
 
 
 --
-genFlatIO :: [FilePath] -> FilePath -> Result CS.Module -> IO (Result FCY.Prog)
-genFlatIO paths fn (Result msgs mod)
-   = do errs <- makeInterfaces paths mod
+genFlatIO :: [FilePath] -> FilePath -> MsgMonad CS.Module -> IO (MsgMonad FCY.Prog)
+genFlatIO paths fn m
+   = runMsgIO m $ \ mod -> 
+     do errs <- makeInterfaces paths mod
 	if null errs then
 	   (do mEnv <- loadInterfaces paths mod
 	       (tyEnv, tcEnv, aEnv, mod', intf, msgs') <- 
@@ -174,10 +145,10 @@
 	           cEnv = curryEnv mEnv tcEnv intf mod'
 	           (prog,msgs'') = genFlatCurry (opts paths) cEnv mEnv 
 	                                        tyEnv tcEnv aEnv' il'
-               return (Result (msgs'' ++ msgs ++ msgs') prog)
+               return (tell msgs'' >> tell msgs' >> return prog)
 	   )
-	   else return (Failure (msgs ++ map (message_ Error) errs))
-genFlatIO _ _ (Failure msgs) = return (Failure msgs)
+	   else return (failWith $ head errs)
+-}
 
 
 -------------------------------------------------------------------------------
@@ -188,16 +159,15 @@
 makeInterfaces paths (CS.Module mid _ decls)
   = do let imports = [preludeMIdent | mid /= preludeMIdent] 
 		      ++ [imp | CS.ImportDecl _ imp _ _ _ <- decls]
-       (deps, errs) <- fmap (flattenDeps . sortDeps)
-		            (foldM (moduleDeps paths []) emptyEnv imports)
+       (deps, errs) <- fmap flattenDeps (foldM (moduleDeps paths []) Map.empty imports)
        when (null errs) (mapM_ (compile deps . snd) deps)
        return errs
  where
  compile deps (Source file' mods)
     = do smake [flatName file', flatIntName file']
-	       (file':catMaybes (map (flatInterface deps) mods))
-	       (compileCurry (opts paths) file')
-	       (return defaultResults)
+	       (file':mapMaybe (flatInterface deps) mods)
+	       (compileModule (opts paths) file')
+	       (return Nothing)
 	 return ()
  compile _ _ = return ()
 
@@ -207,47 +177,12 @@
 	Just (Interface file) -> Just (flatIntName (dropExtension file))
 	_                     -> Nothing
 
--- Declares the filename as module name, if the module name is not
--- explicitly declared in the module.
-patchModuleId :: FilePath -> CS.Module -> CS.Module
-patchModuleId fn (CS.Module mid mexports decls)
-   | (moduleName mid) == "main"
-     = CS.Module (mkMIdent [takeBaseName fn]) mexports decls
-   | otherwise
-     = CS.Module mid mexports decls
 
-
--- Adds an import declaration for the prelude to the module, if
--- it is not the prelude itself. If the module already has an explicit
--- import for the prelude, then a qualified import is added.
-importPrelude :: FilePath -> CS.Module -> CS.Module
-importPrelude fn (CS.Module m es ds)
-   = CS.Module m es (if m == preludeMIdent then ds else ds')
- where ids = [decl | decl@(CS.ImportDecl _ _ _ _ _) <- ds]
-       ds' = CS.ImportDecl (first fn) preludeMIdent
-                        (preludeMIdent `elem` map importedModule ids)
-                        Nothing Nothing : ds
-       importedModule (CS.ImportDecl _ m q asM is) = fromMaybe m asM
-
-
 -- Returns 'True', if file name and module name are equal.
 isValidModuleId :: FilePath -> ModuleIdent -> Bool
 isValidModuleId fn mid
    = last (moduleQualifiers mid) == takeBaseName fn
 
-
--- Converts a literate source program to a non-literate source program
-unlitLiterate :: FilePath -> String -> (String,String)
-unlitLiterate fn src
-  | isLiterateSource fn = unlit fn src
-  | otherwise           = ("",src)
-
-isLiterateSource :: FilePath -> Bool
-isLiterateSource fn = litExt `isSuffixOf` fn
-
-litExt = ".lcurry"
-
-compileCurry = compileModule_
 
 -------------------------------------------------------------------------------
 -- Messages
diff --git a/src/GenAbstractCurry.hs b/src/GenAbstractCurry.hs
--- a/src/GenAbstractCurry.hs
+++ b/src/GenAbstractCurry.hs
@@ -10,17 +10,20 @@
 module GenAbstractCurry (genTypedAbstract, 
 			 genUntypedAbstract) where
 
+import qualified Data.Map as Map
+import qualified Data.Set as Set
 import Data.Maybe
 import Data.List
 import Data.Char
 
-import AbstractCurry
+import Curry.Syntax
+import Curry.AbstractCurry
+
 import Base
 import Types
-import Ident
-import Position
+import Curry.Base.Ident
+import Curry.Base.Position
 import TopEnv
-import Env
 
 
 -------------------------------------------------------------------------------
@@ -54,13 +57,13 @@
 	     = mapfoldl genImportDecl env (reverse (importDecls partitions))
 	 (types, _) 
 	     = mapfoldl genTypeDecl env (reverse (typeDecls partitions))
-	 (funcs, _) 
-	     = mapfoldl (genFuncDecl False) 
+	 (_, funcs) 
+	     = Map.mapAccumWithKey (genFuncDecl False) 
 	                env 
 			(funcDecls partitions)
 	 (ops, _)   
 	     = mapfoldl genOpDecl env (reverse (opDecls partitions))
-     in  CurryProg modname imps types funcs ops
+     in  CurryProg modname imps types (Map.elems funcs) ops
 
 
 -------------------------------------------------------------------------------
@@ -87,16 +90,16 @@
 partitionDecl partitions (FlatExternalDecl pos ids)
    = partitionFuncDecls (\id -> FlatExternalDecl pos [id]) partitions ids
 partitionDecl partitions (InfixDecl pos fix prec idents)
-   = partitions {opDecls = (map (\id -> (InfixDecl pos fix prec [id])) idents)
-		          ++ (opDecls partitions)}
+   = partitions {opDecls = map (\id -> (InfixDecl pos fix prec [id])) idents
+		           ++ opDecls partitions }
 partitionDecl partitions decl
    = case decl of
        ImportDecl _ _ _ _ _ 
-         -> partitions {importDecls = decl:(importDecls partitions)}
+         -> partitions {importDecls = decl: importDecls partitions }
        DataDecl _ _ _ _     
-         -> partitions {typeDecls = decl:(typeDecls partitions)}
+         -> partitions {typeDecls = decl : typeDecls partitions }
        TypeDecl _ _ _ _     
-         -> partitions {typeDecls = decl:(typeDecls partitions)}
+         -> partitions {typeDecls = decl : typeDecls partitions }
        _ -> partitions
 
 
@@ -106,7 +109,7 @@
    = partitions {funcDecls = foldl partitionFuncDecl (funcDecls partitions) ids}
  where
    partitionFuncDecl funcs' id
-      = insertEntry id ((genDecl id):(fromMaybe [] (lookup id funcs'))) funcs'
+      = Map.insert id (genDecl id : fromMaybe [] (Map.lookup id funcs')) funcs'
 
 
 -- Data type for representing partitions of CurrySyntax declarations
@@ -117,14 +120,14 @@
 -- to collect them within an association list
 data Partitions = Partitions {importDecls :: [Decl],
 			      typeDecls   :: [Decl],
-			      funcDecls   :: [(Ident,[Decl])],
+			      funcDecls   :: Map.Map Ident [Decl],
 			      opDecls     :: [Decl]
 			     } deriving Show
 
 -- Generates initial partitions.
 emptyPartitions = Partitions {importDecls = [],
 			      typeDecls   = [],
-			      funcDecls   = [],
+			      funcDecls   = Map.empty,
 			      opDecls     = []
 			     } 
 
@@ -202,15 +205,15 @@
          (ls,ts) = unzip fs
          (ts',env1) = mapfoldl genTypeExpr env ts
          ls' = map name ls
-     in  case mr of
+     in case mr of
            Nothing
              -> (CRecordType (zip ls' ts') Nothing, env1)
            Just tvar@(VariableType _)
              -> let (CTVar iname, env2) = genTypeExpr env1 tvar
                 in  (CRecordType (zip ls' ts') (Just iname), env2)
-           Just rec@(RecordType _ _)
-             -> let (CRecordType fields rbase, env2) = genTypeExpr env1 rec
-		    fields' = foldr (\ (l,t) -> insertEntry l t) 
+           (Just r@(RecordType _ _))
+             -> let (CRecordType fields rbase, env2) = genTypeExpr env1 r
+		    fields' = foldr (uncurry insertEntry) 
 				    fields
 			            (zip ls' ts')
 		in  (CRecordType fields' rbase, env2)
@@ -240,8 +243,8 @@
 --   - since infered types are internally represented in flat style,
 --     all type variables are renamed with generated symbols when
 --     generating typed AbstractCurry.
-genFuncDecl :: Bool -> AbstractEnv -> (Ident, [Decl]) -> (CFuncDecl, AbstractEnv)
-genFuncDecl isLocal env (ident, decls)
+genFuncDecl :: Bool -> AbstractEnv -> Ident -> [Decl] -> (AbstractEnv, CFuncDecl)
+genFuncDecl isLocal env ident decls
    | not (null decls)
      = let name          = genQName False env (qualify ident)
 	   visibility    = genVisibility env ident
@@ -255,21 +258,21 @@
 			         (\ (FunctionDecl _ _ equs)
 				  -> mapfoldl genRule env1 equs)
 				 (find isFunctionDecl decls)
-           mexternal     = applyMaybe genExternal (find isExternal decls)
+           mexternal     = fmap genExternal (find isExternal decls)
 	   arity         = compArity mtype rules
            typeexpr      = fromMaybe (CTCons ("Prelude","untyped") []) mtype
            rule          = compRule evalannot rules mexternal
            env3          = if isLocal then env1 else resetScope env2
-       in  (CFunc name arity visibility typeexpr rule, env3)
+       in  (env3, CFunc name arity visibility typeexpr rule)
    | otherwise
      = internalError ("missing declaration for function \""
 		      ++ show ident ++ "\"")
  where
    genFuncType env decls
       | acytype == UntypedAcy
-	= applyMaybe (genTypeSig env) (find isTypeSig decls)
+	= fmap (genTypeSig env) (find isTypeSig decls)
       | acytype == TypedAcy
-	= applyMaybe (genTypeExpr env) mftype
+	= fmap (genTypeExpr env) mftype
       | otherwise 
 	= Nothing
     where 
@@ -300,7 +303,7 @@
 		mtypeexpr
 
    compArityFromType (CTVar _)        = 0
-   compArityFromType (CFuncType _ t2) = 1 + (compArityFromType t2)
+   compArityFromType (CFuncType _ t2) = 1 + compArityFromType t2
    compArityFromType (CTCons _ _)     = 0
 
    compRule evalannot rules mexternal
@@ -371,7 +374,7 @@
 
    -- The association list 'fdecls' is necessary because function
    -- rules may not be together in the declaration list
-   genLocals :: AbstractEnv -> [(Ident,[Decl])] -> [Decl] 
+   genLocals :: AbstractEnv -> Map.Map Ident [Decl] -> [Decl] 
 	        -> ([CLocalDecl], AbstractEnv)
    genLocals env _ [] = ([], env)
    genLocals env fdecls ((FunctionDecl _ ident _):decls)
@@ -390,15 +393,15 @@
 	      (locals, env2) 
 		= genLocals (endScope env1)
 		            fdecls 
-			    ((FlatExternalDecl pos (tail idents)):decls)
+			    (FlatExternalDecl pos (tail idents):decls)
           in  (funcdecl:locals, env2)
-   genLocals env fdecls ((PatternDecl pos constr rhs):decls)
+   genLocals env fdecls (PatternDecl pos constr rhs : decls)
       = let (patt, env1)    = genLocalPattern pos env constr
 	    (plocals, env2) = genLocalDecls (beginScope env1) 
 			                    (simplifyRhsLocals rhs)
 	    (expr, env3)    = genLocalPattRhs pos env2 (simplifyRhsExpr rhs)
 	    (locals, env4)  = genLocals (endScope env3) fdecls decls
-	in  ((CLocalPat patt expr plocals):locals, env4)
+	in  (CLocalPat patt expr plocals:locals, env4)
    genLocals env fdecls ((ExtraVariables pos idents):decls)
       | null idents  = genLocals env fdecls decls
       | otherwise
@@ -408,23 +411,23 @@
 					 ++ " for free variable \""
 					 ++ show ident ++ "\""))
 		         (getVarIndex env ident)
-	      decls' = (ExtraVariables pos (tail idents)):decls
+	      decls' = ExtraVariables pos (tail idents) : decls
 	      (locals, env') = genLocals env fdecls decls'
-          in  ((CLocalVar (idx, name ident)):locals, env')
+          in (CLocalVar (idx, name ident) : locals, env')
    genLocals env fdecls ((TypeSig _ _ _):decls)
       = genLocals env fdecls decls
    genLocals _ _ decl = internalError ("unexpected local declaration: \n"
 				       ++ show (head decl))
 
-   genLocalFuncDecl :: AbstractEnv -> [(Ident,[Decl])] -> Ident 
+   genLocalFuncDecl :: AbstractEnv -> Map.Map Ident [Decl] -> Ident 
 		       -> (CLocalDecl, AbstractEnv)
    genLocalFuncDecl env fdecls ident
       = let fdecl = fromMaybe 
 		      (internalError ("missing declaration" 
 				      ++ " for local function \""
 				      ++ show ident ++ "\""))
-		      (lookup ident fdecls)
-	    (funcdecl, _) = genFuncDecl True env (ident,fdecl)
+		      (Map.lookup ident fdecls)
+	    (_, funcdecl) = genFuncDecl True env ident fdecl
         in  (CLocalFunc funcdecl, env)
 
    genLocalPattern pos env (LiteralPattern lit)
@@ -477,7 +480,7 @@
       = let (fields', env1) = mapfoldl (genField genLocalPattern) env fields
 	    (mr', env2)
 		= maybe (Nothing, env1)
-		        ((applyFst Just) . (genLocalPattern pos env1))
+		        (applyFst Just . genLocalPattern pos env1)
 			mr
 	in  (CPRecord fields' mr', env2)
 
@@ -518,7 +521,7 @@
 genExpr pos env (List _ args)
    = let cons = Constructor qConsId
 	 nil  = Constructor qNilId
-     in  genExpr pos env (foldr (\e1 e2 -> Apply (Apply cons e1) e2) nil args)
+     in  genExpr pos env (foldr (Apply . Apply cons) nil args)
 genExpr pos env (ListCompr _ expr stmts)
    = let (stmts', env1) = mapfoldl (genStatement pos) (beginScope env) stmts
 	 (expr', env2)  = genExpr pos env1 expr
@@ -659,7 +662,7 @@
 genPattern pos env (RecordPattern fields mr)
    = let (fields', env1) = mapfoldl (genField genPattern) env fields
          (mr', env2)     = maybe (Nothing, env1)
-                                 ((applyFst Just) . (genPattern pos env1))
+                                 (applyFst Just . genPattern pos env1)
 				 mr
      in  (CPRecord fields' mr', env2)
 
@@ -693,12 +696,10 @@
    | otherwise
      = genQualName qident
  where
-  ident = unqualify qident
-
   genQualName qid
-     = let (mmid, id) = splitQualIdent qid
+     = let (mmid, id) = (qualidMod qid, qualidId qid)
 	   mid = maybe (moduleId env)
-		       (\mid' -> fromMaybe mid' (lookupEnv mid' (imports env)))
+		       (\mid' -> fromMaybe mid' (Map.lookup mid' (imports env)))
 		       mmid
        in  (moduleName mid, name id)
 
@@ -749,12 +750,12 @@
 data AbstractEnv = AbstractEnv {moduleId   :: ModuleIdent,
 				typeEnv    :: ValueEnv,
 				tconsEnv   :: TCEnv,
-				exports    :: Env Ident (),
-				imports    :: Env ModuleIdent ModuleIdent,
+				exports    :: Set.Set Ident,
+				imports    :: Map.Map ModuleIdent ModuleIdent,
 				varIndex   :: Int,
 				tvarIndex  :: Int,
-				varScope   :: [Env Ident Int],
-				tvarScope  :: [Env Ident Int],
+				varScope   :: [Map.Map Ident Int],
+				tvarScope  :: [Map.Map Ident Int],
                                 acyType    :: AbstractType
 			       } deriving Show
 
@@ -770,12 +771,12 @@
        {moduleId     = mid,
 	typeEnv      = tyEnv,
 	tconsEnv     = tcEnv,
-	exports      = foldl (buildExportTable mid decls) emptyEnv exps',
-	imports      = foldl buildImportTable emptyEnv decls,
+	exports      = foldl (buildExportTable mid decls) Set.empty exps',
+	imports      = foldl buildImportTable Map.empty decls,
 	varIndex     = 0,
 	tvarIndex    = 0,
-	varScope     = [emptyEnv],
-	tvarScope    = [emptyEnv],
+	varScope     = [Map.empty],
+	tvarScope    = [Map.empty],
         acyType      = absType
        }
  where
@@ -785,25 +786,25 @@
 -- Generates a list of exports for all specified top level declarations
 buildExports :: ModuleIdent -> [Decl] -> [Export]
 buildExports _ [] = []
-buildExports mid ((DataDecl _ ident _ _):ds) 
-   = (ExportTypeAll (qualifyWith mid ident)):(buildExports mid ds)
+buildExports mid (DataDecl _ ident _ _:ds) 
+   = ExportTypeAll (qualifyWith mid ident) : buildExports mid ds
 buildExports mid ((NewtypeDecl _ ident _ _):ds)
-   = (ExportTypeAll (qualifyWith mid ident)):(buildExports mid ds)
+   = ExportTypeAll (qualifyWith mid ident) : buildExports mid ds
 buildExports mid ((TypeDecl _ ident _ _):ds)
-   = (Export (qualifyWith mid ident)):(buildExports mid ds)
+   = Export (qualifyWith mid ident) : buildExports mid ds
 buildExports mid ((FunctionDecl _ ident _):ds)
-   = (Export (qualifyWith mid ident)):(buildExports mid ds)
-buildExports mid ((ExternalDecl _ _ _ ident _):ds)
-   = (Export (qualifyWith mid ident)):(buildExports mid ds)
-buildExports mid ((FlatExternalDecl _ idents):ds)
-   = (map (Export . (qualifyWith mid)) idents) ++ (buildExports mid ds)
+   = Export (qualifyWith mid ident) : buildExports mid ds
+buildExports mid (ExternalDecl _ _ _ ident _ : ds)
+   = Export (qualifyWith mid ident) : buildExports mid ds
+buildExports mid (FlatExternalDecl _ idents : ds)
+   = map (Export . qualifyWith mid) idents ++ buildExports mid ds
 buildExports mid (_:ds) = buildExports mid ds
 
 
 -- Builds a table containing all exported (i.e. public) identifiers
 -- from a module.
-buildExportTable :: ModuleIdent -> [Decl] -> Env Ident () -> Export 
-                    -> Env Ident ()
+buildExportTable :: ModuleIdent -> [Decl] -> Set.Set Ident -> Export 
+                 -> Set.Set Ident
 buildExportTable mid _ exptab (Export qident)
    | isJust (localIdent mid qident)
      = insertExportedIdent exptab (unqualify qident)
@@ -826,8 +827,8 @@
 buildExportTable _ _ exptab (ExportModule _) = exptab
 
 --
-insertExportedIdent :: Env Ident () -> Ident -> Env Ident ()
-insertExportedIdent env ident = bindEnv ident () env
+insertExportedIdent :: Set.Set Ident -> Ident -> Set.Set Ident
+insertExportedIdent env ident = Set.insert ident env
 
 --
 getConstrIdents :: Decl -> [Ident]
@@ -839,16 +840,16 @@
 
 
 -- Builds a table for dereferencing import aliases
-buildImportTable :: Env ModuleIdent ModuleIdent -> Decl
-		    -> Env ModuleIdent ModuleIdent
+buildImportTable :: Map.Map ModuleIdent ModuleIdent -> Decl
+		    -> Map.Map ModuleIdent ModuleIdent
 buildImportTable env (ImportDecl _ mid _ malias _)
-   = bindEnv (fromMaybe mid malias) mid env
+   = Map.insert (fromMaybe mid malias) mid env
 buildImportTable env _ = env
 
 
 -- Checks whether an identifier is exported or not.
 isExported :: AbstractEnv -> Ident -> Bool
-isExported env ident = isJust (lookupEnv ident (exports env))
+isExported env ident = Set.member ident (exports env)
 
 
 -- Generates an unique index for the  variable 'ident' and inserts it
@@ -857,9 +858,9 @@
 genVarIndex env ident 
    = let idx   = varIndex env
          vtabs = varScope env
-	 vtab  = head vtabs --if null vtabs then emptyEnv else head vtabs
+	 vtab  = head vtabs --if null vtabs then Map.empty else head vtabs
      in  (idx, env {varIndex = idx + 1,
-		    varScope = (bindEnv ident idx vtab):(sureTail vtabs)})
+		    varScope = Map.insert ident idx vtab : sureTail vtabs})
 
 -- Generates an unique index for the type variable 'ident' and inserts it
 -- into the type variable table of the current scope.
@@ -867,20 +868,20 @@
 genTVarIndex env ident
    = let idx   = tvarIndex env
          vtabs = tvarScope env
-	 vtab  = head vtabs --if null vtabs then emptyEnv else head vtabs
+	 vtab  = head vtabs --if null vtabs then Map.empty else head vtabs
      in  (idx, env {tvarIndex = idx + 1,
-		    tvarScope = (bindEnv ident idx vtab):(sureTail vtabs)})
+		    tvarScope = Map.insert ident idx vtab : sureTail vtabs })
 
 
 -- Looks up the unique index for the variable 'ident' in the
 -- variable table of the current scope.
 getVarIndex :: AbstractEnv -> Ident -> Maybe Int
-getVarIndex env ident = lookupEnv ident (head (varScope env))
+getVarIndex env ident = Map.lookup ident (head (varScope env))
 
 -- Looks up the unique index for the type variable 'ident' in the type
 -- variable table of the current scope.
 getTVarIndex :: AbstractEnv -> Ident -> Maybe Int
-getTVarIndex env ident = lookupEnv ident (head (tvarScope env))
+getTVarIndex env ident = Map.lookup ident (head (tvarScope env))
 
 
 -- Generates an indentifier which doesn't occur in the variable table
@@ -895,31 +896,18 @@
          = ident
     where ident = mkIdent (name ++ show idx)
 
--- Generates an indentifier which doesn't occur in the type variable table
--- of the current scope.
-freshTVar :: AbstractEnv -> String -> Ident
-freshTVar env name = genFreshTVar env name 0
- where
-   genFreshTVar env name idx
-      | isJust (getTVarIndex env ident)
-         = genFreshTVar env name (idx + 1)
-      | otherwise 
-         = ident
-    where ident = mkIdent (name ++ show idx)
-
-
 -- Sets the index counter back to zero and deletes all stack entries.
 resetScope :: AbstractEnv -> AbstractEnv
 resetScope env = env {varIndex  = 0,
 		      tvarIndex = 0,
-		      varScope  = [emptyEnv],
-		      tvarScope = [emptyEnv]}
+		      varScope  = [Map.empty],
+		      tvarScope = [Map.empty]}
 
 -- Starts a new scope, i.e. copies and pushes the variable table of the current 
 -- scope onto the top of the stack
 beginScope :: AbstractEnv -> AbstractEnv
-beginScope env = env {varScope  = (head vs):vs,
-		      tvarScope = (head tvs):tvs}
+beginScope env = env {varScope  = head vs :vs,
+		      tvarScope = head tvs :tvs }
  where
  vs  = varScope env
  tvs = tvarScope env
@@ -969,7 +957,7 @@
 -- Checks, whether a symbol is defined in the Prelude.
 isPreludeSymbol :: QualIdent -> Bool
 isPreludeSymbol qident
-   = let (mmid, ident) = splitQualIdent qident
+   = let (mmid, ident) = (qualidMod qident, qualidId qident)
      in  (isJust mmid && preludeMIdent == fromJust mmid)
          || elem ident [unitId, listId, nilId, consId]
 	 || isTupleId ident
@@ -986,7 +974,7 @@
 qualLookupType :: QualIdent -> ValueEnv -> Maybe TypeExpr
 qualLookupType qident tyEnv
    = case (qualLookupValue qident tyEnv) of
-       [Value _ ts] -> (\ (ForAll _ ty) -> Just (toCSType ty)) ts
+       [Value _ ts] -> (\ (ForAll _ ty) -> Just (fromType ty)) ts
        _            -> Nothing
 
 -- Looks up the type of a symbol in the type environment and
@@ -994,66 +982,14 @@
 lookupType :: Ident -> ValueEnv -> Maybe TypeExpr
 lookupType ident tyEnv
    = case (lookupValue ident tyEnv) of
-       [Value _ ts] -> (\ (ForAll _ ty) -> Just (toCSType ty)) ts
+       [Value _ ts] -> (\ (ForAll _ ty) -> Just (fromType ty)) ts
        _            -> Nothing
 
 
--- Converts the internal representation of the types from the type
--- envorinment to CurrySyntax representation
-toCSType :: Type -> TypeExpr
-toCSType = fromType 
-{-
-toCSType (TypeConstructor qident types)
-   = ConstructorType qident (map toCSType types)
-toCSType (TypeVariable idx)
-   = VariableType (mkVarIdent idx)
-toCSType (TypeConstrained types _)
-   = toCSType (head types)
-toCSType (TypeArrow type1 type2)
-   = ArrowType (toCSType type1) (toCSType type2)
-toCSType (TypeSkolem idx)
-   = VariableType (mkVarIdent idx)
--}
-
-{-
---
-solveTypeSyn :: TCEnv -> QualIdent -> [TypeExpr] -> Maybe TypeExpr
-solveTypeSyn tcEnv qident args
-   = case (qualLookupTC qident tcEnv) of
-       [AliasType _ _ t] -> Just (adaptType args t)
-       _ -> case (lookupTC (unqualify qident) tcEnv) of
-	       [AliasType _ _ t] -> Just (adaptType args t)
-	       _ -> Nothing
-
---
-adaptType :: [TypeExpr] -> Type -> TypeExpr
-adaptType args texpr = adapt (zip [0 .. ((length args) - 1)] args) texpr
- where
- adapt its (TypeConstructor qident types)
-    = ConstructorType qident (map (adapt its) types)
- adapt its (TypeVariable idx)
-    = fromMaybe (internalError "cannot adapt type variable")
-	        (lookup idx its)
- adapt its (TypeConstrained types _)
-    = adapt its (head types)
- adapt its (TypeArrow type1 type2)
-    = ArrowType (adapt its type1) (adapt its type2)
- adapt its (TypeSkolem idx)
-    = adapt its (TypeVariable idx)
--}
-
--- Generates a variable name from an index.
-mkVarIdent :: Int -> Ident
-mkVarIdent i | i < 0     = mkIdent ('b':(show (i * (-1)))) 
-             | i < 26    = mkIdent [chr (i + ord 'a')]
-	     | otherwise = mkIdent ('a':(show i))
-       
-
-
 -- The following functions transform left-hand-side and right-hand-side terms
 -- for a better handling
 simplifyLhs :: Lhs -> [ConstrTerm]
-simplifyLhs lhs = snd (flatLhs lhs)
+simplifyLhs = snd . flatLhs
 
 simplifyRhsExpr :: Rhs -> [(Expression, Expression)]
 simplifyRhsExpr (SimpleRhs _ expr _) 
@@ -1066,11 +1002,7 @@
 simplifyRhsLocals (GuardedRhs _ locals)  = locals
 
 
--- Applies the function 'f' on the value which is wrapped in 'Just'.
-applyMaybe :: (a -> b) -> Maybe a -> Maybe b
-applyMaybe f (Just x) = Just (f x)
-applyMaybe _ Nothing  = Nothing
-
+-- FIXME This mapfold is a twisted mapAccumL
 -- A combination of 'map' and 'foldl'. It maps a function to a list
 -- from left to right while updating the argument 'e' continously.
 mapfoldl :: (a -> b -> (c,a)) -> a -> [b] -> ([c], a)
@@ -1084,7 +1016,7 @@
 insertEntry k e [] = [(k,e)]
 insertEntry k e ((x,y):xys)
    | k == x    = (k,e):xys
-   | otherwise = (x,y):(insertEntry k e xys)
+   | otherwise = (x,y) : insertEntry k e xys
 
 
 -- Returns the list without the first element. If the list is empty, an
diff --git a/src/GenFlatCurry.hs b/src/GenFlatCurry.hs
--- a/src/GenFlatCurry.hs
+++ b/src/GenFlatCurry.hs
@@ -15,32 +15,27 @@
 import Data.Maybe
 import Data.List
 import qualified Data.Map as Map
-import Base (ArityEnv, ArityInfo(..), ModuleEnv, PEnv, PrecInfo(..), 
-	     OpPrec(..), TCEnv, TypeInfo(..), ValueEnv, ValueInfo(..),
-	     lookupValue, qualLookupTC,
-	     qualLookupArity, lookupArity,  internalError)
 
---import FlatWithSrcRefs
-import ExtendedFlat
-
-import qualified IL
-import qualified CurrySyntax as CS
+import Curry.Base.MessageMonad
+import Curry.Base.Ident as Id
 
+import Base {-(ArityEnv, ArityInfo(..), ModuleEnv,  
+	     TCEnv, TypeInfo(..), ValueEnv, ValueInfo(..),
+	     lookupValue, qualLookupTC,
+	     qualLookupArity, lookupArity,  internalError,
+             qualLookupValue)-}
+import Curry.ExtendedFlat
+import qualified IL.Type as IL
+import qualified IL.CurryToIL as IL
+import qualified Curry.Syntax as CS
 import CurryEnv (CurryEnv)
 import qualified CurryEnv
-
 import ScopeEnv (ScopeEnv)
 import qualified ScopeEnv
-
-
 import Types
 import CurryCompilerOpts
-import Message
 import PatchPrelude
-import Ident as Id
-import Env
 
---import Debug.Trace
 
 trace _ x = x
 
@@ -48,7 +43,7 @@
 
 -- transforms intermediate language code (IL) to FlatCurry code
 genFlatCurry :: Options -> CurryEnv -> ModuleEnv -> ValueEnv -> TCEnv 
-		-> ArityEnv -> IL.Module -> (Prog, [Message])
+		-> ArityEnv -> IL.Module -> (Prog, [WarnMsg])
 genFlatCurry opts cEnv mEnv tyEnv tcEnv aEnv mod
    = (patchPreludeFCY prog, messages)
  where (prog, messages) 
@@ -57,7 +52,7 @@
 
 -- transforms intermediate language code (IL) to FlatCurry interfaces
 genFlatInterface :: Options -> CurryEnv -> ModuleEnv -> ValueEnv -> TCEnv
-		 -> ArityEnv -> IL.Module -> (Prog, [Message])
+		 -> ArityEnv -> IL.Module -> (Prog, [WarnMsg])
 genFlatInterface opts cEnv mEnv tyEnv tcEnv aEnv mod
    = (patchPreludeFCY intf, messages)
  where (intf, messages) 
@@ -177,16 +172,19 @@
    = liftM Var (lookupVarIndex ident)
 visitExpression (IL.Function qident _)
    = do arity_ <- lookupIdArity qident
+        qname <- visitQualIdent qident
+   --     ftype <- lookupIdType qident
+   --     let qident' = qname{ typeofQName = ftype }
 	maybe (internalError (funcArity qident))
-	      (\arity -> genFuncCall qident arity [])
+	      (\arity -> genFuncCall qname arity [])
 	      arity_
 visitExpression (IL.Constructor qident arity)
    = do arity_ <- lookupIdArity qident
 	maybe (internalError (consArity qident))
 	      (\arity -> genConsCall qident arity [])
 	      arity_
-visitExpression (IL.Apply expression1 expression2)
-   = genFlatApplication (IL.Apply expression1 expression2)
+visitExpression (IL.Apply e1 e2)
+   = genFlatApplication e1 e2
 visitExpression (IL.Case r evalannot expression alts)
    = do ea       <- visitEval evalannot
 	expr     <- visitExpression expression
@@ -208,12 +206,10 @@
 	newVarIndex (bindingIdent binding)
         bind <- visitBinding binding
 	expr <- visitExpression expression
-	case expr of
-	  Let binds expr' -> return (Let (bind:binds) expr')
-	  _               -> return (Let [bind] expr)
+        return (Let [bind] expr)
 visitExpression (IL.Letrec bindings expression)
    = do beginScope
-	mapM_ newVarIndex (map bindingIdent bindings)
+	mapM_ (newVarIndex . bindingIdent) bindings
 	binds <- mapM visitBinding bindings
 	expr  <- visitExpression expression
 	endScope
@@ -275,8 +271,8 @@
 
 --
 visitEval :: IL.Eval -> FlatState CaseType
-visitEval IL.Rigid = return (Rigid)
-visitEval IL.Flex  = return (Flex)
+visitEval IL.Rigid = return Rigid
+visitEval IL.Flex  = return Flex
 
 --
 visitBinding :: IL.Binding -> FlatState (VarIndex, Expr)
@@ -300,8 +296,8 @@
 visitTypeIDecl :: CS.IDecl -> FlatState TypeDecl
 visitTypeIDecl (CS.IDataDecl _ qident params constrs_)
    = do let mid = fromMaybe (internalError "GenFlatCurry: no module name")
-		            (fst (splitQualIdent qident))
-	    is  = [0 .. (length params) - 1]
+		            (qualidMod qident)
+	    is  = [0 .. length params - 1]
 	cdecls <- mapM (visitConstrIDecl mid (zip params is)) 
 		       (catMaybes constrs_)
 	qname  <- visitQualIdent qident
@@ -317,7 +313,7 @@
 visitConstrIDecl :: ModuleIdent -> [(Ident, Int)] -> CS.ConstrDecl 
 		    -> FlatState ConsDecl
 visitConstrIDecl mid tis (CS.ConstrDecl _ _ ident typeexprs)
-   = do texprs <- mapM visitType (map (fst . cs2ilType tis) typeexprs)
+   = do texprs <- mapM (visitType . (fst . cs2ilType tis)) typeexprs
 	qname  <- visitQualIdent (qualifyWith mid ident)
 	return (Cons qname (length typeexprs) Public texprs)
 visitConstrIDecl mid tis (CS.ConOpDecl pos ids type1 ident type2)
@@ -338,13 +334,13 @@
 
 --
 visitModuleIdent :: ModuleIdent -> FlatState String
-visitModuleIdent mident = return (Id.moduleName mident)
+visitModuleIdent = return . Id.moduleName
 
 --
 visitQualIdent :: QualIdent -> FlatState QName
 visitQualIdent qident
    = do mid <- moduleId
-	let (mmod, ident) = splitQualIdent qident
+	let (mmod, ident) = (qualidMod qident, qualidId qident)
 	    mod | elem ident [listId, consId, nilId, unitId] || isTupleId ident
 		  = Id.moduleName preludeMIdent
 		| otherwise
@@ -354,7 +350,7 @@
 --
 visitExternalName :: String -> FlatState String
 visitExternalName name 
-   = moduleId >>= (\mid -> return ((Id.moduleName mid) ++ "." ++ name))
+   = moduleId >>= \mid -> return (Id.moduleName mid ++ "." ++ name)
 
 
 -------------------------------------------------------------------------------
@@ -372,11 +368,11 @@
 getExportedImports
    = do mid  <- moduleId
 	exps <- exports
-	genExportedIDecls (envToList (getExpImports mid emptyEnv exps))
+	genExportedIDecls (Map.toList (getExpImports mid Map.empty exps))
 
 --
-getExpImports :: ModuleIdent -> Env ModuleIdent [CS.Export] -> [CS.Export]
-		 -> Env ModuleIdent [CS.Export]
+getExpImports :: ModuleIdent -> Map.Map ModuleIdent [CS.Export] -> [CS.Export]
+		 -> Map.Map ModuleIdent [CS.Export]
 getExpImports mident expenv [] = expenv
 getExpImports mident expenv ((CS.Export qident):exps)
    = getExpImports mident 
@@ -394,20 +390,19 @@
 	 	   (bindExpImport mident qident (CS.ExportTypeAll qident) expenv) 
 		   exps
 getExpImports mident expenv ((CS.ExportModule mident'):exps)
-   = getExpImports mident (bindEnv mident' [] expenv) exps
+   = getExpImports mident (Map.insert mident' [] expenv) exps
 
 --
 bindExpImport :: ModuleIdent -> QualIdent -> CS.Export 
-	         -> Env ModuleIdent [CS.Export] -> Env ModuleIdent [CS.Export]
+	         -> Map.Map ModuleIdent [CS.Export] -> Map.Map ModuleIdent [CS.Export]
 bindExpImport mident qident export expenv
    | isJust (localIdent mident qident)
      = expenv
    | otherwise
-     = let (mmod, _) = splitQualIdent qident
-	   mod       = fromJust mmod
-       in  maybe (bindEnv mod [export] expenv)
-	         (\es -> bindEnv mod (export:es) expenv) 
-		 (lookupEnv mod expenv)
+     = let (Just mod) = qualidMod qident
+       in  maybe (Map.insert mod [export] expenv)
+	         (\es -> Map.insert mod (export:es) expenv) 
+		 (Map.lookup mod expenv)
 
 --
 genExportedIDecls :: [(ModuleIdent,[CS.Export])] -> FlatState [CS.IDecl]
@@ -477,9 +472,9 @@
 -------------------------------------------------------------------------------
 
 --
-genFlatApplication :: IL.Expression -> FlatState Expr
-genFlatApplication applicexpr
-   = genFlatApplic [] applicexpr
+genFlatApplication :: IL.Expression -> IL.Expression -> FlatState Expr
+genFlatApplication e1 e2
+   = genFlatApplic [e2] e1
  where
    genFlatApplic args expression 
       = case expression of
@@ -487,8 +482,9 @@
 	      -> genFlatApplic (expr2:args) expr1
 	  (IL.Function qident _)
 	      -> do arity_ <- lookupIdArity qident
+                    qname <- visitQualIdent qident
 		    maybe (internalError (funcArity qident))
-			  (\arity -> genFuncCall qident arity args)
+			  (\arity -> genFuncCall qname arity args)
 			  arity_
 	  (IL.Constructor qident _)
 	      -> do arity_ <- lookupIdArity qident
@@ -499,36 +495,39 @@
 		    genApplicComb expr args
 
 --
-genFuncCall :: QualIdent -> Int -> [IL.Expression] -> FlatState Expr
-genFuncCall qident arity args
+genFuncCall :: QName -> Int -> [IL.Expression] -> FlatState Expr
+genFuncCall qname arity args
    | arity > cnt 
-     = genComb qident args (FuncPartCall (arity - cnt))
+     = genComb qname args (FuncPartCall (arity - cnt))
    | arity < cnt 
      = do let (funcargs, applicargs) = splitAt arity args
-	  funccall <- genComb qident funcargs FuncCall
+	  funccall <- genComb qname funcargs FuncCall
 	  genApplicComb funccall applicargs
    | otherwise   
-     = genComb qident args FuncCall
+     = genComb qname args FuncCall
  where cnt = length args
 
 --
 genConsCall :: QualIdent -> Int -> [IL.Expression] -> FlatState Expr
 genConsCall qident arity args
    | arity > cnt 
-     = genComb qident args (ConsPartCall (arity - cnt))
+     = do qname <- visitQualIdent qident
+          genComb qname args (ConsPartCall (arity - cnt))
    | arity < cnt
      = do let (funcargs, applicargs) = splitAt arity args
-	  conscall <- genComb qident funcargs ConsCall
+          qname <- visitQualIdent qident
+	  conscall <- genComb qname funcargs ConsCall
 	  genApplicComb conscall applicargs
    | otherwise 
-     = genComb qident args ConsCall 
+     = do qname <- visitQualIdent qident
+          genComb qname args ConsCall 
  where cnt = length args
 
 --
-genComb :: QualIdent -> [IL.Expression] -> CombType -> FlatState Expr
-genComb qident args combtype
+genComb :: QName -> [IL.Expression] -> CombType -> FlatState Expr
+genComb qname args combtype
    = do exprs <- mapM visitExpression args
-	qname <- visitQualIdent qident
+--	qname <- visitQualIdent qident
 	return (Comb combtype qname exprs)
 	 
 --
@@ -544,7 +543,7 @@
 
 --
 genOpDecls :: FlatState [OpDecl]
-genOpDecls = fixities >>= (\fix -> mapM genOpDecl fix)
+genOpDecls = fixities >>= mapM genOpDecl
 
 --
 genOpDecl :: CS.IDecl -> FlatState OpDecl
@@ -604,7 +603,7 @@
 genRecordType :: CS.IDecl -> FlatState TypeDecl
 genRecordType (CS.ITypeDecl _ qident params (CS.RecordType fields _))
    = do let is = [0 .. (length params) - 1]
-	    (mod,ident) = splitQualIdent qident
+	    (mod,ident) = (qualidMod qident, qualidId qident)
 	qname <- visitQualIdent ((maybe qualify qualifyWith mod) 
 				 (recordExtId ident))
 	labels <- mapM (genRecordLabel mod (zip params is)) fields
@@ -682,17 +681,14 @@
      = internalError ("GenFlatCurry.matchTypeVars: "
 		      ++ show ty ++ "\n" ++ show typeexpr)
 
-  matchList ms tys typeexprs
-     = foldl (\ms' (ty,typeexpr) -> match ms' ty typeexpr)
-             ms
-	     (zip tys typeexprs)
+  matchList ms tys
+     = foldl (\ms' (ty,typeexpr) -> match ms' ty typeexpr) ms . zip tys
 
 
 flattenRecordTypeFields :: [([Ident],CS.TypeExpr)] -> [(Ident,CS.TypeExpr)]
-flattenRecordTypeFields fss
+flattenRecordTypeFields
    = concatMap (\ (labels, typeexpr)
 		-> map (\label -> (label,typeexpr)) labels)
-               fss
 
 -------------------------------------------------------------------------------
 
@@ -756,29 +752,10 @@
 missingVarIndex id = "GenFlatCurry: missing index for \"" ++ show id ++ "\""
 
 
-overlappingRules qid = (OverlapRules,
-                           "function \""
-		        ++ show qid 
+overlappingRules qid =  "function \""
+		        ++ qualName qid 
 		        ++ "\" is non-deterministic due to non-trivial "
-		        ++ "overlapping rules")
-
-
--------------------------------------------------------------------------------
-prelude_types :: [TypeDecl]
-prelude_types = [(Type (preludeName "()") Public [] 
-		  [(Cons (preludeName "()") 0 Public [])]),
-		 (Type (preludeName "[]") Public [0] 
-		  [(Cons (preludeName "[]") 0 Public []),
-		   (Cons (preludeName ":") 2 Public 
-		    [(TVar 0),(TCons (preludeName "[]") [(TVar 0)])])])]
-                ++ map mkTupleType [2..15]
-    where
-      preludeName = curry mkQName "Prelude"
-      mkTupleType n = let last  = n-1
-                          name = preludeName("(" ++ replicate last ',' ++ ")")
-                          idxs  = [0..last]
-                          vars  = map TVar idxs
-                      in Type name Public idxs [Cons name n Public vars]
+		        ++ "overlapping rules"
 
 
 -------------------------------------------------------------------------------
@@ -851,13 +828,13 @@
 -- Data type for representing an environment which contains information needed
 -- for generating FlatCurry code.
 data FlatEnv = FlatEnv{ moduleIdE     :: ModuleIdent,
-			  functionIdE   :: QualIdent,
+			  functionIdE   :: QualIdent,    -- function name for error messages
 			  compilerOptsE :: Options,
 			  moduleEnvE    :: ModuleEnv,
 			  arityEnvE     :: ArityEnv,
 			  typeEnvE      :: ValueEnv,
 			  tConsEnvE     :: TCEnv,
-			  publicEnvE    :: Env Ident IdentExport,
+			  publicEnvE    :: Map.Map Ident IdentExport,
 			  fixitiesE     :: [CS.IDecl],
 			  typeSynonymsE :: [CS.IDecl],
 			  importsE      :: [CS.IDecl],
@@ -867,7 +844,7 @@
 			  varIdsE       :: ScopeEnv Ident VarIndex,
 			  tvarIndexE    :: Int,
 			  tvarIdsE      :: ScopeEnv Ident TVarIndex,
-			  messagesE     :: [Message],
+			  messagesE     :: [WarnMsg],
 			  genInterfaceE :: Bool
 			}
 
@@ -884,7 +861,7 @@
 
 -- Runs a 'FlatState' action and returns the result
 run :: Options -> CurryEnv -> ModuleEnv -> ValueEnv -> TCEnv -> ArityEnv 
-    -> Bool -> FlatState a -> (a, [Message])
+    -> Bool -> FlatState a -> (a, [WarnMsg])
 run opts cEnv mEnv tyEnv tcEnv aEnv genIntf f
    = (result, messagesE env)
  where
@@ -955,7 +932,7 @@
 --
 isPublic :: Bool -> QualIdent -> FlatState Bool
 isPublic isConstr qid = gets (\env -> maybe False isP
-                                      (lookupEnv (unqualify qid) 
+                                      (Map.lookup (unqualify qid) 
                                        (publicEnvE env)))
   where
     isP NotConstr = not isConstr
@@ -965,7 +942,7 @@
 --
 lookupModuleIntf :: ModuleIdent -> FlatState (Maybe [CS.IDecl])
 lookupModuleIntf mid
-   = gets (lookupEnv mid . moduleEnvE)
+   = gets (Map.lookup mid . moduleEnvE)
 
 --
 lookupIdArity :: QualIdent -> FlatState (Maybe Int)
@@ -980,6 +957,20 @@
 			      _               -> Nothing
 		      _  -> Nothing
 
+--
+lookupIdType :: QualIdent -> FlatState (Maybe TypeExpr)
+lookupIdType qid
+   = do aEnv <- gets typeEnvE
+        lookupT qid aEnv
+    where
+      lookupT qid aEnv = let vals = qualLookupValue qid aEnv 
+                             ts = [ t | Value _ (ForAll _ t) <- vals]
+                         in case ts of 
+                              t : _ -> do t' <- visitType (IL.translType t)
+                                          return (Just t')
+                              [] -> error ("no type for " ++ show qid ++ show vals ++ show aEnv) -- return Nothing
+
+
 -- Generates a new index for a variable
 newVarIndex :: Ident -> FlatState VarIndex
 newVarIndex id
@@ -1005,46 +996,11 @@
 				        varIdsE = ScopeEnv.new 
 				      })
 
--- Generates a new index for a type variable
-newTVarIndex :: Ident -> FlatState Int
-newTVarIndex id
-   = do idx0 <- gets tvarIndexE
-        let idx = 1 + idx0
-        vids <- gets tvarIdsE
-        modify (\env -> env{ tvarIndexE = idx,
-			     tvarIdsE   = ScopeEnv.insert id idx vids
-			   })
-        return idx
-
--- Looks up the index of an existing type variable or generates a new index,
--- if the type variable doesn't exist
-getTVarIndex :: Ident -> FlatState Int
-getTVarIndex id
-   = do idx0 <- gets tvarIndexE
-        let idx = idx0 + 1
-        vids <- gets tvarIdsE    
-        maybe (do modify (\env -> env{ tvarIndexE = idx,
-		                       tvarIdsE   = ScopeEnv.insert id idx vids })
-                  return idx)
-              return
-              (ScopeEnv.lookup id vids)
-
 --
-lookupTVarIndex :: Ident -> FlatState (Maybe Int)
-lookupTVarIndex id
-   = gets (ScopeEnv.lookup id . tvarIdsE)
-
---
-clearTVarIndices :: FlatState ()
-clearTVarIndices = modify (\env -> env { tvarIndexE = 0,
-					 tvarIdsE = ScopeEnv.new 
-				       })
-
---
-genWarning :: (WarningType,String) -> FlatState ()
-genWarning (warnType,msg)
+genWarning :: String -> FlatState ()
+genWarning msg
    = modify (\env -> env{ messagesE = warnMsg:(messagesE env) })
-    where warnMsg = message_ (Warning warnType) msg
+    where warnMsg = WarnMsg Nothing msg
 
 --
 genInterface :: FlatState Bool
@@ -1076,14 +1032,14 @@
 -- Note: Currently the record functions (selection and update) for all public 
 -- record labels are inserted into the environment, though they are not
 -- explicitly declared in the export specifications.
-genPubEnv :: ModuleIdent -> [CS.IDecl] -> Env Ident IdentExport
-genPubEnv mid idecls = foldl (bindEnvIDecl mid) emptyEnv idecls
+genPubEnv :: ModuleIdent -> [CS.IDecl] -> Map.Map Ident IdentExport
+genPubEnv mid idecls = foldl (bindEnvIDecl mid) Map.empty idecls
 
-bindIdentExport :: Ident -> Bool -> Env Ident IdentExport -> Env Ident IdentExport
+bindIdentExport :: Ident -> Bool -> Map.Map Ident IdentExport -> Map.Map Ident IdentExport
 bindIdentExport id isConstr env =
-    maybe (bindEnv id (if isConstr then OnlyConstr else NotConstr) env)
-          (\ ie -> bindEnv id (updateIdentExport ie isConstr) env)
-          (lookupEnv id env)
+    maybe (Map.insert id (if isConstr then OnlyConstr else NotConstr) env)
+          (\ ie -> Map.insert id (updateIdentExport ie isConstr) env)
+          (Map.lookup id env)
   where
     updateIdentExport OnlyConstr True  = OnlyConstr
     updateIdentExport OnlyConstr False = NotOnlyConstr
@@ -1093,7 +1049,7 @@
 
 
 --
-bindEnvIDecl :: ModuleIdent -> Env Ident IdentExport -> CS.IDecl -> Env Ident IdentExport
+bindEnvIDecl :: ModuleIdent -> Map.Map Ident IdentExport -> CS.IDecl -> Map.Map Ident IdentExport
 bindEnvIDecl mid env (CS.IDataDecl _ qid _ mcdecls)
    = maybe env 
            (\id -> foldl bindEnvConstrDecl
@@ -1111,30 +1067,24 @@
 bindEnvIDecl _ env _ = env
 
 --
-bindEnvITypeDecl :: Env Ident IdentExport -> Ident -> CS.TypeExpr
-		    -> Env Ident IdentExport
+bindEnvITypeDecl :: Map.Map Ident IdentExport -> Ident -> CS.TypeExpr
+		    -> Map.Map Ident IdentExport
 bindEnvITypeDecl env id (CS.RecordType fs _)
    = bindIdentExport id False (foldl (bindEnvRecordLabel id) env fs)
 bindEnvITypeDecl env id texpr
    = bindIdentExport id False env
 
 --
-bindEnvConstrDecl :: Env Ident IdentExport -> CS.ConstrDecl -> Env Ident IdentExport
+bindEnvConstrDecl :: Map.Map Ident IdentExport -> CS.ConstrDecl -> Map.Map Ident IdentExport
 bindEnvConstrDecl env (CS.ConstrDecl _ _ id _)  = bindIdentExport id True env
 bindEnvConstrDecl env (CS.ConOpDecl _ _ _ id _) = bindIdentExport id True env
 
 --
-bindEnvNewConstrDecl :: Env Ident IdentExport -> CS.NewConstrDecl -> Env Ident IdentExport
+bindEnvNewConstrDecl :: Map.Map Ident IdentExport -> CS.NewConstrDecl -> Map.Map Ident IdentExport
 bindEnvNewConstrDecl env (CS.NewConstrDecl _ _ id _) = bindIdentExport id False env
 
 --
-bindEnvRecordLabel :: Ident -> Env Ident IdentExport -> ([Ident],CS.TypeExpr) 
-		   -> Env Ident IdentExport
-bindEnvRecordLabel rec env ([lab],_)
-   = bindIdentExport (recSelectorId (qualify rec) lab)
-             False
-	     (bindIdentExport (recUpdateId (qualify rec) lab) False env)
-
-
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
+bindEnvRecordLabel :: Ident -> Map.Map Ident IdentExport -> ([Ident],CS.TypeExpr) -> Map.Map Ident IdentExport
+bindEnvRecordLabel r env ([lab], _) = bindIdentExport (recSelectorId (qualify r) lab) False expo
+    where 
+      expo = (bindIdentExport (recUpdateId (qualify r) lab) False env)
diff --git a/src/IL.lhs b/src/IL.lhs
deleted file mode 100644
--- a/src/IL.lhs
+++ /dev/null
@@ -1,108 +0,0 @@
-% $Id: IL.lhs,v 1.18 2003/10/28 05:43:38 wlux Exp $
-%
-% Copyright (c) 1999-2003 Wolfgang Lux
-% See LICENSE for the full license.
-%
-% Modified by Martin Engelke (men@informatik.uni-kiel.de)
-%
-\nwfilename{IL.lhs}
-\section{The intermediate language}
-The module \texttt{IL} defines the intermediate language which will be
-compiled into abstract machine code. The intermediate language removes
-a lot of syntactic sugar from the Curry source language.  Top-level
-declarations are restricted to data type and function definitions. A
-newtype definition serves mainly as a hint to the backend that it must
-provide an auxiliary function for partial applications of the
-constructor. \textbf{Newtype constructors must not occur in patterns
-and may be used in expressions only as partial applications.}
-
-Type declarations use a de-Bruijn indexing scheme (starting at 0) for
-type variables. In the type of a function, all type variables are
-numbered in the order of their occurence from left to right, i.e., a
-type \texttt{(Int -> b) -> (a,b) -> c -> (a,c)} is translated into the
-type (using integer numbers to denote the type variables)
-\texttt{(Int -> 0) -> (1,0) -> 2 -> (1,2)}.
-
-Pattern matching in an equation is handled via flexible and rigid
-\texttt{Case} expressions. Overlapping rules are translated with the
-help of \texttt{Or} expressions. The intermediate language has three
-kinds of binding expressions, \texttt{Exist} expressions introduce a
-new logical variable, \texttt{Let} expression support a single
-non-recursive variable binding, and \texttt{Letrec} expressions
-introduce multiple variables with recursive initializer expressions.
-The intermediate language explicitly distinguishes (local) variables
-and (global) functions in expressions.
-
-\em{Note:} this modified version uses haskell type \texttt{Integer}
-instead of \texttt{Int} for representing integer values. This provides
-an unlimited range of integer constants in Curry programs.
-\begin{verbatim}
-
-> module IL where
-> import Ident
-> import Position (SrcRef(..))
-
-> data Module = Module ModuleIdent [ModuleIdent] [Decl] deriving (Eq,Show)
-
-> data Decl = 
->     DataDecl QualIdent Int [ConstrDecl [Type]]
->   | NewtypeDecl QualIdent Int (ConstrDecl Type)
->   | FunctionDecl QualIdent [Ident] Type Expression
->   | ExternalDecl QualIdent CallConv String Type
->   deriving (Eq,Show)
-
-> data ConstrDecl a = ConstrDecl QualIdent a deriving (Eq,Show)
-> data CallConv = Primitive | CCall deriving (Eq,Show)
-
-> data Type =
->     TypeConstructor QualIdent [Type]
->   | TypeVariable Int
->   | TypeArrow Type Type
->   deriving (Eq,Show)
-
-> data Literal = Char SrcRef Char | Int SrcRef Integer | Float SrcRef Double deriving (Eq,Show)
-
-> data ConstrTerm =
->   -- literal patterns
->     LiteralPattern Literal
->   -- constructors
->   | ConstructorPattern QualIdent [Ident]
->   -- default
->   | VariablePattern Ident
->   deriving (Eq,Show)
-
-> data Expression =
->   -- literal constants
->     Literal Literal
->   -- variables, functions, constructors
->   | Variable Ident | Function QualIdent Int | Constructor QualIdent Int
->   -- applications
->   | Apply Expression Expression
->   -- case expressions
->   | Case SrcRef Eval Expression [Alt]
->   -- non-determinisismic or
->   | Or Expression Expression
->   -- binding forms
->   | Exist Ident Expression
->   | Let Binding Expression
->   | Letrec [Binding] Expression
->   deriving (Eq,Show)
-
-> data Eval = Rigid | Flex deriving (Eq,Show)
-> data Alt = Alt ConstrTerm Expression deriving (Eq,Show)
-> data Binding = Binding Ident Expression deriving (Eq,Show)
-
-\end{verbatim}
-
-> instance SrcRefOf ConstrTerm where
->   srcRefOf (LiteralPattern l) = srcRefOf l
->   srcRefOf (ConstructorPattern i _) = srcRefOf i
->   srcRefOf (VariablePattern i) = srcRefOf i
-
-
-> instance SrcRefOf Literal where
->   srcRefOf (Char s _)   = s
->   srcRefOf (Int s _)    = s
->   srcRefOf (Float s _)  = s  
-
-
diff --git a/src/IL/CurryToIL.lhs b/src/IL/CurryToIL.lhs
new file mode 100644
--- /dev/null
+++ b/src/IL/CurryToIL.lhs
@@ -0,0 +1,598 @@
+
+% $Id: ILTrans.lhs,v 1.86 2004/02/13 19:23:58 wlux Exp $
+%
+% Copyright (c) 1999-2003, Wolfgang Lux
+% See LICENSE for the full license.
+%
+% Modified by Martin Engelke (men@informatik.uni-kiel.de)
+%
+\nwfilename{ILTrans.lhs}
+\section{Translating Curry into the Intermediate Language}
+After desugaring and lifting have been performed, the source code is
+translated into the intermediate language. Besides translating from
+source terms and expressions into intermediate language terms and
+expressions this phase in particular has to implement the pattern
+matching algorithm for equations and case expressions.
+
+Because of name conflicts between the source and intermediate language
+data structures, we can use only a qualified import for the
+\texttt{IL} module.
+\begin{verbatim}
+
+> module IL.CurryToIL(ilTrans,ilTransIntf, translType) where
+
+> import Data.Maybe
+> import Data.List
+> import qualified Data.Set as Set
+> import qualified Data.Map as Map
+
+> import Curry.Base.Position
+> import Curry.Base.Ident
+> import Curry.Syntax
+> import Curry.Syntax.Utils
+
+> import Types
+> import Base
+> import qualified IL.Type as IL
+> import Utils
+
+
+
+\end{verbatim}
+\paragraph{Modules}
+At the top-level, the compiler has to translate data type, newtype,
+function, and external declarations. When translating a data type or
+newtype declaration, we ignore the types in the declaration and lookup
+the types of the constructors in the type environment instead because
+these types are already fully expanded, i.e., they do not include any
+alias types.
+\begin{verbatim}
+
+> ilTrans :: Bool -> ValueEnv -> TCEnv -> EvalEnv -> Module -> IL.Module
+> ilTrans flat tyEnv tcEnv evEnv (Module m _ ds) = 
+>   IL.Module m (imports m ds') ds'
+>   where ds' = concatMap (translGlobalDecl flat m tyEnv tcEnv evEnv) ds
+
+> translGlobalDecl :: Bool -> ModuleIdent -> ValueEnv -> TCEnv -> EvalEnv
+>                  -> Decl -> [IL.Decl]
+> translGlobalDecl _ m tyEnv tcEnv _ (DataDecl _ tc tvs cs) =
+>   [translData m tyEnv tcEnv tc tvs cs]
+> translGlobalDecl _ m tyEnv tcEnv _ (NewtypeDecl _ tc tvs nc) =
+>   [translNewtype m tyEnv tcEnv tc tvs nc]
+> translGlobalDecl flat m tyEnv tcEnv evEnv (FunctionDecl pos f eqs) =
+>   [translFunction pos flat m tyEnv tcEnv evEnv f eqs]
+> translGlobalDecl _ m tyEnv tcEnv _ (ExternalDecl _ cc ie f _) =
+>   [translExternal m tyEnv tcEnv f cc (fromJust ie)]
+> translGlobalDecl _ _ _ _ _ _ = []
+
+> translData :: ModuleIdent -> ValueEnv -> TCEnv -> Ident -> [Ident] -> [ConstrDecl]
+>            -> IL.Decl
+> translData m tyEnv tcEnv tc tvs cs =
+>   IL.DataDecl (qualifyWith m tc) (length tvs)
+>               (map (translConstrDecl m tyEnv tcEnv) cs)
+
+> translNewtype :: ModuleIdent -> ValueEnv -> TCEnv -> Ident -> [Ident] 
+>	        -> NewConstrDecl -> IL.Decl
+> translNewtype m tyEnv tcEnv tc tvs (NewConstrDecl _ _ c _) =
+>   IL.NewtypeDecl (qualifyWith m tc) (length tvs)
+>                  (IL.ConstrDecl c' (translType' m tyEnv tcEnv ty))
+>                  -- (IL.ConstrDecl c' (translType ty))
+>   where c' = qualifyWith m c
+>         TypeArrow ty _ = constrType tyEnv c'
+
+> translConstrDecl :: ModuleIdent -> ValueEnv -> TCEnv -> ConstrDecl
+>                  -> IL.ConstrDecl [IL.Type]
+> translConstrDecl m tyEnv tcEnv d =
+>   IL.ConstrDecl c' (map (translType' m tyEnv tcEnv)
+>	                  (arrowArgs (constrType tyEnv c')))
+>   -- IL.ConstrDecl c' (map translType (arrowArgs (constrType tyEnv c')))
+>   where c' = qualifyWith m (constr d)
+>         constr (ConstrDecl _ _ c _) = c
+>         constr (ConOpDecl _ _ _ op _) = op
+
+> translExternal :: ModuleIdent -> ValueEnv -> TCEnv -> Ident -> CallConv
+>                -> String -> IL.Decl
+> translExternal m tyEnv tcEnv f cc ie =
+>   IL.ExternalDecl f' (callConv cc) ie 
+>                   (translType' m tyEnv tcEnv (varType tyEnv f'))
+>   -- IL.ExternalDecl f' (callConv cc) ie (translType (varType tyEnv f'))
+>   where f' = qualifyWith m f
+>         callConv CallConvPrimitive = IL.Primitive
+>         callConv CallConvCCall = IL.CCall
+
+\end{verbatim}
+\paragraph{Interfaces}
+In order to generate code, the compiler also needs to know the tags
+and arities of all imported data constructors. For that reason we
+compile the data type declarations of all interfaces into the
+intermediate language, too. In this case we do not lookup the
+types in the environment because the types in the interfaces are
+already fully expanded. Note that we do not translate data types
+which are imported into the interface from some other module.
+\begin{verbatim}
+
+> ilTransIntf :: ValueEnv -> TCEnv -> Interface -> [IL.Decl]
+> ilTransIntf tyEnv tcEnv (Interface m ds) = 
+>   foldr (translIntfDecl m tyEnv tcEnv) [] ds
+
+> translIntfDecl :: ModuleIdent -> ValueEnv -> TCEnv -> IDecl -> [IL.Decl] 
+>	         -> [IL.Decl]
+> translIntfDecl m tyEnv tcEnv (IDataDecl _ tc tvs cs) ds
+>   | not (isQualified tc) = 
+>     translIntfData m tyEnv tcEnv (unqualify tc) tvs cs : ds
+> translIntfDecl _ _ _ _ ds = ds
+
+> translIntfData :: ModuleIdent -> ValueEnv -> TCEnv -> Ident -> [Ident] 
+>	         -> [Maybe ConstrDecl] -> IL.Decl
+> translIntfData m tyEnv tcEnv tc tvs cs =
+>   IL.DataDecl (qualifyWith m tc) (length tvs)
+>               (map (maybe hiddenConstr 
+>	                    (translIntfConstrDecl m tyEnv tcEnv tvs)) cs)
+>   where hiddenConstr = IL.ConstrDecl qAnonId []
+>         qAnonId = qualify anonId
+
+> translIntfConstrDecl :: ModuleIdent -> ValueEnv -> TCEnv -> [Ident] 
+>                      -> ConstrDecl -> IL.ConstrDecl [IL.Type]
+> translIntfConstrDecl m tyEnv tcEnv tvs (ConstrDecl _ _ c tys) =
+>   IL.ConstrDecl (qualifyWith m c) (map (translType' m tyEnv tcEnv)
+>			                 (toQualTypes m tvs tys))
+>   -- IL.ConstrDecl (qualifyWith m c) (map translType (toQualTypes m tvs tys))
+> translIntfConstrDecl m tyEnv tcEnv tvs (ConOpDecl _ _ ty1 op ty2) =
+>   IL.ConstrDecl (qualifyWith m op)
+>                 (map (translType' m tyEnv tcEnv)
+>	               (toQualTypes m tvs [ty1,ty2]))
+>   -- IL.ConstrDecl (qualifyWith m op)
+>   --              (map translType (toQualTypes m tvs [ty1,ty2]))
+
+\end{verbatim}
+\paragraph{Types}
+The type representation in the intermediate language is the same as
+the internal representation except that it does not support
+constrained type variables and skolem types. The former are fixed and
+the later are replaced by fresh type constructors.
+
+Due to possible occurrence of record types, it is necessary to transform
+them back into their corresponding type constructors.
+\begin{verbatim}
+
+> translType' :: ModuleIdent -> ValueEnv -> TCEnv -> Type -> IL.Type
+> translType' m tyEnv tcEnv ty =
+>   translType (elimRecordTypes m tyEnv tcEnv (maximum (0:(typeVars ty))) ty)
+
+> translType :: Type -> IL.Type
+> translType (TypeConstructor tc tys) =
+>   IL.TypeConstructor tc (map translType tys)
+> translType (TypeVariable tv) = IL.TypeVariable tv
+> translType (TypeConstrained tys _) = translType (head tys)
+> translType (TypeArrow ty1 ty2) =
+>   IL.TypeArrow (translType ty1) (translType ty2)
+> translType (TypeSkolem k) =
+>   IL.TypeConstructor (qualify (mkIdent ("_" ++ show k))) []
+
+> elimRecordTypes :: ModuleIdent -> ValueEnv -> TCEnv -> Int -> Type -> Type
+> elimRecordTypes m tyEnv tcEnv n (TypeConstructor t tys) =
+>   TypeConstructor t (map (elimRecordTypes m tyEnv tcEnv n) tys)
+> elimRecordTypes m tyEnv tcEnv n (TypeVariable v) =
+>   TypeVariable v
+> elimRecordTypes m tyEnv tcEnv n (TypeConstrained tys v) =
+>   TypeConstrained (map (elimRecordTypes m tyEnv tcEnv n) tys) v
+> elimRecordTypes m tyEnv tcEnv n (TypeArrow t1 t2) =
+>   TypeArrow (elimRecordTypes m tyEnv tcEnv n t1)
+>             (elimRecordTypes m tyEnv tcEnv n t2)
+> elimRecordTypes m tyEnv tcEnv n (TypeSkolem v) =
+>   TypeSkolem v
+> elimRecordTypes m tyEnv tcEnv n (TypeRecord fs _)
+>   | null fs = internalError "elimRecordTypes: empty record type"
+>   | otherwise =
+>     case (lookupValue (fst (head fs)) tyEnv) of
+>       [Label _ r _] ->
+>         case (qualLookupTC r tcEnv) of
+>           [AliasType _ n' (TypeRecord fs' _)] ->
+>	      let is = [0 .. n'-1]
+>                 vs = foldl (matchTypeVars fs)
+>			     Map.empty
+>			     fs'
+>		  tys = map (\i -> maybe (TypeVariable (i+n))
+>			                 (elimRecordTypes m tyEnv tcEnv n)
+>		                         (Map.lookup i vs))
+>		            is 
+>	      in  TypeConstructor r tys
+>	    _ -> internalError "elimRecordTypes: no record type"
+>       _ -> internalError "elimRecordTypes: no label"
+
+> matchTypeVars :: [(Ident,Type)] -> Map.Map Int Type -> (Ident,Type) 
+>	           -> Map.Map Int Type
+> matchTypeVars fs vs (l,ty) =
+>   maybe vs (match vs ty) (lookup l fs)
+>   where
+>   match vs (TypeVariable i) ty' = Map.insert i ty' vs
+>   match vs (TypeConstructor _ tys) (TypeConstructor _ tys') =
+>     matchList vs tys tys'
+>   match vs (TypeConstrained tys _) (TypeConstrained tys' _) =
+>     matchList vs tys tys'
+>   match vs (TypeArrow ty1 ty2) (TypeArrow ty1' ty2') =
+>     matchList vs [ty1,ty2] [ty1',ty2']
+>   match vs (TypeSkolem _) (TypeSkolem _) = vs
+>   match vs (TypeRecord fs _) (TypeRecord fs' _) =
+>     foldl (matchTypeVars fs') vs fs
+>   match vs ty ty' = 
+>     internalError ("matchTypeVars: " ++ show ty ++ "\n" ++ show ty')
+>
+>   matchList vs tys tys' = 
+>     foldl (\vs' (ty,ty') -> match vs' ty ty') vs (zip tys tys')
+
+\end{verbatim}
+\paragraph{Functions}
+Each function in the program is translated into a function of the
+intermediate language. The arguments of the function are renamed such
+that all variables occurring in the same position (in different
+equations) have the same name. This is necessary in order to
+facilitate the translation of pattern matching into a \texttt{case}
+expression. We use the following simple convention here: The top-level
+arguments of the function are named from left to right \texttt{\_1},
+\texttt{\_2}, and so on. The names of nested arguments are constructed
+by appending \texttt{\_1}, \texttt{\_2}, etc. from left to right to
+the name that were assigned to a variable occurring at the position of
+the constructor term.
+
+Some special care is needed for the selector functions introduced by
+the compiler in place of pattern bindings. In order to generate the
+code for updating all pattern variables, the equality of names between
+the pattern variables in the first argument of the selector function
+and their repeated occurrences in the remaining arguments must be
+preserved. This means that the second and following arguments of a
+selector function have to be renamed according to the name mapping
+computed for its first argument.
+
+If an evaluation annotation is available for a function, it determines
+the evaluation mode of the case expression. Otherwise, the function
+uses flexible matching.
+\begin{verbatim}
+
+> type RenameEnv = Map.Map Ident Ident
+
+> translFunction :: Position -> Bool -> ModuleIdent -> ValueEnv -> TCEnv
+>       -> EvalEnv -> Ident -> [Equation] -> IL.Decl
+> translFunction pos flat m tyEnv tcEnv evEnv f eqs =
+>   -- | f == mkIdent "fun" = error (show (translType' m tyEnv tcEnv ty))
+>   -- | otherwise = 
+>     IL.FunctionDecl f' vs (translType' m tyEnv tcEnv ty) expr
+>    -- = IL.FunctionDecl f' vs (translType ty)
+>    --                  (match ev vs (map (translEquation tyEnv vs vs'') eqs))
+>   where f'  = qualifyWith m f
+>         ty  = varType tyEnv f'
+>         -- ty' = elimRecordType m tyEnv tcEnv (maximum (0:(typeVars ty))) ty
+>         ev' = Map.lookup f evEnv
+>         ev  = maybe (defaultMode ty) evalMode ev'
+>         vs  = if not flat && isFpSelectorId f then translArgs eqs vs' else vs'
+>         (vs',vs'') = splitAt (equationArity (head eqs)) 
+>                              (argNames (mkIdent ""))
+>         expr | ev' == Just EvalChoice
+>                = IL.Apply 
+>                    (IL.Function 
+>                       (qualifyWith preludeMIdent (mkIdent "commit"))
+>                       1)
+>                    (match (ast pos) IL.Rigid vs 
+>                       (map (translEquation tyEnv vs vs'') eqs))
+>              | otherwise
+>                =  match (ast pos) ev vs (map (translEquation tyEnv vs vs'') eqs)
+>         ---
+>         -- (vs',vs'') = splitAt (arrowArity ty) (argNames (mkIdent ""))
+
+> evalMode :: EvalAnnotation -> IL.Eval
+> evalMode EvalRigid = IL.Rigid
+> evalMode EvalChoice = error "eval choice is not yet supported"
+
+> defaultMode :: Type -> IL.Eval
+> defaultMode _ = IL.Flex
+>
+> --defaultMode ty = if isIO (arrowBase ty) then IL.Rigid else IL.Flex
+> --  where TypeConstructor qIOId _ = ioType undefined
+> --        isIO (TypeConstructor tc [_]) = tc == qIOId
+> --        isIO _ = False
+
+> translArgs :: [Equation] -> [Ident] -> [Ident]
+> translArgs [Equation _ (FunLhs _ (t:ts)) _] (v:_) =
+>   v : map (translArg (bindRenameEnv v t Map.empty)) ts
+>   where translArg env (VariablePattern v) = fromJust (Map.lookup v env)
+
+> translEquation :: ValueEnv -> [Ident] -> [Ident] -> Equation
+>                -> ([NestedTerm],IL.Expression)
+> translEquation tyEnv vs vs' (Equation _ (FunLhs _ ts) rhs) =
+>   (zipWith translTerm vs ts,
+>    translRhs tyEnv vs' (foldr2 bindRenameEnv Map.empty vs ts) rhs)
+
+> translRhs :: ValueEnv -> [Ident] -> RenameEnv -> Rhs -> IL.Expression
+> translRhs tyEnv vs env (SimpleRhs _ e _) = translExpr tyEnv vs env e
+
+
+> equationArity :: Equation -> Int
+> equationArity (Equation _ lhs _) = p_equArity lhs
+>  where
+>    p_equArity (FunLhs _ ts) = length ts
+>    p_equArity (OpLhs _ _ _) = 2
+>    p_equArity _             = error "ILTrans - illegal equation"
+
+
+\end{verbatim}
+\paragraph{Pattern Matching}
+The pattern matching code searches for the left-most inductive
+argument position in the left hand sides of all rules defining an
+equation. An inductive position is a position where all rules have a
+constructor rooted term. If such a position is found, a \texttt{case}
+expression is generated for the argument at that position. The
+matching code is then computed recursively for all of the alternatives
+independently. If no inductive position is found, the algorithm looks
+for the left-most demanded argument position, i.e., a position where
+at least one of the rules has a constructor rooted term. If such a
+position is found, an \texttt{or} expression is generated with those
+cases that have a variable at the argument position in one branch and
+all other rules in the other branch. If there is no demanded position,
+the pattern matching is finished and the compiler translates the right
+hand sides of the remaining rules, eventually combining them using
+\texttt{or} expressions.
+
+Actually, the algorithm below combines the search for inductive and
+demanded positions. The function \texttt{match} scans the argument
+lists for the left-most demanded position. If this turns out to be
+also an inductive position, the function \texttt{matchInductive} is
+called in order to generate a \texttt{case} expression. Otherwise, the
+function \texttt{optMatch} is called that tries to find an inductive
+position in the remaining arguments. If one is found,
+\texttt{matchInductive} is called, otherwise the function
+\texttt{optMatch} uses the demanded argument position found by
+\texttt{match}.
+\begin{verbatim}
+
+> data NestedTerm = NestedTerm IL.ConstrTerm [NestedTerm] deriving Show
+
+> pattern (NestedTerm t _) = t
+> arguments (NestedTerm _ ts) = ts
+
+> translLiteral :: Literal -> IL.Literal
+> translLiteral (Char p c) = IL.Char p c
+> translLiteral (Int id i) = IL.Int (ast (positionOfIdent id)) i
+> translLiteral (Float p f) = IL.Float p f
+> translLiteral _ = internalError "translLiteral"
+
+> translTerm :: Ident -> ConstrTerm -> NestedTerm
+> translTerm _ (LiteralPattern l) =
+>   NestedTerm (IL.LiteralPattern (translLiteral l)) []
+> translTerm v (VariablePattern _) = NestedTerm (IL.VariablePattern v) []
+> translTerm v (ConstructorPattern c ts) =
+>   NestedTerm (IL.ConstructorPattern c (take (length ts) vs))
+>              (zipWith translTerm vs ts)
+>   where vs = argNames v
+> translTerm v (AsPattern _ t) = translTerm v t
+> translTerm _ _ = internalError "translTerm"
+
+> bindRenameEnv :: Ident -> ConstrTerm -> RenameEnv -> RenameEnv
+> bindRenameEnv _ (LiteralPattern _) env = env
+> bindRenameEnv v (VariablePattern v') env = Map.insert v' v env
+> bindRenameEnv v (ConstructorPattern _ ts) env =
+>   foldr2 bindRenameEnv env (argNames v) ts
+> bindRenameEnv v (AsPattern v' t) env = Map.insert v' v (bindRenameEnv v t env)
+> bindRenameEnv _ _ env = internalError "bindRenameEnv"
+
+> argNames :: Ident -> [Ident]
+> argNames v = [mkIdent (prefix ++ show i) | i <- [1..]]
+>   where prefix = name v ++ "_"
+
+> type Match = ([NestedTerm],IL.Expression)
+> type Match' = ([NestedTerm] -> [NestedTerm],[NestedTerm],IL.Expression)
+
+> isDefaultPattern :: IL.ConstrTerm -> Bool
+> isDefaultPattern (IL.VariablePattern _) = True
+> isDefaultPattern _ = False
+
+> isDefaultMatch :: (IL.ConstrTerm,a) -> Bool
+> isDefaultMatch = isDefaultPattern . fst
+
+> match :: SrcRef -> IL.Eval -> [Ident] -> [Match] -> IL.Expression
+> match _   ev [] alts = foldl1 IL.Or (map snd alts)
+> match pos ev (v:vs) alts
+>   | null vars = e1
+>   | null nonVars = e2
+>   | otherwise = optMatch pos ev (IL.Or e1 e2) (v:) vs (map skipArg alts)
+>   where (vars,nonVars) = partition isDefaultMatch (map tagAlt alts)
+>         e1 = matchInductive pos ev id v vs nonVars
+>         e2 = match pos ev vs (map snd vars)
+>         tagAlt (t:ts,e) = (pattern t,(arguments t ++ ts,e))
+>         skipArg (t:ts,e) = ((t:),ts,e)
+
+> optMatch :: SrcRef -> IL.Eval -> IL.Expression -> ([Ident] -> [Ident]) 
+>    -> [Ident] ->[Match'] -> IL.Expression
+> optMatch _ ev e prefix [] alts = e
+> optMatch pos ev e prefix (v:vs) alts
+>   | null vars = matchInductive pos ev prefix v vs nonVars
+>   | otherwise = optMatch pos ev e (prefix . (v:)) vs (map skipArg alts)
+>   where (vars,nonVars) = partition isDefaultMatch (map tagAlt alts)
+>         tagAlt (prefix,t:ts,e) = (pattern t,(prefix (arguments t ++ ts),e))
+>         skipArg (prefix,t:ts,e) = (prefix . (t:),ts,e)
+
+> matchInductive :: SrcRef -> IL.Eval -> ([Ident] -> [Ident]) -> Ident 
+>    -> [Ident] ->[(IL.ConstrTerm,Match)] -> IL.Expression
+> matchInductive pos ev prefix v vs alts =
+>   IL.Case pos ev (IL.Variable v) (matchAlts ev prefix vs alts)
+
+> matchAlts :: IL.Eval -> ([Ident] -> [Ident]) -> [Ident] ->
+>     [(IL.ConstrTerm,Match)] -> [IL.Alt]
+> matchAlts ev prefix vs [] = []
+> matchAlts ev prefix vs ((t,alt):alts) =
+>   IL.Alt t (match (srcRefOf t) 
+>                   ev (prefix (vars t ++ vs)) (alt : map snd same)) :
+>   matchAlts ev prefix vs others
+>   where (same,others) = partition ((t ==) . fst) alts 
+>         vars (IL.ConstructorPattern _ vs) = vs
+>         vars _ = []
+
+\end{verbatim}
+Matching in a \texttt{case}-expression works a little bit differently.
+In this case, the alternatives are matched from the first to the last
+alternative and the first matching alternative is chosen. All
+remaining alternatives are discarded.
+
+\ToDo{The case matching algorithm should use type information in order
+to detect total matches and immediately discard all alternatives which
+cannot be reached.}
+\begin{verbatim}
+
+> caseMatch :: SrcRef -> ([Ident] -> [Ident]) -> [Ident] -> [Match'] 
+>    -> IL.Expression
+> caseMatch _ prefix [] alts = thd3 (head alts)
+> caseMatch r prefix (v:vs) alts
+>   | isDefaultMatch (head alts') =
+>       caseMatch r (prefix . (v:)) vs (map skipArg alts)
+>   | otherwise =
+>       IL.Case r IL.Rigid (IL.Variable v) (caseMatchAlts prefix vs alts')
+>   where alts' = map tagAlt alts
+>         tagAlt (prefix,t:ts,e) = (pattern t,(prefix,arguments t ++ ts,e))
+>         skipArg (prefix,t:ts,e) = (prefix . (t:),ts,e)
+
+> caseMatchAlts ::
+>     ([Ident] -> [Ident]) -> [Ident] -> [(IL.ConstrTerm,Match')] -> [IL.Alt]
+> caseMatchAlts prefix vs alts = map caseAlt (ts ++ ts')
+>   where (ts',ts) = partition isDefaultPattern (nub (map fst alts))
+>         caseAlt t =
+>           IL.Alt t (caseMatch (srcRefOf t) id (prefix (vars t ++ vs))
+>                               (matchingCases t alts))
+>         matchingCases t =
+>           map (joinArgs (vars t)) . filter (matches t . fst)
+>         matches t t' = t == t' || isDefaultPattern t'
+>         joinArgs vs (IL.VariablePattern _,(prefix,ts,e)) =
+>            (id,prefix (map varPattern vs ++ ts),e)
+>         joinArgs _ (_,(prefix,ts,e)) = (id,prefix ts,e)
+>         varPattern v = NestedTerm (IL.VariablePattern v) []
+>         vars (IL.ConstructorPattern _ vs) = vs
+>         vars _ = []
+
+\end{verbatim}
+\paragraph{Expressions}
+Note that the case matching algorithm assumes that the matched
+expression is accessible through a variable. The translation of case
+expressions therefore introduces a let binding for the scrutinized
+expression and immediately throws it away after the matching -- except
+if the matching algorithm has decided to use that variable in the
+right hand sides of the case expression. This may happen, for
+instance, if one of the alternatives contains an \texttt{@}-pattern.
+\begin{verbatim}
+
+> translExpr :: ValueEnv -> [Ident] -> RenameEnv -> Expression -> IL.Expression
+> translExpr _ _ _ (Literal l) = IL.Literal (translLiteral l)
+> translExpr tyEnv _ env (Variable v) =
+>   case lookupVar v env of
+>     Just v' -> IL.Variable v'
+>     Nothing -> IL.Function v (arrowArity (varType tyEnv v))
+>   where lookupVar v env
+>           | isQualified v = Nothing
+>           | otherwise = Map.lookup (unqualify v) env
+> translExpr tyEnv _ _ (Constructor c) =
+>   IL.Constructor c (arrowArity (constrType tyEnv c))
+> translExpr tyEnv vs env (Apply e1 e2) =
+>   IL.Apply (translExpr tyEnv vs env e1) (translExpr tyEnv vs env e2)
+> translExpr tyEnv vs env (Let ds e) =
+>   case ds of
+>     [ExtraVariables _ vs] -> foldr IL.Exist e' vs
+>     [d] | all (`notElem` bv d) (qfv emptyMIdent d) ->
+>       IL.Let (translBinding env' d) e'
+>     _ -> IL.Letrec (map (translBinding env') ds) e'
+>   where e' = translExpr tyEnv vs env' e
+>         env' = foldr2 Map.insert env bvs bvs
+>         bvs = bv ds
+>         translBinding env (PatternDecl _ (VariablePattern v) rhs) =
+>           IL.Binding v (translRhs tyEnv vs env rhs)
+>         translBinding env p = error $ "unexpected binding: "++show p
+> translExpr tyEnv ~(v:vs) env (Case r e alts) =
+>   case caseMatch r id [v] (map (translAlt v) alts) of
+>     IL.Case r mode (IL.Variable v') alts'
+>       | v == v' && v `notElem` fv alts' -> IL.Case r mode e' alts'
+>     e''
+>       | v `elem` fv e'' -> IL.Let (IL.Binding v e') e''
+>       | otherwise -> e''
+>   where e' = translExpr tyEnv vs env e
+>         translAlt v (Alt _ t rhs) =
+>           (id,
+>            [translTerm v t],
+>            translRhs tyEnv vs (bindRenameEnv v t env) rhs)
+> translExpr _ _ _ _ = internalError "translExpr"
+
+> instance Expr IL.Expression where
+>   fv (IL.Variable v) = [v]
+>   fv (IL.Apply e1 e2) = fv e1 ++ fv e2
+>   fv (IL.Case _ _ e alts) = fv e ++ fv alts
+>   fv (IL.Or e1 e2) = fv e1 ++ fv e2
+>   fv (IL.Exist v e) = filter (/= v) (fv e)
+>   fv (IL.Let (IL.Binding v e1) e2) = fv e1 ++ filter (/= v) (fv e2)
+>   fv (IL.Letrec bds e) = filter (`notElem` vs) (fv es ++ fv e)
+>     where (vs,es) = unzip [(v,e) | IL.Binding v e <- bds]
+>   fv _ = []
+
+> instance Expr IL.Alt where
+>   fv (IL.Alt (IL.ConstructorPattern _ vs) e) = filter (`notElem` vs) (fv e)
+>   fv (IL.Alt (IL.VariablePattern v) e) = filter (v /=) (fv e)
+>   fv (IL.Alt _ e) = fv e
+
+\end{verbatim}
+\paragraph{Auxiliary Definitions}
+The functions \texttt{varType} and \texttt{constrType} return the type
+of variables and constructors, respectively. The quantifiers are
+stripped from the types.
+\begin{verbatim}
+
+> varType :: ValueEnv -> QualIdent -> Type
+> varType tyEnv f =
+>   case qualLookupValue f tyEnv of
+>     [Value _ (ForAll _ ty)] -> ty
+>     _ -> internalError ("varType: " ++ show f)
+
+> constrType :: ValueEnv -> QualIdent -> Type
+> constrType tyEnv c =
+>   case qualLookupValue c tyEnv of
+>     [DataConstructor _ (ForAllExist _ _ ty)] -> ty
+>     [NewtypeConstructor _ (ForAllExist _ _ ty)] -> ty
+>     _ -> internalError ("constrType: " ++ show c)
+
+\end{verbatim}
+The list of import declarations in the intermediate language code is
+determined by collecting all module qualifiers used in the current
+module.
+\begin{verbatim}
+
+> imports :: ModuleIdent -> [IL.Decl] -> [ModuleIdent]
+> imports m = Set.toList . Set.delete m . Set.fromList . foldr modulesDecl []
+
+> modulesDecl :: IL.Decl -> [ModuleIdent] -> [ModuleIdent]
+> modulesDecl (IL.DataDecl _ _ cs) ms = foldr modulesConstrDecl ms cs
+>   where modulesConstrDecl (IL.ConstrDecl _ tys) ms = foldr modulesType ms tys
+> modulesDecl (IL.NewtypeDecl _ _ (IL.ConstrDecl _ ty)) ms = modulesType ty ms
+> modulesDecl (IL.FunctionDecl _ _ ty e) ms = modulesType ty (modulesExpr e ms)
+> modulesDecl (IL.ExternalDecl _ _ _ ty) ms = modulesType ty ms
+
+> modulesType :: IL.Type -> [ModuleIdent] -> [ModuleIdent]
+> modulesType (IL.TypeConstructor tc tys) ms =
+>   modules tc (foldr modulesType ms tys)
+> modulesType (IL.TypeVariable _) ms = ms
+> modulesType (IL.TypeArrow ty1 ty2) ms = modulesType ty1 (modulesType ty2 ms)
+
+> modulesExpr :: IL.Expression -> [ModuleIdent] -> [ModuleIdent]
+> modulesExpr (IL.Function f _) ms = modules f ms
+> modulesExpr (IL.Constructor c _) ms = modules c ms
+> modulesExpr (IL.Apply e1 e2) ms = modulesExpr e1 (modulesExpr e2 ms)
+> modulesExpr (IL.Case _ _ e as) ms = modulesExpr e (foldr modulesAlt ms as)
+>   where modulesAlt (IL.Alt t e) ms = modulesConstrTerm t (modulesExpr e ms)
+>         modulesConstrTerm (IL.ConstructorPattern c _) ms = modules c ms
+>         modulesConstrTerm _ ms = ms
+> modulesExpr (IL.Or e1 e2) ms = modulesExpr e1 (modulesExpr e2 ms)
+> modulesExpr (IL.Exist _ e) ms = modulesExpr e ms
+> modulesExpr (IL.Let b e) ms = modulesBinding b (modulesExpr e ms)
+> modulesExpr (IL.Letrec bs e) ms = foldr modulesBinding (modulesExpr e ms) bs
+> modulesExpr _ ms = ms
+
+> modulesBinding :: IL.Binding -> [ModuleIdent] -> [ModuleIdent]
+> modulesBinding (IL.Binding _ e) = modulesExpr e
+
+> modules :: QualIdent -> [ModuleIdent] -> [ModuleIdent]
+> modules x ms = maybe ms (: ms) (qualidMod x)
+
+\end{verbatim}
+
diff --git a/src/IL/Pretty.lhs b/src/IL/Pretty.lhs
new file mode 100644
--- /dev/null
+++ b/src/IL/Pretty.lhs
@@ -0,0 +1,167 @@
+% $Id: ILPP.lhs,v 1.22 2003/10/28 05:43:43 wlux Exp $
+%
+% Copyright (c) 1999-2003 Wolfgang Lux
+% See LICENSE for the full license.
+%
+% Modified by Martin Engelke (men@informatik.uni-kiel.de)
+%
+\nwfilename{ILPP.lhs}
+\section{A pretty printer for the intermediate language}
+This module implements just another pretty printer, this time for the
+intermediate language. It was mainly adapted from the Curry pretty
+printer (see sect.~\ref{sec:CurryPP}) which, in turn, is based on Simon
+Marlow's pretty printer for Haskell.
+\begin{verbatim}
+
+> module IL.Pretty(ppModule)  where
+> 
+> import Curry.Base.Ident
+> 
+> import IL.Type
+> import PrettyCombinators
+
+> default(Int,Double)
+
+> dataIndent = 2
+> bodyIndent = 2
+> exprIndent = 2
+> caseIndent = 2
+> altIndent = 2
+
+> ppModule :: Module -> Doc
+> ppModule (Module m is ds) =
+>   vcat (text "module" <+> text (show m) <+> text "where" :
+>         map ppImport is ++ map ppDecl ds)
+
+> ppImport :: ModuleIdent -> Doc
+> ppImport m = text "import" <+> text (show m)
+
+> ppDecl :: Decl -> Doc
+> ppDecl (DataDecl tc n cs) =
+>   sep (text "data" <+> ppTypeLhs tc n :
+>        map (nest dataIndent)
+>            (zipWith (<+>) (equals : repeat (char '|')) (map ppConstr cs)))
+> ppDecl (NewtypeDecl tc n (ConstrDecl c ty)) =
+>   sep [text "newtype" <+> ppTypeLhs tc n <+> equals,
+>        nest dataIndent (ppConstr (ConstrDecl c [ty]))]
+> ppDecl (FunctionDecl f vs ty exp) =
+>   ppTypeSig f ty $$
+>   sep [ppQIdent f <+> hsep (map ppIdent vs) <+> equals,
+>        nest bodyIndent (ppExpr 0 exp)]
+> ppDecl (ExternalDecl f cc ie ty) =
+>   sep [text "external" <+> ppCallConv cc <+> text (show ie),
+>        nest bodyIndent (ppTypeSig f ty)]
+>   where ppCallConv Primitive = text "primitive"
+>         ppCallConv CCall = text "ccall"
+
+> ppTypeLhs :: QualIdent -> Int -> Doc
+> ppTypeLhs tc n = ppQIdent tc <+> hsep (map text (take n typeVars))
+
+> ppConstr :: ConstrDecl [Type] -> Doc
+> ppConstr (ConstrDecl c tys) = ppQIdent c <+> fsep (map (ppType 2) tys)
+
+> ppTypeSig :: QualIdent -> Type -> Doc
+> ppTypeSig f ty = ppQIdent f <+> text "::" <+> ppType 0 ty
+
+> ppType :: Int -> Type -> Doc
+> ppType p (TypeConstructor tc tys)
+>   | isQTupleId tc = parens (fsep (punctuate comma (map (ppType 0) tys)))
+>   | unqualify tc == nilId = brackets (ppType 0 (head tys))
+>   | otherwise =
+>       ppParen (p > 1 && not (null tys))
+>               (ppQIdent tc <+> fsep (map (ppType 2) tys))
+> ppType _ (TypeVariable n)
+>   | n >= 0 = text (typeVars !! n)
+>   | otherwise = text ('_':show (-n))
+> ppType p (TypeArrow ty1 ty2) =
+>   ppParen (p > 0) (fsep (ppArrow (TypeArrow ty1 ty2)))
+>   where ppArrow (TypeArrow ty1 ty2) =
+>           ppType 1 ty1 <+> text "->" : ppArrow ty2
+>         ppArrow ty = [ppType 0 ty]
+
+> ppBinding :: Binding -> Doc
+> ppBinding (Binding v exp) =
+>   sep [ppIdent v <+> equals,nest bodyIndent (ppExpr 0 exp)]
+
+> ppAlt :: Alt -> Doc
+> ppAlt (Alt pat exp) =
+>   sep [ppConstrTerm pat <+> text "->",nest altIndent (ppExpr 0 exp)]
+
+> ppLiteral :: Literal -> Doc
+> ppLiteral (Char _ c) = text (show c)
+> ppLiteral (Int _ i) = integer i
+> ppLiteral (Float _ f) = double f
+
+> ppConstrTerm :: ConstrTerm -> Doc
+> ppConstrTerm (LiteralPattern l) = ppLiteral l
+> ppConstrTerm (ConstructorPattern c [v1,v2])
+>   | isQInfixOp c = ppIdent v1 <+> ppQInfixOp c <+> ppIdent v2
+> ppConstrTerm (ConstructorPattern c vs)
+>   | isQTupleId c = parens (fsep (punctuate comma (map ppIdent vs)))
+>   | otherwise = ppQIdent c <+> fsep (map ppIdent vs)
+> ppConstrTerm (VariablePattern v) = ppIdent v
+
+> ppExpr :: Int -> Expression -> Doc
+> ppExpr p (Literal l) = ppLiteral l
+> ppExpr p (Variable v) = ppIdent v
+> ppExpr p (Function f _) = ppQIdent f
+> ppExpr p (Constructor c _) = ppQIdent c
+> ppExpr p (Apply (Apply (Function f _) e1) e2)
+>   | isQInfixOp f = ppInfixApp p e1 f e2
+> ppExpr p (Apply (Apply (Constructor c _) e1) e2)
+>   | isQInfixOp c = ppInfixApp p e1 c e2
+> ppExpr p (Apply e1 e2) =
+>   ppParen (p > 2) (sep [ppExpr 2 e1,nest exprIndent (ppExpr 3 e2)])
+> ppExpr p (Case _ ev e alts) =
+>   ppParen (p > 0)
+>           (text "case" <+> ppEval ev <+> ppExpr 0 e <+> text "of" $$
+>            nest caseIndent (vcat (map ppAlt alts)))
+>   where ppEval Rigid = text "rigid"
+>         ppEval Flex = text "flex"
+> ppExpr p (Or e1 e2) =
+>   ppParen (p > 0) (sep [ppExpr 0 e1,char '|' <+> ppExpr 0 e2])
+> ppExpr p (Exist v e) =
+>   ppParen (p > 0)
+>           (sep [text "let" <+> ppIdent v <+> text "free" <+> text "in",
+>                 ppExpr 0 e])
+> ppExpr p (Let b e) =
+>   ppParen (p > 0) (sep [text "let" <+> ppBinding b <+> text "in",ppExpr 0 e])
+> ppExpr p (Letrec bs e) =
+>   ppParen (p > 0)
+>           (sep [text "letrec" <+> vcat (map ppBinding bs) <+> text "in",
+>                 ppExpr 0 e])
+
+> ppInfixApp :: Int -> Expression -> QualIdent -> Expression -> Doc
+> ppInfixApp p e1 op e2 =
+>   ppParen (p > 1)
+>           (sep [ppExpr 2 e1 <+> ppQInfixOp op,nest exprIndent (ppExpr 2 e2)])
+
+> ppIdent :: Ident -> Doc
+> ppIdent ident
+>   | isInfixOp ident = parens (ppName ident)
+>   | otherwise = ppName ident
+
+> ppQIdent :: QualIdent -> Doc
+> ppQIdent ident
+>   | isQInfixOp ident = parens (ppQual ident)
+>   | otherwise = ppQual ident
+
+> ppQInfixOp :: QualIdent -> Doc
+> ppQInfixOp op
+>   | isQInfixOp op = ppQual op
+>   | otherwise = char '`' <> ppQual op <> char '`'
+
+> ppName :: Ident -> Doc
+> ppName x = text (name x)
+
+> ppQual :: QualIdent -> Doc
+> ppQual x = text (qualName x)
+
+> typeVars :: [String]
+> typeVars = [mkTypeVar c i | i <- [0..], c <- ['a' .. 'z']]
+>   where mkTypeVar c i = c : if i == 0 then [] else show i
+
+> ppParen :: Bool -> Doc -> Doc
+> ppParen p = if p then parens else id
+
+\end{verbatim}
diff --git a/src/IL/Scope.hs b/src/IL/Scope.hs
new file mode 100644
--- /dev/null
+++ b/src/IL/Scope.hs
@@ -0,0 +1,124 @@
+module IL.Scope (getModuleScope,
+		insertDeclScope, insertConstrDeclScope,
+		insertCallConvScope, insertTypeScope,
+		insertLiteralScope, insertConstrTermScope,
+		insertExprScope, insertAltScope,
+		insertBindingScope) where
+
+import Curry.Base.Ident
+
+import IL.Type
+import OldScopeEnv as ScopeEnv
+
+
+-------------------------------------------------------------------------------
+
+--
+getModuleScope :: Module -> ScopeEnv
+getModuleScope (Module _ _ decls) = foldl insertDecl newScopeEnv decls
+
+
+--
+insertDeclScope :: ScopeEnv -> Decl -> ScopeEnv
+insertDeclScope env (DataDecl _ _ _) = env
+insertDeclScope env (NewtypeDecl _ _ _) = env
+insertDeclScope env (FunctionDecl _ params _ _)
+   = foldr ScopeEnv.insertIdent (ScopeEnv.beginScope env) params
+insertDeclScope env (ExternalDecl _ _ _ _) = env
+
+
+--
+insertConstrDeclScope :: ScopeEnv -> ConstrDecl [Type] -> ScopeEnv
+insertConstrDeclScope env _ = env
+
+
+--
+insertCallConvScope :: ScopeEnv -> CallConv -> ScopeEnv
+insertCallConvScope env _ = env
+
+
+--
+insertTypeScope :: ScopeEnv -> Type -> ScopeEnv
+insertTypeScope env _ = env
+
+
+--
+insertLiteralScope :: ScopeEnv -> Literal -> ScopeEnv
+insertLiteralScope env _ = env
+
+
+--
+insertConstrTermScope :: ScopeEnv -> ConstrTerm -> ScopeEnv
+insertConstrTermScope env _ = env
+
+
+--
+insertExprScope :: ScopeEnv -> Expression -> ScopeEnv
+insertExprScope env (Literal _) = env
+insertExprScope env (Variable _) = env
+insertExprScope env (Function _ _) = env
+insertExprScope env (Constructor _ _) = env
+insertExprScope env (Apply _ _) = env
+insertExprScope env (Case _ _ _ _) = env
+insertExprScope env (Or _ _) = env
+insertExprScope env (Exist ident _)
+   = ScopeEnv.insertIdent ident (ScopeEnv.beginScope env)
+insertExprScope env (Let bind _)
+   = insertBinding (beginScope env) bind
+insertExprScope env (Letrec binds _)
+   = foldl insertBinding (beginScope env) binds
+
+
+--
+insertAltScope :: ScopeEnv -> Alt -> ScopeEnv
+insertAltScope env (Alt cterm _)
+   = insertConstrTerm (ScopeEnv.beginScope env) cterm
+
+
+--
+insertBindingScope :: ScopeEnv -> Binding -> ScopeEnv
+insertBindingScope env _ = env
+
+
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+
+--
+insertDecl :: ScopeEnv -> Decl -> ScopeEnv
+insertDecl env (DataDecl qident _ cdecls)
+   = foldl insertConstrDecl
+	 (ScopeEnv.insertIdent (unqualify qident) env)
+	 cdecls
+
+insertDecl env (NewtypeDecl qident _ cdecl)
+   = insertConstrDecl (ScopeEnv.insertIdent (unqualify qident) env) cdecl
+
+insertDecl env (FunctionDecl qident _ _ _)
+   = ScopeEnv.insertIdent (unqualify qident) env
+
+insertDecl env (ExternalDecl qident _ _ _)
+   = ScopeEnv.insertIdent (unqualify qident) env
+
+
+--
+insertConstrDecl :: ScopeEnv -> ConstrDecl a -> ScopeEnv
+insertConstrDecl env (ConstrDecl qident _)
+   = ScopeEnv.insertIdent (unqualify qident) env
+
+
+--
+insertConstrTerm :: ScopeEnv -> ConstrTerm -> ScopeEnv
+insertConstrTerm env (LiteralPattern _) = env
+insertConstrTerm env (ConstructorPattern _ params)
+   = foldr ScopeEnv.insertIdent env params
+insertConstrTerm env (VariablePattern ident)
+   = ScopeEnv.insertIdent ident env
+
+
+--
+insertBinding :: ScopeEnv -> Binding -> ScopeEnv
+insertBinding env (Binding ident _) = ScopeEnv.insertIdent ident env
+
+
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
diff --git a/src/IL/Type.lhs b/src/IL/Type.lhs
new file mode 100644
--- /dev/null
+++ b/src/IL/Type.lhs
@@ -0,0 +1,109 @@
+% $Id: IL.lhs,v 1.18 2003/10/28 05:43:38 wlux Exp $
+%
+% Copyright (c) 1999-2003 Wolfgang Lux
+% See LICENSE for the full license.
+%
+% Modified by Martin Engelke (men@informatik.uni-kiel.de)
+%
+\nwfilename{IL.lhs}
+\section{The intermediate language}
+The module \texttt{IL} defines the intermediate language which will be
+compiled into abstract machine code. The intermediate language removes
+a lot of syntactic sugar from the Curry source language.  Top-level
+declarations are restricted to data type and function definitions. A
+newtype definition serves mainly as a hint to the backend that it must
+provide an auxiliary function for partial applications of the
+constructor. \textbf{Newtype constructors must not occur in patterns
+and may be used in expressions only as partial applications.}
+
+Type declarations use a de-Bruijn indexing scheme (starting at 0) for
+type variables. In the type of a function, all type variables are
+numbered in the order of their occurence from left to right, i.e., a
+type \texttt{(Int -> b) -> (a,b) -> c -> (a,c)} is translated into the
+type (using integer numbers to denote the type variables)
+\texttt{(Int -> 0) -> (1,0) -> 2 -> (1,2)}.
+
+Pattern matching in an equation is handled via flexible and rigid
+\texttt{Case} expressions. Overlapping rules are translated with the
+help of \texttt{Or} expressions. The intermediate language has three
+kinds of binding expressions, \texttt{Exist} expressions introduce a
+new logical variable, \texttt{Let} expression support a single
+non-recursive variable binding, and \texttt{Letrec} expressions
+introduce multiple variables with recursive initializer expressions.
+The intermediate language explicitly distinguishes (local) variables
+and (global) functions in expressions.
+
+\em{Note:} this modified version uses haskell type \texttt{Integer}
+instead of \texttt{Int} for representing integer values. This provides
+an unlimited range of integer constants in Curry programs.
+\begin{verbatim}
+
+> module IL.Type where
+
+> import Curry.Base.Ident
+> import Curry.Base.Position (SrcRef(..))
+
+> data Module = Module ModuleIdent [ModuleIdent] [Decl] deriving (Eq,Show)
+
+> data Decl = 
+>     DataDecl QualIdent Int [ConstrDecl [Type]]
+>   | NewtypeDecl QualIdent Int (ConstrDecl Type)
+>   | FunctionDecl QualIdent [Ident] Type Expression
+>   | ExternalDecl QualIdent CallConv String Type
+>   deriving (Eq,Show)
+
+> data ConstrDecl a = ConstrDecl QualIdent a deriving (Eq,Show)
+> data CallConv = Primitive | CCall deriving (Eq,Show)
+
+> data Type =
+>     TypeConstructor QualIdent [Type]
+>   | TypeVariable Int
+>   | TypeArrow Type Type
+>   deriving (Eq,Show)
+
+> data Literal = Char SrcRef Char | Int SrcRef Integer | Float SrcRef Double deriving (Eq,Show)
+
+> data ConstrTerm =
+>   -- literal patterns
+>     LiteralPattern Literal
+>   -- constructors
+>   | ConstructorPattern QualIdent [Ident]
+>   -- default
+>   | VariablePattern Ident
+>   deriving (Eq,Show)
+
+> data Expression =
+>   -- literal constants
+>     Literal Literal
+>   -- variables, functions, constructors
+>   | Variable Ident | Function QualIdent Int | Constructor QualIdent Int
+>   -- applications
+>   | Apply Expression Expression
+>   -- case expressions
+>   | Case SrcRef Eval Expression [Alt]
+>   -- non-determinisismic or
+>   | Or Expression Expression
+>   -- binding forms
+>   | Exist Ident Expression
+>   | Let Binding Expression
+>   | Letrec [Binding] Expression
+>   deriving (Eq,Show)
+
+> data Eval = Rigid | Flex deriving (Eq,Show)
+> data Alt = Alt ConstrTerm Expression deriving (Eq,Show)
+> data Binding = Binding Ident Expression deriving (Eq,Show)
+
+\end{verbatim}
+
+> instance SrcRefOf ConstrTerm where
+>   srcRefOf (LiteralPattern l) = srcRefOf l
+>   srcRefOf (ConstructorPattern i _) = srcRefOf i
+>   srcRefOf (VariablePattern i) = srcRefOf i
+
+
+> instance SrcRefOf Literal where
+>   srcRefOf (Char s _)   = s
+>   srcRefOf (Int s _)    = s
+>   srcRefOf (Float s _)  = s  
+
+
diff --git a/src/IL/XML.lhs b/src/IL/XML.lhs
new file mode 100644
--- /dev/null
+++ b/src/IL/XML.lhs
@@ -0,0 +1,518 @@
+
+% $Id: ILxml.lhs,v 1.0 2001/06/19 12:19:18 rafa Exp $
+%
+% $Log: ILxml.lhs,v $
+%
+% Revision 1.1  2001/06/19 12:19:18  rafa
+% Pretty printer in XML for the intermediate language added.
+%
+%
+% Modified by Martin Engelke (men@informatik.uni-kiel.de)
+%
+\nwfilename{ILxml.lhs}
+\section{A pretty printer in XML for the intermediate language}
+This module implements just another pretty printer, this time in XML and for
+the intermediate language. It was mainly adapted from the Curry pretty
+printer (see sect.~\ref{sec:CurryPP}), which in turn is based on Simon
+Marlow's pretty printer for Haskell. The format of the output intends to be
+similar to that of Flat-Curry XML representation.
+\begin{verbatim}
+
+> module IL.XML(module IL.XML) where
+
+> import Data.Maybe
+
+> import Curry.Base.Ident
+> import qualified Curry.Syntax as CS
+
+> import IL.Type
+> import CurryEnv
+> import PrettyCombinators
+
+
+
+> -- identation level
+> level::Int
+> level = 3
+
+> xmlModule :: CurryEnv -> Module -> Doc
+> xmlModule cEnv m = text "<prog>" $$ nest level (xmlBody cEnv m) 
+>	                           $$ text "</prog>"
+
+> xmlBody :: CurryEnv -> Module -> Doc
+> xmlBody cEnv (Module name imports decls) =
+>                   xmlElement "module"      xmlModuleDecl      moduleDecl   $$
+>                   xmlElement "import"      xmlImportDecl      importDecl   $$
+>                   xmlElement "types"       xmlTypeDecl        typeDecl     $$
+>                   xmlElement "functions"   xmlFunctionDecl    functionDecl $$
+>                   xmlElement "operators"   xmlOperatorDecl    operatorDecl $$
+>                   xmlElement "translation" xmlTranslationDecl translationDecl
+>               where
+>                 moduleDecl      = [name]
+>                 importDecl      = imports
+>                 operatorDecl    = infixDecls cEnv
+>                 translationDecl = foldl (qualIDeclId (moduleId cEnv))
+>			                  [] 
+>				          (interface cEnv)
+>                 (functionDecl,typeDecl) = splitDecls decls
+
+> -- =========================================================================
+
+> xmlModuleDecl :: ModuleIdent -> Doc
+> xmlModuleDecl name = xmlModuleIdent name
+
+> -- =========================================================================
+
+> xmlImportDecl :: ModuleIdent -> Doc
+> xmlImportDecl name = xmlElement "module" xmlModuleDecl  [name]
+
+
+> -- =========================================================================
+> --            T Y P E S
+> -- =========================================================================
+
+> xmlTypeDecl :: Decl -> Doc
+> xmlTypeDecl (DataDecl tc arity cs) =
+>   beginType                                  $$
+>   nest level (xmlTypeParams arity)           $$
+>   xmlLines xmlConstructor cs                 $$
+>   endType
+>  where
+>   beginType = text "<type name=\"" <> (xmlQualIdent tc) <> text "\">"
+>   endType   = text "</type>"
+
+> xmlTypeParams :: Int -> Doc
+> xmlTypeParams n = xmlElement "params" xmlTypeVar [0..(n-1)]
+
+> xmlConstructor :: ConstrDecl [Type] -> Doc
+> xmlConstructor (ConstrDecl ident []) = xmlConstructorBegin ident 0
+> xmlConstructor (ConstrDecl ident l)  =
+>   xmlConstructorBegin ident (length l) $$
+>   xmlLines xmlType l $$
+>   xmlConstructorEnd
+>  where
+>   xmlConstructorEnd = text "</cons>"
+
+> xmlConstructorBegin :: QualIdent -> Int -> Doc
+> xmlConstructorBegin ident n = xmlHeadingWithArity "cons" ident n (n==0)
+
+> xmlHeadingWithArity :: String -> QualIdent -> Int -> Bool -> Doc
+> xmlHeadingWithArity tagName ident n single =
+>   if single
+>   then prefix<>text "/>"
+>   else prefix<> text ">"
+>   where
+>     prefix = text ("<"++tagName++" name=\"") <> name <> text "\" " <> arity
+>     arity  = text "arity=\"" <> xmlInt n <> text "\""
+>     name   = xmlQualIdent ident
+
+
+> xmlType :: Type -> Doc
+> xmlType (TypeConstructor ident []) = xmlTypeConsBegin ident True
+> xmlType (TypeConstructor ident l)  = xmlTypeConsBegin ident False $$
+>                                      xmlLines xmlType l           $$
+>                                      xmlTypeConsEnd
+>                                      where
+>                                        xmlTypeConsEnd = text "</tcons>"
+
+> xmlType (TypeVariable n) = xmlTypeVar n
+> xmlType (TypeArrow  a b) = xmlTypeFun a b
+
+> xmlTypeConsBegin :: QualIdent -> Bool -> Doc
+> xmlTypeConsBegin ident single =
+>   if single
+>   then prefix <> text "/>"
+>   else prefix <> text ">"
+>   where
+>     name   = xmlQualIdent ident
+>     prefix = text "<tcons name=\"" <> name <> text "\""
+
+> xmlTypeVar :: Int -> Doc
+> xmlTypeVar n = text "<tvar>"<> xmlInt n <> text "</tvar>"
+
+> xmlTypeFun :: Type -> Type -> Doc
+> xmlTypeFun a b =  xmlElement "functype" xmlType  [a,b]
+
+
+> -- =========================================================================
+> --            F U N C T I O N S
+> -- =========================================================================
+
+> xmlFunctionDecl :: Decl -> Doc
+> xmlFunctionDecl (NewtypeDecl tc arity (ConstrDecl ident ty)) =
+>   xmlFunctionDecl (FunctionDecl ident [arg] ftype (Variable arg))
+>   where
+>    arg = mkIdent "_1"
+>    ftype = TypeArrow ty (TypeConstructor tc (map TypeVariable [0..arity-1]))
+
+> xmlFunctionDecl (FunctionDecl ident largs fType expr) =
+>    heading $$ nest level (xmlRule largs expr) $$ end
+>  where
+>    heading = xmlBeginFunction ident (length largs) fType
+>    end     = text "</func>"
+
+> xmlFunctionDecl (ExternalDecl ident callConv internalName fType) =
+>    heading $$ external $$ end
+>  where
+>    heading  = xmlBeginFunction ident (xmlFunctionArity fType) fType
+>    external = text ("<external>"
+>                     ++ xmlFormat internalName
+>                     ++ "</external>")
+>    end      = text "</func>"
+
+> xmlBeginFunction :: QualIdent -> Int -> Type -> Doc
+> xmlBeginFunction ident n fType =
+>    heading $$ typeDecls
+>    where
+>      heading   = xmlHeadingWithArity "func" ident n False
+>      typeDecls = nest level (xmlType fType)
+
+> xmlEndFunction ::  Doc
+> xmlEndFunction  = text "</func>"
+
+> xmlFunctionArity :: Type -> Int
+> xmlFunctionArity (TypeConstructor ident l) = 0
+> xmlFunctionArity (TypeVariable n)          = 0
+> xmlFunctionArity (TypeArrow  a b)          = 1 + (xmlFunctionArity b)
+
+> xmlRule :: [Ident] -> Expression -> Doc
+> xmlRule lArgs e = text "<rule>"               $$
+>                   nest level (xmlLhs lArgs)   $$
+>                   nest level (xmlRhs lArgs e) $$
+>                   text "</rule>"
+
+> xmlLhs :: [Ident] -> Doc
+> xmlLhs l  = xmlElement "lhs" xmlVar [0..((length l)-1)]
+
+> xmlRhs :: [Ident] -> Expression -> Doc
+> xmlRhs l e = text "<rhs>"  $$ nest level rhs $$ text "</rhs>"
+>              where
+>                varDicc    = xmlBuildDicc l
+>                (rhs, _) = xmlExpr varDicc e
+
+> -- =========================================================================
+
+> -- =========================================================================
+> --            E X P R E S S I O N S
+> -- =========================================================================
+
+> xmlExpr :: [(Int,Ident)] -> Expression -> (Doc,[(Int,Ident)])
+> xmlExpr d (Literal lit)  = (xmlLiteral (xmlLit lit),d)
+> xmlExpr d (Variable ident)  = xmlExprVar d ident
+> xmlExpr d (Function ident arity)    = (xmlSingleApp ident arity True,d)
+> xmlExpr d (Constructor ident arity) = (xmlSingleApp ident arity False,d)
+> xmlExpr d exp@(Apply e1 e2)         = xmlApply  d exp (xmlAppArgs exp)
+> xmlExpr d (Case _ eval expr alt)      = xmlCase   d eval expr alt
+> xmlExpr d (Or expr1 expr2)          = xmlOr     d expr1 expr2
+> xmlExpr d (Exist ident expr)        = xmlFree   d ident expr
+> xmlExpr d (Let binding expr)        = xmlLet    d binding expr
+> xmlExpr d (Letrec lBinding expr)    = xmlLetrec d lBinding expr
+>   --error "Recursive let bindings not supported in FlatCurry"
+
+> -- =========================================================================
+
+> xmlSingleApp :: QualIdent -> Int -> Bool -> Doc
+> xmlSingleApp ident arity isFunction =
+>    if arity>0
+>    then xmlCombHeading identDoc (text "PartCall") True
+>    else xmlCombHeading identDoc (text totalApp) True
+>    where
+>       identDoc = xmlQualIdent ident
+>       totalApp = if isFunction then "FuncCall" else "ConsCall"
+
+
+> xmlCombHeading :: Doc -> Doc -> Bool -> Doc
+> xmlCombHeading name cType single =
+>     if single
+>     then prefix <> text " />"
+>     else prefix <> text ">"
+>     where
+>       prefix = text "<comb type=\""<>cType<>text "\" name=\""<>name<>text "\""
+
+> -- =========================================================================
+
+> xmlExprVar :: [(Int,Ident)] -> Ident -> (Doc,[(Int,Ident)])
+> xmlExprVar d ident =
+>    if isNew
+>    then (xmlVar newVar, (newVar,ident):d)
+>    else (xmlVar var, d)
+>    where
+>       var    = xmlLookUp ident d
+>       isNew  = var == -1
+>       newVar = xmlNewVar d
+
+> -- =========================================================================
+
+
+> xmlApply :: [(Int,Ident)] -> Expression -> (Expression,[Expression]) ->
+>              (Doc,[(Int,Ident)])
+
+> xmlApply d exp ((Function ident arity),lExp) =
+>   xmlApplyFunctor d ident arity lExp True
+
+> xmlApply d exp ((Constructor ident arity),lExp) =
+>   xmlApplyFunctor d ident arity lExp False
+
+> xmlApply d (Apply expr1 expr2) e' =
+>   (text "<apply>" $$ nest level e1 $$ nest level e2 $$ text "</apply>", d2)
+>     where
+>        (e1,d1) = xmlExpr d  expr1
+>        (e2,d2) = xmlExpr d1 expr2
+
+> xmlApplyFunctor ::[(Int,Ident)] -> QualIdent -> Int -> [Expression] ->
+>                     Bool -> (Doc,[(Int,Ident)])
+> xmlApplyFunctor d ident arity lArgs isFunction =
+>    xmlCombApply d (xmlQualIdent ident)  (text cTypeS) n lArgs
+>    where
+>       n     = length (lArgs)
+>       cTypeS = if n==arity
+>               then if isFunction
+>                    then "FuncCall"
+>                    else "ConsCall"
+>               else "PartCall"
+
+
+> xmlCombApply :: [(Int,Ident)] -> Doc -> Doc -> Int ->
+>                                 [Expression] -> (Doc,[(Int,Ident)])
+> xmlCombApply d name cType 0 lArgs =
+>    (xmlCombHeading name cType True,d)
+> xmlCombApply d name cType n lArgs =
+>    (xmlCombHeading name cType False $$ xmlLines id lDocs$$ text "</comb>", d1)
+>    where
+>      (lDocs,d1) = xmlMapDicc d xmlExpr lArgs
+
+
+> xmlAppArgs :: Expression -> (Expression,[Expression])
+> xmlAppArgs (Apply e1 e2) = (e,lArgs++[e2])
+>                            where
+>                                (e,lArgs) = (xmlAppArgs e1)
+> xmlAppArgs e             = (e,[])
+> -- =========================================================================
+
+
+> -- =========================================================================
+
+> xmlCase :: [(Int,Ident)] -> Eval -> Expression -> [Alt] -> (Doc,[(Int,Ident)])
+> xmlCase d eval expr lAlt =
+>   (heading $$ nest level e1 $$ xmlLines id lDocs$$ end,d2)
+>   where
+>     sEval      = if eval==Rigid then "\"Rigid\"" else "\"Flex\""
+>     heading    = text "<case type=" <> text sEval <> text ">"
+>     end        = text "</case>"
+>     (e1,_)    = xmlExpr d expr
+>     (lDocs,d2) = xmlMapDicc d xmlBranch  lAlt
+
+> xmlOr :: [(Int,Ident)] -> Expression -> Expression -> (Doc,[(Int,Ident)])
+> xmlOr d  expr1 expr2 =
+>    (text "<or>" $$ nest level e1 $$ nest level e2 $$  text "</or>",d2)
+>    where
+>      (e1,d1) = xmlExpr d expr1
+>      (e2,d2) = xmlExpr d1 expr2
+
+
+> xmlBranch :: [(Int,Ident)] -> Alt -> (Doc,[(Int,Ident)])
+> xmlBranch d (Alt pattern expr) =
+>    (text "<branch>" $$ nest level e1 $$ nest level e2 $$ text "</branch>",d2)
+>    where
+>      (e1,d1) = xmlPattern d pattern
+>      (e2,d2) = xmlExpr d1 expr
+
+
+> xmlPattern :: [(Int,Ident)] -> ConstrTerm -> (Doc,[(Int,Ident)])
+> xmlPattern d (LiteralPattern lit) = (xmlLitPattern (xmlLit lit),d)
+> xmlPattern d (ConstructorPattern ident lArgs) = xmlConsPattern d ident  lArgs
+> xmlPattern d (VariablePattern _) = error "Variable patterns not allowed in Flat Curry"
+
+> xmlConsPattern :: [(Int,Ident)] -> QualIdent -> [Ident] -> (Doc,[(Int,Ident)])
+> xmlConsPattern d ident lArgs =
+>    (heading $$ xmlLines id lDocs $$ end,d2)
+>    where
+>      heading    = text "<pattern name=\""<> (xmlQualIdent ident) <>
+>                   text "\"" <> endh
+>      endh       = if (length lArgs)>0 then text ">" else text "/>"
+>      end        = if (length lArgs)>0 then text "</pattern>" else empty
+>      (lDocs,d2) = xmlMapDicc d xmlExprVar lArgs
+
+> -- =========================================================================
+
+
+> xmlFree :: [(Int,Ident)] -> Ident -> Expression -> (Doc,[(Int,Ident)])
+> xmlFree d ident exp =
+>  (text "<freevars>" $$ nest level v $$ nest level e $$ text "</freevars>",d2)
+>                    where
+>                       (v,d1) = xmlExprVar d  ident
+>                       (e,d2) = xmlExpr d1 exp
+
+
+> -- =========================================================================
+
+> xmlLet :: [(Int,Ident)] -> Binding -> Expression -> (Doc,[(Int,Ident)])
+> xmlLet d binding exp =
+>   (text "<let>" $$ nest level b $$ nest level e $$ text "</let>", d2)
+>   where
+>    (b,d1) = xmlBinding d binding
+>    (e,d2) = xmlExpr d1 exp
+
+> xmlBinding :: [(Int,Ident)] -> Binding -> (Doc,[(Int,Ident)])
+> xmlBinding d  (Binding ident exp) =
+>    (text "<binding>" $$ nest level v $$ nest level e $$ text "</binding>",d2)
+>    where
+>       (v,_)  = xmlExprVar d ident
+>       (e,d2) = xmlExpr d exp
+
+> -- =========================================================================
+
+> xmlLetrec :: [(Int,Ident)] -> [Binding] -> Expression -> (Doc,[(Int,Ident)])
+> xmlLetrec d lB exp =
+>   (text "<letrec>" $$ xmlLines id b $$ nest level e $$ text "</letrec>",d2)
+>   where
+>     (b,d1) = xmlMapDicc d xmlBinding lB
+>     (e,d2) = xmlExpr d1 exp
+
+> -- =========================================================================
+
+
+> -- =========================================================================
+> --            A U X I L I A R Y  F U N C T I O N S
+> -- =========================================================================
+
+> splitDecls :: [Decl] -> ([Decl],[Decl])
+> splitDecls []     = ([],[])
+> splitDecls (x:xs) = case x of
+>                      DataDecl     _ _ _   -> (functionDecl,x:typeDecl)
+>                      NewtypeDecl  _ _ _   -> (x:functionDecl,typeDecl)
+>                      FunctionDecl _ _ _ _ -> (x:functionDecl,typeDecl)
+>                      ExternalDecl _ _ _ _   -> (x:functionDecl,typeDecl)
+>                   where
+>                       (functionDecl,typeDecl) = splitDecls xs
+
+
+
+
+> xmlElement :: Eq a => String -> (a -> Doc) -> [a] -> Doc
+> xmlElement name f []     = text ("<"++name++" />")
+> xmlElement name f lDecls = beginElement $$ xmlLines f lDecls $$ endElement
+>                            where
+>                                beginElement = text ("<"++name++">")
+>                                endElement   = text ("</"++name++">")
+>
+
+> xmlLines :: (a -> Doc) -> [a] -> Doc
+> xmlLines f = (nest level).vcat.(map f)
+
+
+> xmlMapDicc::[(Int,Ident)] -> ([(Int,Ident)] -> a -> (Doc,[(Int,Ident)])) ->
+>              [a] -> ([Doc],[(Int,Ident)])
+> xmlMapDicc d f lArgs = foldl newArg ([],d) lArgs
+>                             where
+>                               newArg (l,d)  e = (l++[v'],d')
+>                                                 where (v',d') = f d e
+>
+
+
+> -- The dictionary identifies var names with integers
+> -- it will be ordered starting at the greatest integer
+> xmlBuildDicc :: [Ident] -> [(Int,Ident)]
+> xmlBuildDicc l = reverse (zip [0..((length l)-1)] l)
+
+> -- looks for a ident in the dictorionary. If it appears returns its
+> -- associated value. Otherwise, -1 is returned
+> xmlLookUp :: Ident -> [(Int,Ident)] -> Int
+> xmlLookUp ident []          = -1
+> xmlLookUp ident ((n,name):xs) = if ident==name
+>                                 then n
+>                                 else xmlLookUp ident xs
+
+> -- generates a integer corresponding to a new var
+> xmlNewVar :: [(Int,Ident)] -> Int
+> xmlNewVar []             = 0
+> xmlNewVar ((n,ident):xs) = n+1
+
+> xmlVar :: Int -> Doc
+> xmlVar n = text "<var>" <> xmlInt n <> text "</var>"
+
+> xmlLiteral :: Doc -> Doc
+> xmlLiteral d =   text "<lit>" $$ nest level d $$ text "</lit>"
+
+> xmlLitPattern :: Doc -> Doc
+> xmlLitPattern d =   text "<lpattern>" $$ nest level d $$ text "</lpattern>"
+
+
+> xmlLit :: Literal -> Doc
+> xmlLit (Char _ c) = text "<charc>" <>  xmlInt (fromEnum c) <> text "</charc>"
+> xmlLit (Int _ n) = text "<intc>" <>  xmlInteger n <> text "</intc>"
+> xmlLit (Float _ n) = text "<floatc>" <>  xmlFloat n <> text "</floatc>"
+
+> xmlOperatorDecl :: CS.IDecl -> Doc
+> xmlOperatorDecl (CS.IInfixDecl _ fixity prec qident) =
+>     text "<op fixity=\"" <> xmlFixity fixity 
+>     <> text "\" prec=\"" <> xmlInteger prec <> text "\">"
+>     <> xmlIdent (unqualify qident)
+>     <> text "</op>"
+
+> xmlFixity :: CS.Infix -> Doc
+> xmlFixity CS.InfixL = text "InfixlOp"
+> xmlFixity CS.InfixR = text "InfixrOp"
+> xmlFixity CS.Infix  = text "InfixOp"
+
+
+> xmlTranslationDecl :: QualIdent -> Doc
+> xmlTranslationDecl expId =
+>       text "<trans>" 
+>    $$ nest level (   text "<name>"    <> xmlIdent (unqualify expId) <> text "</name>"
+>                   $$ text "<intname>" <> xmlQualIdent expId         <> text "</intname>")
+>    $$ text "</trans>"
+
+
+> xmlIdent :: Ident -> Doc
+> xmlIdent ident = text (xmlFormat (name ident))
+
+> xmlInt :: Int -> Doc
+> xmlInt n = text (show n)
+
+> xmlInteger :: Integer -> Doc
+> xmlInteger n = text (show n)
+
+> xmlFloat :: Double -> Doc
+> xmlFloat n = text (show n)
+
+> xmlQualIdent :: QualIdent -> Doc
+> xmlQualIdent ident = text (xmlFormat (qualName ident))
+
+> xmlModuleIdent:: ModuleIdent -> Doc
+> xmlModuleIdent name = text (xmlFormat (moduleName name))
+
+> xmlFormat :: String -> String
+> xmlFormat []       = []
+> xmlFormat ('>':xs) = "&gt;"++xmlFormat xs
+> xmlFormat ('<':xs) = "&lt;"++xmlFormat xs
+> xmlFormat ('&':xs) = "&amp;"++xmlFormat xs
+> xmlFormat (x:xs)   = x:(xmlFormat xs)
+
+> -- =========================================================================
+
+> qualIDeclId :: ModuleIdent -> [QualIdent] -> CS.IDecl -> [QualIdent]
+> qualIDeclId mid qids (CS.IDataDecl _ qid _ mcdecls)
+>    = foldl (qualConstrDeclId mid) (qid:qids) (catMaybes mcdecls)
+> qualIDeclId mid qids (CS.INewtypeDecl _ qid _ ncdecl)
+>    = qualNewConstrDeclId mid (qid:qids) ncdecl
+> qualIDeclId mid qids (CS.ITypeDecl _ qid _ _)
+>    = qid:qids
+> qualIDeclId mid qids (CS.IFunctionDecl _ qid _ _)
+>    = qid:qids
+> qualIDeclId mid qids _ = qids
+
+> qualConstrDeclId :: ModuleIdent -> [QualIdent] -> CS.ConstrDecl 
+>	              -> [QualIdent]
+> qualConstrDeclId mid qids (CS.ConstrDecl _ _ id _)
+>    = (qualifyWith mid id):qids
+> qualConstrDeclId mid qids (CS.ConOpDecl _ _ _ id _)
+>    = (qualifyWith mid id):qids
+
+> qualNewConstrDeclId :: ModuleIdent -> [QualIdent] -> CS.NewConstrDecl 
+>	                 -> [QualIdent]
+> qualNewConstrDeclId mid qids (CS.NewConstrDecl _ _ id _)
+>    = (qualifyWith mid id):qids
+
+
+\end{verbatim}
diff --git a/src/ILPP.lhs b/src/ILPP.lhs
deleted file mode 100644
--- a/src/ILPP.lhs
+++ /dev/null
@@ -1,166 +0,0 @@
-% -*- LaTeX -*-
-% $Id: ILPP.lhs,v 1.22 2003/10/28 05:43:43 wlux Exp $
-%
-% Copyright (c) 1999-2003 Wolfgang Lux
-% See LICENSE for the full license.
-%
-% Modified by Martin Engelke (men@informatik.uni-kiel.de)
-%
-\nwfilename{ILPP.lhs}
-\section{A pretty printer for the intermediate language}
-This module implements just another pretty printer, this time for the
-intermediate language. It was mainly adapted from the Curry pretty
-printer (see sect.~\ref{sec:CurryPP}) which, in turn, is based on Simon
-Marlow's pretty printer for Haskell.
-\begin{verbatim}
-
-> module ILPP(module ILPP, Doc) where
-> import Ident
-> import IL
-> import Pretty
-
-> default(Int,Double)
-
-> dataIndent = 2
-> bodyIndent = 2
-> exprIndent = 2
-> caseIndent = 2
-> altIndent = 2
-
-> ppModule :: Module -> Doc
-> ppModule (Module m is ds) =
->   vcat (text "module" <+> text (show m) <+> text "where" :
->         map ppImport is ++ map ppDecl ds)
-
-> ppImport :: ModuleIdent -> Doc
-> ppImport m = text "import" <+> text (show m)
-
-> ppDecl :: Decl -> Doc
-> ppDecl (DataDecl tc n cs) =
->   sep (text "data" <+> ppTypeLhs tc n :
->        map (nest dataIndent)
->            (zipWith (<+>) (equals : repeat (char '|')) (map ppConstr cs)))
-> ppDecl (NewtypeDecl tc n (ConstrDecl c ty)) =
->   sep [text "newtype" <+> ppTypeLhs tc n <+> equals,
->        nest dataIndent (ppConstr (ConstrDecl c [ty]))]
-> ppDecl (FunctionDecl f vs ty exp) =
->   ppTypeSig f ty $$
->   sep [ppQIdent f <+> hsep (map ppIdent vs) <+> equals,
->        nest bodyIndent (ppExpr 0 exp)]
-> ppDecl (ExternalDecl f cc ie ty) =
->   sep [text "external" <+> ppCallConv cc <+> text (show ie),
->        nest bodyIndent (ppTypeSig f ty)]
->   where ppCallConv Primitive = text "primitive"
->         ppCallConv CCall = text "ccall"
-
-> ppTypeLhs :: QualIdent -> Int -> Doc
-> ppTypeLhs tc n = ppQIdent tc <+> hsep (map text (take n typeVars))
-
-> ppConstr :: ConstrDecl [Type] -> Doc
-> ppConstr (ConstrDecl c tys) = ppQIdent c <+> fsep (map (ppType 2) tys)
-
-> ppTypeSig :: QualIdent -> Type -> Doc
-> ppTypeSig f ty = ppQIdent f <+> text "::" <+> ppType 0 ty
-
-> ppType :: Int -> Type -> Doc
-> ppType p (TypeConstructor tc tys)
->   | isQTupleId tc = parens (fsep (punctuate comma (map (ppType 0) tys)))
->   | unqualify tc == nilId = brackets (ppType 0 (head tys))
->   | otherwise =
->       ppParen (p > 1 && not (null tys))
->               (ppQIdent tc <+> fsep (map (ppType 2) tys))
-> ppType _ (TypeVariable n)
->   | n >= 0 = text (typeVars !! n)
->   | otherwise = text ('_':show (-n))
-> ppType p (TypeArrow ty1 ty2) =
->   ppParen (p > 0) (fsep (ppArrow (TypeArrow ty1 ty2)))
->   where ppArrow (TypeArrow ty1 ty2) =
->           ppType 1 ty1 <+> text "->" : ppArrow ty2
->         ppArrow ty = [ppType 0 ty]
-
-> ppBinding :: Binding -> Doc
-> ppBinding (Binding v exp) =
->   sep [ppIdent v <+> equals,nest bodyIndent (ppExpr 0 exp)]
-
-> ppAlt :: Alt -> Doc
-> ppAlt (Alt pat exp) =
->   sep [ppConstrTerm pat <+> text "->",nest altIndent (ppExpr 0 exp)]
-
-> ppLiteral :: Literal -> Doc
-> ppLiteral (Char _ c) = text (show c)
-> ppLiteral (Int _ i) = integer i
-> ppLiteral (Float _ f) = double f
-
-> ppConstrTerm :: ConstrTerm -> Doc
-> ppConstrTerm (LiteralPattern l) = ppLiteral l
-> ppConstrTerm (ConstructorPattern c [v1,v2])
->   | isQInfixOp c = ppIdent v1 <+> ppQInfixOp c <+> ppIdent v2
-> ppConstrTerm (ConstructorPattern c vs)
->   | isQTupleId c = parens (fsep (punctuate comma (map ppIdent vs)))
->   | otherwise = ppQIdent c <+> fsep (map ppIdent vs)
-> ppConstrTerm (VariablePattern v) = ppIdent v
-
-> ppExpr :: Int -> Expression -> Doc
-> ppExpr p (Literal l) = ppLiteral l
-> ppExpr p (Variable v) = ppIdent v
-> ppExpr p (Function f _) = ppQIdent f
-> ppExpr p (Constructor c _) = ppQIdent c
-> ppExpr p (Apply (Apply (Function f _) e1) e2)
->   | isQInfixOp f = ppInfixApp p e1 f e2
-> ppExpr p (Apply (Apply (Constructor c _) e1) e2)
->   | isQInfixOp c = ppInfixApp p e1 c e2
-> ppExpr p (Apply e1 e2) =
->   ppParen (p > 2) (sep [ppExpr 2 e1,nest exprIndent (ppExpr 3 e2)])
-> ppExpr p (Case _ ev e alts) =
->   ppParen (p > 0)
->           (text "case" <+> ppEval ev <+> ppExpr 0 e <+> text "of" $$
->            nest caseIndent (vcat (map ppAlt alts)))
->   where ppEval Rigid = text "rigid"
->         ppEval Flex = text "flex"
-> ppExpr p (Or e1 e2) =
->   ppParen (p > 0) (sep [ppExpr 0 e1,char '|' <+> ppExpr 0 e2])
-> ppExpr p (Exist v e) =
->   ppParen (p > 0)
->           (sep [text "let" <+> ppIdent v <+> text "free" <+> text "in",
->                 ppExpr 0 e])
-> ppExpr p (Let b e) =
->   ppParen (p > 0) (sep [text "let" <+> ppBinding b <+> text "in",ppExpr 0 e])
-> ppExpr p (Letrec bs e) =
->   ppParen (p > 0)
->           (sep [text "letrec" <+> vcat (map ppBinding bs) <+> text "in",
->                 ppExpr 0 e])
-
-> ppInfixApp :: Int -> Expression -> QualIdent -> Expression -> Doc
-> ppInfixApp p e1 op e2 =
->   ppParen (p > 1)
->           (sep [ppExpr 2 e1 <+> ppQInfixOp op,nest exprIndent (ppExpr 2 e2)])
-
-> ppIdent :: Ident -> Doc
-> ppIdent ident
->   | isInfixOp ident = parens (ppName ident)
->   | otherwise = ppName ident
-
-> ppQIdent :: QualIdent -> Doc
-> ppQIdent ident
->   | isQInfixOp ident = parens (ppQual ident)
->   | otherwise = ppQual ident
-
-> ppQInfixOp :: QualIdent -> Doc
-> ppQInfixOp op
->   | isQInfixOp op = ppQual op
->   | otherwise = char '`' <> ppQual op <> char '`'
-
-> ppName :: Ident -> Doc
-> ppName x = text (name x)
-
-> ppQual :: QualIdent -> Doc
-> ppQual x = text (qualName x)
-
-> typeVars :: [String]
-> typeVars = [mkTypeVar c i | i <- [0..], c <- ['a' .. 'z']]
->   where mkTypeVar c i = c : if i == 0 then [] else show i
-
-> ppParen :: Bool -> Doc -> Doc
-> ppParen p = if p then parens else id
-
-\end{verbatim}
diff --git a/src/ILScope.hs b/src/ILScope.hs
deleted file mode 100644
--- a/src/ILScope.hs
+++ /dev/null
@@ -1,124 +0,0 @@
-module ILScope (getModuleScope,
-		insertDeclScope, insertConstrDeclScope,
-		insertCallConvScope, insertTypeScope,
-		insertLiteralScope, insertConstrTermScope,
-		insertExprScope, insertAltScope,
-		insertBindingScope) where
-
-
-import IL
-import Ident
-import OldScopeEnv as ScopeEnv
-
-
--------------------------------------------------------------------------------
-
---
-getModuleScope :: Module -> ScopeEnv
-getModuleScope (Module _ _ decls) = foldl insertDecl newScopeEnv decls
-
-
---
-insertDeclScope :: ScopeEnv -> Decl -> ScopeEnv
-insertDeclScope env (DataDecl _ _ _) = env
-insertDeclScope env (NewtypeDecl _ _ _) = env
-insertDeclScope env (FunctionDecl _ params _ _)
-   = foldr ScopeEnv.insertIdent (ScopeEnv.beginScope env) params
-insertDeclScope env (ExternalDecl _ _ _ _) = env
-
-
---
-insertConstrDeclScope :: ScopeEnv -> ConstrDecl [Type] -> ScopeEnv
-insertConstrDeclScope env _ = env
-
-
---
-insertCallConvScope :: ScopeEnv -> CallConv -> ScopeEnv
-insertCallConvScope env _ = env
-
-
---
-insertTypeScope :: ScopeEnv -> Type -> ScopeEnv
-insertTypeScope env _ = env
-
-
---
-insertLiteralScope :: ScopeEnv -> Literal -> ScopeEnv
-insertLiteralScope env _ = env
-
-
---
-insertConstrTermScope :: ScopeEnv -> ConstrTerm -> ScopeEnv
-insertConstrTermScope env _ = env
-
-
---
-insertExprScope :: ScopeEnv -> Expression -> ScopeEnv
-insertExprScope env (Literal _) = env
-insertExprScope env (Variable _) = env
-insertExprScope env (Function _ _) = env
-insertExprScope env (Constructor _ _) = env
-insertExprScope env (Apply _ _) = env
-insertExprScope env (Case _ _ _ _) = env
-insertExprScope env (Or _ _) = env
-insertExprScope env (Exist ident _)
-   = ScopeEnv.insertIdent ident (ScopeEnv.beginScope env)
-insertExprScope env (Let bind _)
-   = insertBinding (beginScope env) bind
-insertExprScope env (Letrec binds _)
-   = foldl insertBinding (beginScope env) binds
-
-
---
-insertAltScope :: ScopeEnv -> Alt -> ScopeEnv
-insertAltScope env (Alt cterm _)
-   = insertConstrTerm (ScopeEnv.beginScope env) cterm
-
-
---
-insertBindingScope :: ScopeEnv -> Binding -> ScopeEnv
-insertBindingScope env _ = env
-
-
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-
---
-insertDecl :: ScopeEnv -> Decl -> ScopeEnv
-insertDecl env (DataDecl qident _ cdecls)
-   = foldl insertConstrDecl
-	 (ScopeEnv.insertIdent (unqualify qident) env)
-	 cdecls
-
-insertDecl env (NewtypeDecl qident _ cdecl)
-   = insertConstrDecl (ScopeEnv.insertIdent (unqualify qident) env) cdecl
-
-insertDecl env (FunctionDecl qident _ _ _)
-   = ScopeEnv.insertIdent (unqualify qident) env
-
-insertDecl env (ExternalDecl qident _ _ _)
-   = ScopeEnv.insertIdent (unqualify qident) env
-
-
---
-insertConstrDecl :: ScopeEnv -> ConstrDecl a -> ScopeEnv
-insertConstrDecl env (ConstrDecl qident _)
-   = ScopeEnv.insertIdent (unqualify qident) env
-
-
---
-insertConstrTerm :: ScopeEnv -> ConstrTerm -> ScopeEnv
-insertConstrTerm env (LiteralPattern _) = env
-insertConstrTerm env (ConstructorPattern _ params)
-   = foldr ScopeEnv.insertIdent env params
-insertConstrTerm env (VariablePattern ident)
-   = ScopeEnv.insertIdent ident env
-
-
---
-insertBinding :: ScopeEnv -> Binding -> ScopeEnv
-insertBinding env (Binding ident _) = ScopeEnv.insertIdent ident env
-
-
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
diff --git a/src/ILTrans.lhs b/src/ILTrans.lhs
deleted file mode 100644
--- a/src/ILTrans.lhs
+++ /dev/null
@@ -1,595 +0,0 @@
-
-% $Id: ILTrans.lhs,v 1.86 2004/02/13 19:23:58 wlux Exp $
-%
-% Copyright (c) 1999-2003, Wolfgang Lux
-% See LICENSE for the full license.
-%
-% Modified by Martin Engelke (men@informatik.uni-kiel.de)
-%
-\nwfilename{ILTrans.lhs}
-\section{Translating Curry into the Intermediate Language}
-After desugaring and lifting have been performed, the source code is
-translated into the intermediate language. Besides translating from
-source terms and expressions into intermediate language terms and
-expressions this phase in particular has to implement the pattern
-matching algorithm for equations and case expressions.
-
-Because of name conflicts between the source and intermediate language
-data structures, we can use only a qualified import for the
-\texttt{IL} module.
-\begin{verbatim}
-
-> module ILTrans(ilTrans,ilTransIntf) where
-
-> import Data.Maybe
-> import Data.List
-> import qualified Data.Set as Set
-> import qualified Data.Map as Map
-
-> import Base
-> import qualified IL
-> import Utils
-> import Env
-
-
-
-
-\end{verbatim}
-\paragraph{Modules}
-At the top-level, the compiler has to translate data type, newtype,
-function, and external declarations. When translating a data type or
-newtype declaration, we ignore the types in the declaration and lookup
-the types of the constructors in the type environment instead because
-these types are already fully expanded, i.e., they do not include any
-alias types.
-\begin{verbatim}
-
-> ilTrans :: Bool -> ValueEnv -> TCEnv -> EvalEnv -> Module -> IL.Module
-> ilTrans flat tyEnv tcEnv evEnv (Module m _ ds) = 
->   IL.Module m (imports m ds') ds'
->   where ds' = concatMap (translGlobalDecl flat m tyEnv tcEnv evEnv) ds
-
-> translGlobalDecl :: Bool -> ModuleIdent -> ValueEnv -> TCEnv -> EvalEnv
->                  -> Decl -> [IL.Decl]
-> translGlobalDecl _ m tyEnv tcEnv _ (DataDecl _ tc tvs cs) =
->   [translData m tyEnv tcEnv tc tvs cs]
-> translGlobalDecl _ m tyEnv tcEnv _ (NewtypeDecl _ tc tvs nc) =
->   [translNewtype m tyEnv tcEnv tc tvs nc]
-> translGlobalDecl flat m tyEnv tcEnv evEnv (FunctionDecl pos f eqs) =
->   [translFunction pos flat m tyEnv tcEnv evEnv f eqs]
-> translGlobalDecl _ m tyEnv tcEnv _ (ExternalDecl _ cc ie f _) =
->   [translExternal m tyEnv tcEnv f cc (fromJust ie)]
-> translGlobalDecl _ _ _ _ _ _ = []
-
-> translData :: ModuleIdent -> ValueEnv -> TCEnv -> Ident -> [Ident] -> [ConstrDecl]
->            -> IL.Decl
-> translData m tyEnv tcEnv tc tvs cs =
->   IL.DataDecl (qualifyWith m tc) (length tvs)
->               (map (translConstrDecl m tyEnv tcEnv) cs)
-
-> translNewtype :: ModuleIdent -> ValueEnv -> TCEnv -> Ident -> [Ident] 
->	        -> NewConstrDecl -> IL.Decl
-> translNewtype m tyEnv tcEnv tc tvs (NewConstrDecl _ _ c _) =
->   IL.NewtypeDecl (qualifyWith m tc) (length tvs)
->                  (IL.ConstrDecl c' (translType' m tyEnv tcEnv ty))
->                  -- (IL.ConstrDecl c' (translType ty))
->   where c' = qualifyWith m c
->         TypeArrow ty _ = constrType tyEnv c'
-
-> translConstrDecl :: ModuleIdent -> ValueEnv -> TCEnv -> ConstrDecl
->                  -> IL.ConstrDecl [IL.Type]
-> translConstrDecl m tyEnv tcEnv d =
->   IL.ConstrDecl c' (map (translType' m tyEnv tcEnv)
->	                  (arrowArgs (constrType tyEnv c')))
->   -- IL.ConstrDecl c' (map translType (arrowArgs (constrType tyEnv c')))
->   where c' = qualifyWith m (constr d)
->         constr (ConstrDecl _ _ c _) = c
->         constr (ConOpDecl _ _ _ op _) = op
-
-> translExternal :: ModuleIdent -> ValueEnv -> TCEnv -> Ident -> CallConv
->                -> String -> IL.Decl
-> translExternal m tyEnv tcEnv f cc ie =
->   IL.ExternalDecl f' (callConv cc) ie 
->                   (translType' m tyEnv tcEnv (varType tyEnv f'))
->   -- IL.ExternalDecl f' (callConv cc) ie (translType (varType tyEnv f'))
->   where f' = qualifyWith m f
->         callConv CallConvPrimitive = IL.Primitive
->         callConv CallConvCCall = IL.CCall
-
-\end{verbatim}
-\paragraph{Interfaces}
-In order to generate code, the compiler also needs to know the tags
-and arities of all imported data constructors. For that reason we
-compile the data type declarations of all interfaces into the
-intermediate language, too. In this case we do not lookup the
-types in the environment because the types in the interfaces are
-already fully expanded. Note that we do not translate data types
-which are imported into the interface from some other module.
-\begin{verbatim}
-
-> ilTransIntf :: ValueEnv -> TCEnv -> Interface -> [IL.Decl]
-> ilTransIntf tyEnv tcEnv (Interface m ds) = 
->   foldr (translIntfDecl m tyEnv tcEnv) [] ds
-
-> translIntfDecl :: ModuleIdent -> ValueEnv -> TCEnv -> IDecl -> [IL.Decl] 
->	         -> [IL.Decl]
-> translIntfDecl m tyEnv tcEnv (IDataDecl _ tc tvs cs) ds
->   | not (isQualified tc) = 
->     translIntfData m tyEnv tcEnv (unqualify tc) tvs cs : ds
-> translIntfDecl _ _ _ _ ds = ds
-
-> translIntfData :: ModuleIdent -> ValueEnv -> TCEnv -> Ident -> [Ident] 
->	         -> [Maybe ConstrDecl] -> IL.Decl
-> translIntfData m tyEnv tcEnv tc tvs cs =
->   IL.DataDecl (qualifyWith m tc) (length tvs)
->               (map (maybe hiddenConstr 
->	                    (translIntfConstrDecl m tyEnv tcEnv tvs)) cs)
->   where hiddenConstr = IL.ConstrDecl qAnonId []
->         qAnonId = qualify anonId
-
-> translIntfConstrDecl :: ModuleIdent -> ValueEnv -> TCEnv -> [Ident] 
->                      -> ConstrDecl -> IL.ConstrDecl [IL.Type]
-> translIntfConstrDecl m tyEnv tcEnv tvs (ConstrDecl _ _ c tys) =
->   IL.ConstrDecl (qualifyWith m c) (map (translType' m tyEnv tcEnv)
->			                 (toQualTypes m tvs tys))
->   -- IL.ConstrDecl (qualifyWith m c) (map translType (toQualTypes m tvs tys))
-> translIntfConstrDecl m tyEnv tcEnv tvs (ConOpDecl _ _ ty1 op ty2) =
->   IL.ConstrDecl (qualifyWith m op)
->                 (map (translType' m tyEnv tcEnv)
->	               (toQualTypes m tvs [ty1,ty2]))
->   -- IL.ConstrDecl (qualifyWith m op)
->   --              (map translType (toQualTypes m tvs [ty1,ty2]))
-
-\end{verbatim}
-\paragraph{Types}
-The type representation in the intermediate language is the same as
-the internal representation except that it does not support
-constrained type variables and skolem types. The former are fixed and
-the later are replaced by fresh type constructors.
-
-Due to possible occurrence of record types, it is necessary to transform
-them back into their corresponding type constructors.
-\begin{verbatim}
-
-> translType' :: ModuleIdent -> ValueEnv -> TCEnv -> Type -> IL.Type
-> translType' m tyEnv tcEnv ty =
->   translType (elimRecordTypes m tyEnv tcEnv (maximum (0:(typeVars ty))) ty)
-
-> translType :: Type -> IL.Type
-> translType (TypeConstructor tc tys) =
->   IL.TypeConstructor tc (map translType tys)
-> translType (TypeVariable tv) = IL.TypeVariable tv
-> translType (TypeConstrained tys _) = translType (head tys)
-> translType (TypeArrow ty1 ty2) =
->   IL.TypeArrow (translType ty1) (translType ty2)
-> translType (TypeSkolem k) =
->   IL.TypeConstructor (qualify (mkIdent ("_" ++ show k))) []
-
-> elimRecordTypes :: ModuleIdent -> ValueEnv -> TCEnv -> Int -> Type -> Type
-> elimRecordTypes m tyEnv tcEnv n (TypeConstructor t tys) =
->   TypeConstructor t (map (elimRecordTypes m tyEnv tcEnv n) tys)
-> elimRecordTypes m tyEnv tcEnv n (TypeVariable v) =
->   TypeVariable v
-> elimRecordTypes m tyEnv tcEnv n (TypeConstrained tys v) =
->   TypeConstrained (map (elimRecordTypes m tyEnv tcEnv n) tys) v
-> elimRecordTypes m tyEnv tcEnv n (TypeArrow t1 t2) =
->   TypeArrow (elimRecordTypes m tyEnv tcEnv n t1)
->             (elimRecordTypes m tyEnv tcEnv n t2)
-> elimRecordTypes m tyEnv tcEnv n (TypeSkolem v) =
->   TypeSkolem v
-> elimRecordTypes m tyEnv tcEnv n (TypeRecord fs _)
->   | null fs = internalError "elimRecordTypes: empty record type"
->   | otherwise =
->     case (lookupValue (fst (head fs)) tyEnv) of
->       [Label _ r _] ->
->         case (qualLookupTC r tcEnv) of
->           [AliasType _ n' (TypeRecord fs' _)] ->
->	      let is = [0 .. n'-1]
->                 vs = foldl (matchTypeVars fs)
->			     Map.empty
->			     fs'
->		  tys = map (\i -> maybe (TypeVariable (i+n))
->			                 (elimRecordTypes m tyEnv tcEnv n)
->		                         (Map.lookup i vs))
->		            is 
->	      in  TypeConstructor r tys
->	    _ -> internalError "elimRecordTypes: no record type"
->       _ -> internalError "elimRecordTypes: no label"
-
-> matchTypeVars :: [(Ident,Type)] -> Map.Map Int Type -> (Ident,Type) 
->	           -> Map.Map Int Type
-> matchTypeVars fs vs (l,ty) =
->   maybe vs (match vs ty) (lookup l fs)
->   where
->   match vs (TypeVariable i) ty' = Map.insert i ty' vs
->   match vs (TypeConstructor _ tys) (TypeConstructor _ tys') =
->     matchList vs tys tys'
->   match vs (TypeConstrained tys _) (TypeConstrained tys' _) =
->     matchList vs tys tys'
->   match vs (TypeArrow ty1 ty2) (TypeArrow ty1' ty2') =
->     matchList vs [ty1,ty2] [ty1',ty2']
->   match vs (TypeSkolem _) (TypeSkolem _) = vs
->   match vs (TypeRecord fs _) (TypeRecord fs' _) =
->     foldl (matchTypeVars fs') vs fs
->   match vs ty ty' = 
->     internalError ("matchTypeVars: " ++ show ty ++ "\n" ++ show ty')
->
->   matchList vs tys tys' = 
->     foldl (\vs' (ty,ty') -> match vs' ty ty') vs (zip tys tys')
-
-\end{verbatim}
-\paragraph{Functions}
-Each function in the program is translated into a function of the
-intermediate language. The arguments of the function are renamed such
-that all variables occurring in the same position (in different
-equations) have the same name. This is necessary in order to
-facilitate the translation of pattern matching into a \texttt{case}
-expression. We use the following simple convention here: The top-level
-arguments of the function are named from left to right \texttt{\_1},
-\texttt{\_2}, and so on. The names of nested arguments are constructed
-by appending \texttt{\_1}, \texttt{\_2}, etc. from left to right to
-the name that were assigned to a variable occurring at the position of
-the constructor term.
-
-Some special care is needed for the selector functions introduced by
-the compiler in place of pattern bindings. In order to generate the
-code for updating all pattern variables, the equality of names between
-the pattern variables in the first argument of the selector function
-and their repeated occurrences in the remaining arguments must be
-preserved. This means that the second and following arguments of a
-selector function have to be renamed according to the name mapping
-computed for its first argument.
-
-If an evaluation annotation is available for a function, it determines
-the evaluation mode of the case expression. Otherwise, the function
-uses flexible matching.
-\begin{verbatim}
-
-> type RenameEnv = Env Ident Ident
-
-> translFunction :: Position -> Bool -> ModuleIdent -> ValueEnv -> TCEnv
->       -> EvalEnv -> Ident -> [Equation] -> IL.Decl
-> translFunction pos flat m tyEnv tcEnv evEnv f eqs =
->   -- | f == mkIdent "fun" = error (show (translType' m tyEnv tcEnv ty))
->   -- | otherwise = 
->     IL.FunctionDecl f' vs (translType' m tyEnv tcEnv ty) expr
->    -- = IL.FunctionDecl f' vs (translType ty)
->    --                  (match ev vs (map (translEquation tyEnv vs vs'') eqs))
->   where f'  = qualifyWith m f
->         ty  = varType tyEnv f'
->         -- ty' = elimRecordType m tyEnv tcEnv (maximum (0:(typeVars ty))) ty
->         ev' = lookupEval f evEnv
->         ev  = maybe (defaultMode ty) evalMode ev'
->         vs  = if not flat && isFpSelectorId f then translArgs eqs vs' else vs'
->         (vs',vs'') = splitAt (equationArity (head eqs)) 
->                              (argNames (mkIdent ""))
->         expr | ev' == Just EvalChoice
->                = IL.Apply 
->                    (IL.Function 
->                       (qualifyWith preludeMIdent (mkIdent "commit"))
->                       1)
->                    (match (ast pos) IL.Rigid vs 
->                       (map (translEquation tyEnv vs vs'') eqs))
->              | otherwise
->                =  match (ast pos) ev vs (map (translEquation tyEnv vs vs'') eqs)
->         ---
->         -- (vs',vs'') = splitAt (arrowArity ty) (argNames (mkIdent ""))
-
-> evalMode :: EvalAnnotation -> IL.Eval
-> evalMode EvalRigid = IL.Rigid
-> evalMode EvalChoice = error "eval choice is not yet supported"
-
-> defaultMode :: Type -> IL.Eval
-> defaultMode _ = IL.Flex
->
-> --defaultMode ty = if isIO (arrowBase ty) then IL.Rigid else IL.Flex
-> --  where TypeConstructor qIOId _ = ioType undefined
-> --        isIO (TypeConstructor tc [_]) = tc == qIOId
-> --        isIO _ = False
-
-> translArgs :: [Equation] -> [Ident] -> [Ident]
-> translArgs [Equation _ (FunLhs _ (t:ts)) _] (v:_) =
->   v : map (translArg (bindRenameEnv v t emptyEnv)) ts
->   where translArg env (VariablePattern v) = fromJust (lookupEnv v env)
-
-> translEquation :: ValueEnv -> [Ident] -> [Ident] -> Equation
->                -> ([NestedTerm],IL.Expression)
-> translEquation tyEnv vs vs' (Equation _ (FunLhs _ ts) rhs) =
->   (zipWith translTerm vs ts,
->    translRhs tyEnv vs' (foldr2 bindRenameEnv emptyEnv vs ts) rhs)
-
-> translRhs :: ValueEnv -> [Ident] -> RenameEnv -> Rhs -> IL.Expression
-> translRhs tyEnv vs env (SimpleRhs _ e _) = translExpr tyEnv vs env e
-
-
-> equationArity :: Equation -> Int
-> equationArity (Equation _ lhs _) = p_equArity lhs
->  where
->    p_equArity (FunLhs _ ts) = length ts
->    p_equArity (OpLhs _ _ _) = 2
->    p_equArity _             = error "ILTrans - illegal equation"
-
-
-\end{verbatim}
-\paragraph{Pattern Matching}
-The pattern matching code searches for the left-most inductive
-argument position in the left hand sides of all rules defining an
-equation. An inductive position is a position where all rules have a
-constructor rooted term. If such a position is found, a \texttt{case}
-expression is generated for the argument at that position. The
-matching code is then computed recursively for all of the alternatives
-independently. If no inductive position is found, the algorithm looks
-for the left-most demanded argument position, i.e., a position where
-at least one of the rules has a constructor rooted term. If such a
-position is found, an \texttt{or} expression is generated with those
-cases that have a variable at the argument position in one branch and
-all other rules in the other branch. If there is no demanded position,
-the pattern matching is finished and the compiler translates the right
-hand sides of the remaining rules, eventually combining them using
-\texttt{or} expressions.
-
-Actually, the algorithm below combines the search for inductive and
-demanded positions. The function \texttt{match} scans the argument
-lists for the left-most demanded position. If this turns out to be
-also an inductive position, the function \texttt{matchInductive} is
-called in order to generate a \texttt{case} expression. Otherwise, the
-function \texttt{optMatch} is called that tries to find an inductive
-position in the remaining arguments. If one is found,
-\texttt{matchInductive} is called, otherwise the function
-\texttt{optMatch} uses the demanded argument position found by
-\texttt{match}.
-\begin{verbatim}
-
-> data NestedTerm = NestedTerm IL.ConstrTerm [NestedTerm] deriving Show
-
-> pattern (NestedTerm t _) = t
-> arguments (NestedTerm _ ts) = ts
-
-> translLiteral :: Literal -> IL.Literal
-> translLiteral (Char p c) = IL.Char p c
-> translLiteral (Int id i) = IL.Int (ast (positionOfIdent id)) i
-> translLiteral (Float p f) = IL.Float p f
-> translLiteral _ = internalError "translLiteral"
-
-> translTerm :: Ident -> ConstrTerm -> NestedTerm
-> translTerm _ (LiteralPattern l) =
->   NestedTerm (IL.LiteralPattern (translLiteral l)) []
-> translTerm v (VariablePattern _) = NestedTerm (IL.VariablePattern v) []
-> translTerm v (ConstructorPattern c ts) =
->   NestedTerm (IL.ConstructorPattern c (take (length ts) vs))
->              (zipWith translTerm vs ts)
->   where vs = argNames v
-> translTerm v (AsPattern _ t) = translTerm v t
-> translTerm _ _ = internalError "translTerm"
-
-> bindRenameEnv :: Ident -> ConstrTerm -> RenameEnv -> RenameEnv
-> bindRenameEnv _ (LiteralPattern _) env = env
-> bindRenameEnv v (VariablePattern v') env = bindEnv v' v env
-> bindRenameEnv v (ConstructorPattern _ ts) env =
->   foldr2 bindRenameEnv env (argNames v) ts
-> bindRenameEnv v (AsPattern v' t) env = bindEnv v' v (bindRenameEnv v t env)
-> bindRenameEnv _ _ env = internalError "bindRenameEnv"
-
-> argNames :: Ident -> [Ident]
-> argNames v = [mkIdent (prefix ++ show i) | i <- [1..]]
->   where prefix = name v ++ "_"
-
-> type Match = ([NestedTerm],IL.Expression)
-> type Match' = ([NestedTerm] -> [NestedTerm],[NestedTerm],IL.Expression)
-
-> isDefaultPattern :: IL.ConstrTerm -> Bool
-> isDefaultPattern (IL.VariablePattern _) = True
-> isDefaultPattern _ = False
-
-> isDefaultMatch :: (IL.ConstrTerm,a) -> Bool
-> isDefaultMatch = isDefaultPattern . fst
-
-> match :: SrcRef -> IL.Eval -> [Ident] -> [Match] -> IL.Expression
-> match _   ev [] alts = foldl1 IL.Or (map snd alts)
-> match pos ev (v:vs) alts
->   | null vars = e1
->   | null nonVars = e2
->   | otherwise = optMatch pos ev (IL.Or e1 e2) (v:) vs (map skipArg alts)
->   where (vars,nonVars) = partition isDefaultMatch (map tagAlt alts)
->         (nonArgs,args) = partition (null.fst) alts
->         e1 = matchInductive pos ev id v vs nonVars
->         e2 = match pos ev vs (map snd vars)
->         tagAlt (t:ts,e) = (pattern t,(arguments t ++ ts,e))
->         skipArg (t:ts,e) = ((t:),ts,e)
-
-> optMatch :: SrcRef -> IL.Eval -> IL.Expression -> ([Ident] -> [Ident]) 
->    -> [Ident] ->[Match'] -> IL.Expression
-> optMatch _ ev e prefix [] alts = e
-> optMatch pos ev e prefix (v:vs) alts
->   | null vars = matchInductive pos ev prefix v vs nonVars
->   | otherwise = optMatch pos ev e (prefix . (v:)) vs (map skipArg alts)
->   where (vars,nonVars) = partition isDefaultMatch (map tagAlt alts)
->         tagAlt (prefix,t:ts,e) = (pattern t,(prefix (arguments t ++ ts),e))
->         skipArg (prefix,t:ts,e) = (prefix . (t:),ts,e)
-
-> matchInductive :: SrcRef -> IL.Eval -> ([Ident] -> [Ident]) -> Ident 
->    -> [Ident] ->[(IL.ConstrTerm,Match)] -> IL.Expression
-> matchInductive pos ev prefix v vs alts =
->   IL.Case pos ev (IL.Variable v) (matchAlts ev prefix vs alts)
-
-> matchAlts :: IL.Eval -> ([Ident] -> [Ident]) -> [Ident] ->
->     [(IL.ConstrTerm,Match)] -> [IL.Alt]
-> matchAlts ev prefix vs [] = []
-> matchAlts ev prefix vs ((t,alt):alts) =
->   IL.Alt t (match (srcRefOf t) 
->                   ev (prefix (vars t ++ vs)) (alt : map snd same)) :
->   matchAlts ev prefix vs others
->   where (same,others) = partition ((t ==) . fst) alts 
->         vars (IL.ConstructorPattern _ vs) = vs
->         vars _ = []
-
-\end{verbatim}
-Matching in a \texttt{case}-expression works a little bit differently.
-In this case, the alternatives are matched from the first to the last
-alternative and the first matching alternative is chosen. All
-remaining alternatives are discarded.
-
-\ToDo{The case matching algorithm should use type information in order
-to detect total matches and immediately discard all alternatives which
-cannot be reached.}
-\begin{verbatim}
-
-> caseMatch :: SrcRef -> ([Ident] -> [Ident]) -> [Ident] -> [Match'] 
->    -> IL.Expression
-> caseMatch _ prefix [] alts = thd3 (head alts)
-> caseMatch r prefix (v:vs) alts
->   | isDefaultMatch (head alts') =
->       caseMatch r (prefix . (v:)) vs (map skipArg alts)
->   | otherwise =
->       IL.Case r IL.Rigid (IL.Variable v) (caseMatchAlts prefix vs alts')
->   where alts' = map tagAlt alts
->         tagAlt (prefix,t:ts,e) = (pattern t,(prefix,arguments t ++ ts,e))
->         skipArg (prefix,t:ts,e) = (prefix . (t:),ts,e)
-
-> caseMatchAlts ::
->     ([Ident] -> [Ident]) -> [Ident] -> [(IL.ConstrTerm,Match')] -> [IL.Alt]
-> caseMatchAlts prefix vs alts = map caseAlt (ts ++ ts')
->   where (ts',ts) = partition isDefaultPattern (nub (map fst alts))
->         caseAlt t =
->           IL.Alt t (caseMatch (srcRefOf t) id (prefix (vars t ++ vs))
->                               (matchingCases t alts))
->         matchingCases t =
->           map (joinArgs (vars t)) . filter (matches t . fst)
->         matches t t' = t == t' || isDefaultPattern t'
->         joinArgs vs (IL.VariablePattern _,(prefix,ts,e)) =
->            (id,prefix (map varPattern vs ++ ts),e)
->         joinArgs _ (_,(prefix,ts,e)) = (id,prefix ts,e)
->         varPattern v = NestedTerm (IL.VariablePattern v) []
->         vars (IL.ConstructorPattern _ vs) = vs
->         vars _ = []
-
-\end{verbatim}
-\paragraph{Expressions}
-Note that the case matching algorithm assumes that the matched
-expression is accessible through a variable. The translation of case
-expressions therefore introduces a let binding for the scrutinized
-expression and immediately throws it away after the matching -- except
-if the matching algorithm has decided to use that variable in the
-right hand sides of the case expression. This may happen, for
-instance, if one of the alternatives contains an \texttt{@}-pattern.
-\begin{verbatim}
-
-> translExpr :: ValueEnv -> [Ident] -> RenameEnv -> Expression -> IL.Expression
-> translExpr _ _ _ (Literal l) = IL.Literal (translLiteral l)
-> translExpr tyEnv _ env (Variable v) =
->   case lookupVar v env of
->     Just v' -> IL.Variable v'
->     Nothing -> IL.Function v (arrowArity (varType tyEnv v))
->   where lookupVar v env
->           | isQualified v = Nothing
->           | otherwise = lookupEnv (unqualify v) env
-> translExpr tyEnv _ _ (Constructor c) =
->   IL.Constructor c (arrowArity (constrType tyEnv c))
-> translExpr tyEnv vs env (Apply e1 e2) =
->   IL.Apply (translExpr tyEnv vs env e1) (translExpr tyEnv vs env e2)
-> translExpr tyEnv vs env (Let ds e) =
->   case ds of
->     [ExtraVariables _ vs] -> foldr IL.Exist e' vs
->     [d] | all (`notElem` bv d) (qfv emptyMIdent d) ->
->       IL.Let (translBinding env' d) e'
->     _ -> IL.Letrec (map (translBinding env') ds) e'
->   where e' = translExpr tyEnv vs env' e
->         env' = foldr2 bindEnv env bvs bvs
->         bvs = bv ds
->         translBinding env (PatternDecl _ (VariablePattern v) rhs) =
->           IL.Binding v (translRhs tyEnv vs env rhs)
->         translBinding env p = error $ "unexpected binding: "++show p
-> translExpr tyEnv ~(v:vs) env (Case r e alts) =
->   case caseMatch r id [v] (map (translAlt v) alts) of
->     IL.Case r mode (IL.Variable v') alts'
->       | v == v' && v `notElem` fv alts' -> IL.Case r mode e' alts'
->     e''
->       | v `elem` fv e'' -> IL.Let (IL.Binding v e') e''
->       | otherwise -> e''
->   where e' = translExpr tyEnv vs env e
->         translAlt v (Alt _ t rhs) =
->           (id,
->            [translTerm v t],
->            translRhs tyEnv vs (bindRenameEnv v t env) rhs)
-> translExpr _ _ _ _ = internalError "translExpr"
-
-> instance Expr IL.Expression where
->   fv (IL.Variable v) = [v]
->   fv (IL.Apply e1 e2) = fv e1 ++ fv e2
->   fv (IL.Case _ _ e alts) = fv e ++ fv alts
->   fv (IL.Or e1 e2) = fv e1 ++ fv e2
->   fv (IL.Exist v e) = filter (/= v) (fv e)
->   fv (IL.Let (IL.Binding v e1) e2) = fv e1 ++ filter (/= v) (fv e2)
->   fv (IL.Letrec bds e) = filter (`notElem` vs) (fv es ++ fv e)
->     where (vs,es) = unzip [(v,e) | IL.Binding v e <- bds]
->   fv _ = []
-
-> instance Expr IL.Alt where
->   fv (IL.Alt (IL.ConstructorPattern _ vs) e) = filter (`notElem` vs) (fv e)
->   fv (IL.Alt (IL.VariablePattern v) e) = filter (v /=) (fv e)
->   fv (IL.Alt _ e) = fv e
-
-\end{verbatim}
-\paragraph{Auxiliary Definitions}
-The functions \texttt{varType} and \texttt{constrType} return the type
-of variables and constructors, respectively. The quantifiers are
-stripped from the types.
-\begin{verbatim}
-
-> varType :: ValueEnv -> QualIdent -> Type
-> varType tyEnv f =
->   case qualLookupValue f tyEnv of
->     [Value _ (ForAll _ ty)] -> ty
->     _ -> internalError ("varType: " ++ show f)
-
-> constrType :: ValueEnv -> QualIdent -> Type
-> constrType tyEnv c =
->   case qualLookupValue c tyEnv of
->     [DataConstructor _ (ForAllExist _ _ ty)] -> ty
->     [NewtypeConstructor _ (ForAllExist _ _ ty)] -> ty
->     _ -> internalError ("constrType: " ++ show c)
-
-\end{verbatim}
-The list of import declarations in the intermediate language code is
-determined by collecting all module qualifiers used in the current
-module.
-\begin{verbatim}
-
-> imports :: ModuleIdent -> [IL.Decl] -> [ModuleIdent]
-> imports m = Set.toList . Set.delete m . Set.fromList . foldr modulesDecl []
-
-> modulesDecl :: IL.Decl -> [ModuleIdent] -> [ModuleIdent]
-> modulesDecl (IL.DataDecl _ _ cs) ms = foldr modulesConstrDecl ms cs
->   where modulesConstrDecl (IL.ConstrDecl _ tys) ms = foldr modulesType ms tys
-> modulesDecl (IL.NewtypeDecl _ _ (IL.ConstrDecl _ ty)) ms = modulesType ty ms
-> modulesDecl (IL.FunctionDecl _ _ ty e) ms = modulesType ty (modulesExpr e ms)
-> modulesDecl (IL.ExternalDecl _ _ _ ty) ms = modulesType ty ms
-
-> modulesType :: IL.Type -> [ModuleIdent] -> [ModuleIdent]
-> modulesType (IL.TypeConstructor tc tys) ms =
->   modules tc (foldr modulesType ms tys)
-> modulesType (IL.TypeVariable _) ms = ms
-> modulesType (IL.TypeArrow ty1 ty2) ms = modulesType ty1 (modulesType ty2 ms)
-
-> modulesExpr :: IL.Expression -> [ModuleIdent] -> [ModuleIdent]
-> modulesExpr (IL.Function f _) ms = modules f ms
-> modulesExpr (IL.Constructor c _) ms = modules c ms
-> modulesExpr (IL.Apply e1 e2) ms = modulesExpr e1 (modulesExpr e2 ms)
-> modulesExpr (IL.Case _ _ e as) ms = modulesExpr e (foldr modulesAlt ms as)
->   where modulesAlt (IL.Alt t e) ms = modulesConstrTerm t (modulesExpr e ms)
->         modulesConstrTerm (IL.ConstructorPattern c _) ms = modules c ms
->         modulesConstrTerm _ ms = ms
-> modulesExpr (IL.Or e1 e2) ms = modulesExpr e1 (modulesExpr e2 ms)
-> modulesExpr (IL.Exist _ e) ms = modulesExpr e ms
-> modulesExpr (IL.Let b e) ms = modulesBinding b (modulesExpr e ms)
-> modulesExpr (IL.Letrec bs e) ms = foldr modulesBinding (modulesExpr e ms) bs
-> modulesExpr _ ms = ms
-
-> modulesBinding :: IL.Binding -> [ModuleIdent] -> [ModuleIdent]
-> modulesBinding (IL.Binding _ e) = modulesExpr e
-
-> modules :: QualIdent -> [ModuleIdent] -> [ModuleIdent]
-> modules x ms = maybe ms (: ms) (fst (splitQualIdent x))
-
-\end{verbatim}
-
diff --git a/src/ILxml.lhs b/src/ILxml.lhs
deleted file mode 100644
--- a/src/ILxml.lhs
+++ /dev/null
@@ -1,518 +0,0 @@
-
-% $Id: ILxml.lhs,v 1.0 2001/06/19 12:19:18 rafa Exp $
-%
-% $Log: ILxml.lhs,v $
-%
-% Revision 1.1  2001/06/19 12:19:18  rafa
-% Pretty printer in XML for the intermediate language added.
-%
-%
-% Modified by Martin Engelke (men@informatik.uni-kiel.de)
-%
-\nwfilename{ILxml.lhs}
-\section{A pretty printer in XML for the intermediate language}
-This module implements just another pretty printer, this time in XML and for
-the intermediate language. It was mainly adapted from the Curry pretty
-printer (see sect.~\ref{sec:CurryPP}), which in turn is based on Simon
-Marlow's pretty printer for Haskell. The format of the output intends to be
-similar to that of Flat-Curry XML representation.
-\begin{verbatim}
-
-> module ILxml(module ILxml, Doc) where
-
-> import Data.Maybe
-> import Data.Char(chr,ord,isAlphaNum)
-
-> import Ident
-> import IL
-> import qualified CurrySyntax as CS
-> import CurryEnv
-> import Pretty
-
-
-
-> -- identation level
-> level::Int
-> level = 3
-
-> xmlModule :: CurryEnv -> Module -> Doc
-> xmlModule cEnv m = text "<prog>" $$ nest level (xmlBody cEnv m) 
->	                           $$ text "</prog>"
-
-> xmlBody :: CurryEnv -> Module -> Doc
-> xmlBody cEnv (Module name imports decls) =
->                   xmlElement "module"      xmlModuleDecl      moduleDecl   $$
->                   xmlElement "import"      xmlImportDecl      importDecl   $$
->                   xmlElement "types"       xmlTypeDecl        typeDecl     $$
->                   xmlElement "functions"   xmlFunctionDecl    functionDecl $$
->                   xmlElement "operators"   xmlOperatorDecl    operatorDecl $$
->                   xmlElement "translation" xmlTranslationDecl translationDecl
->               where
->                 moduleDecl      = [name]
->                 importDecl      = imports
->                 operatorDecl    = infixDecls cEnv
->                 translationDecl = foldl (qualIDeclId (moduleId cEnv))
->			                  [] 
->				          (interface cEnv)
->                 (functionDecl,typeDecl) = splitDecls decls
-
-> -- =========================================================================
-
-> xmlModuleDecl :: ModuleIdent -> Doc
-> xmlModuleDecl name = xmlModuleIdent name
-
-> -- =========================================================================
-
-> xmlImportDecl :: ModuleIdent -> Doc
-> xmlImportDecl name = xmlElement "module" xmlModuleDecl  [name]
-
-
-> -- =========================================================================
-> --            T Y P E S
-> -- =========================================================================
-
-> xmlTypeDecl :: Decl -> Doc
-> xmlTypeDecl (DataDecl tc arity cs) =
->   beginType                                  $$
->   nest level (xmlTypeParams arity)           $$
->   xmlLines xmlConstructor cs                 $$
->   endType
->  where
->   beginType = text "<type name=\"" <> (xmlQualIdent tc) <> text "\">"
->   endType   = text "</type>"
-
-> xmlTypeParams :: Int -> Doc
-> xmlTypeParams n = xmlElement "params" xmlTypeVar [0..(n-1)]
-
-> xmlConstructor :: ConstrDecl [Type] -> Doc
-> xmlConstructor (ConstrDecl ident []) = xmlConstructorBegin ident 0
-> xmlConstructor (ConstrDecl ident l)  =
->   xmlConstructorBegin ident (length l) $$
->   xmlLines xmlType l $$
->   xmlConstructorEnd
->  where
->   xmlConstructorEnd = text "</cons>"
-
-> xmlConstructorBegin :: QualIdent -> Int -> Doc
-> xmlConstructorBegin ident n = xmlHeadingWithArity "cons" ident n (n==0)
-
-> xmlHeadingWithArity :: String -> QualIdent -> Int -> Bool -> Doc
-> xmlHeadingWithArity tagName ident n single =
->   if single
->   then prefix<>text "/>"
->   else prefix<> text ">"
->   where
->     prefix = text ("<"++tagName++" name=\"") <> name <> text "\" " <> arity
->     arity  = text "arity=\"" <> xmlInt n <> text "\""
->     name   = xmlQualIdent ident
-
-
-> xmlType :: Type -> Doc
-> xmlType (TypeConstructor ident []) = xmlTypeConsBegin ident True
-> xmlType (TypeConstructor ident l)  = xmlTypeConsBegin ident False $$
->                                      xmlLines xmlType l           $$
->                                      xmlTypeConsEnd
->                                      where
->                                        xmlTypeConsEnd = text "</tcons>"
-
-> xmlType (TypeVariable n) = xmlTypeVar n
-> xmlType (TypeArrow  a b) = xmlTypeFun a b
-
-> xmlTypeConsBegin :: QualIdent -> Bool -> Doc
-> xmlTypeConsBegin ident single =
->   if single
->   then prefix <> text "/>"
->   else prefix <> text ">"
->   where
->     name   = xmlQualIdent ident
->     prefix = text "<tcons name=\"" <> name <> text "\""
-
-> xmlTypeVar :: Int -> Doc
-> xmlTypeVar n = text "<tvar>"<> xmlInt n <> text "</tvar>"
-
-> xmlTypeFun :: Type -> Type -> Doc
-> xmlTypeFun a b =  xmlElement "functype" xmlType  [a,b]
-
-
-> -- =========================================================================
-> --            F U N C T I O N S
-> -- =========================================================================
-
-> xmlFunctionDecl :: Decl -> Doc
-> xmlFunctionDecl (NewtypeDecl tc arity (ConstrDecl ident ty)) =
->   xmlFunctionDecl (FunctionDecl ident [arg] ftype (Variable arg))
->   where
->    arg = mkIdent "_1"
->    ftype = TypeArrow ty (TypeConstructor tc (map TypeVariable [0..arity-1]))
-
-> xmlFunctionDecl (FunctionDecl ident largs fType expr) =
->    heading $$ nest level (xmlRule largs expr) $$ end
->  where
->    heading = xmlBeginFunction ident (length largs) fType
->    end     = text "</func>"
-
-> xmlFunctionDecl (ExternalDecl ident callConv internalName fType) =
->    heading $$ external $$ end
->  where
->    heading  = xmlBeginFunction ident (xmlFunctionArity fType) fType
->    external = text ("<external>"
->                     ++ xmlFormat internalName
->                     ++ "</external>")
->    end      = text "</func>"
-
-> xmlBeginFunction :: QualIdent -> Int -> Type -> Doc
-> xmlBeginFunction ident n fType =
->    heading $$ typeDecls
->    where
->      heading   = xmlHeadingWithArity "func" ident n False
->      typeDecls = nest level (xmlType fType)
-
-> xmlEndFunction ::  Doc
-> xmlEndFunction  = text "</func>"
-
-> xmlFunctionArity :: Type -> Int
-> xmlFunctionArity (TypeConstructor ident l) = 0
-> xmlFunctionArity (TypeVariable n)          = 0
-> xmlFunctionArity (TypeArrow  a b)          = 1 + (xmlFunctionArity b)
-
-> xmlRule :: [Ident] -> Expression -> Doc
-> xmlRule lArgs e = text "<rule>"               $$
->                   nest level (xmlLhs lArgs)   $$
->                   nest level (xmlRhs lArgs e) $$
->                   text "</rule>"
-
-> xmlLhs :: [Ident] -> Doc
-> xmlLhs l  = xmlElement "lhs" xmlVar [0..((length l)-1)]
-
-> xmlRhs :: [Ident] -> Expression -> Doc
-> xmlRhs l e = text "<rhs>"  $$ nest level rhs $$ text "</rhs>"
->              where
->                varDicc    = xmlBuildDicc l
->                (rhs,dicc) = xmlExpr varDicc e
-
-> -- =========================================================================
-
-> -- =========================================================================
-> --            E X P R E S S I O N S
-> -- =========================================================================
-
-> xmlExpr :: [(Int,Ident)] -> Expression -> (Doc,[(Int,Ident)])
-> xmlExpr d (Literal lit)  = (xmlLiteral (xmlLit lit),d)
-> xmlExpr d (Variable ident)  = xmlExprVar d ident
-> xmlExpr d (Function ident arity)    = (xmlSingleApp ident arity True,d)
-> xmlExpr d (Constructor ident arity) = (xmlSingleApp ident arity False,d)
-> xmlExpr d exp@(Apply e1 e2)         = xmlApply  d exp (xmlAppArgs exp)
-> xmlExpr d (Case _ eval expr alt)      = xmlCase   d eval expr alt
-> xmlExpr d (Or expr1 expr2)          = xmlOr     d expr1 expr2
-> xmlExpr d (Exist ident expr)        = xmlFree   d ident expr
-> xmlExpr d (Let binding expr)        = xmlLet    d binding expr
-> xmlExpr d (Letrec lBinding expr)    = xmlLetrec d lBinding expr
->   --error "Recursive let bindings not supported in FlatCurry"
-
-> -- =========================================================================
-
-> xmlSingleApp :: QualIdent -> Int -> Bool -> Doc
-> xmlSingleApp ident arity isFunction =
->    if arity>0
->    then xmlCombHeading identDoc (text "PartCall") True
->    else xmlCombHeading identDoc (text totalApp) True
->    where
->       identDoc = xmlQualIdent ident
->       totalApp = if isFunction then "FuncCall" else "ConsCall"
-
-
-> xmlCombHeading :: Doc -> Doc -> Bool -> Doc
-> xmlCombHeading name cType single =
->     if single
->     then prefix <> text " />"
->     else prefix <> text ">"
->     where
->       prefix = text "<comb type=\""<>cType<>text "\" name=\""<>name<>text "\""
-
-> -- =========================================================================
-
-> xmlExprVar :: [(Int,Ident)] -> Ident -> (Doc,[(Int,Ident)])
-> xmlExprVar d ident =
->    if isNew
->    then (xmlVar newVar, (newVar,ident):d)
->    else (xmlVar var, d)
->    where
->       var    = xmlLookUp ident d
->       isNew  = var == -1
->       newVar = xmlNewVar d
-
-> -- =========================================================================
-
-
-> xmlApply :: [(Int,Ident)] -> Expression -> (Expression,[Expression]) ->
->              (Doc,[(Int,Ident)])
-
-> xmlApply d exp ((Function ident arity),lExp) =
->   xmlApplyFunctor d ident arity lExp True
-
-> xmlApply d exp ((Constructor ident arity),lExp) =
->   xmlApplyFunctor d ident arity lExp False
-
-> xmlApply d (Apply expr1 expr2) e' =
->   (text "<apply>" $$ nest level e1 $$ nest level e2 $$ text "</apply>", d2)
->     where
->        (e1,d1) = xmlExpr d  expr1
->        (e2,d2) = xmlExpr d1 expr2
-
-> xmlApplyFunctor ::[(Int,Ident)] -> QualIdent -> Int -> [Expression] ->
->                     Bool -> (Doc,[(Int,Ident)])
-> xmlApplyFunctor d ident arity lArgs isFunction =
->    xmlCombApply d (xmlQualIdent ident)  (text cTypeS) n lArgs
->    where
->       n     = length (lArgs)
->       cTypeS = if n==arity
->               then if isFunction
->                    then "FuncCall"
->                    else "ConsCall"
->               else "PartCall"
-
-
-> xmlCombApply :: [(Int,Ident)] -> Doc -> Doc -> Int ->
->                                 [Expression] -> (Doc,[(Int,Ident)])
-> xmlCombApply d name cType 0 lArgs =
->    (xmlCombHeading name cType True,d)
-> xmlCombApply d name cType n lArgs =
->    (xmlCombHeading name cType False $$ xmlLines id lDocs$$ text "</comb>", d1)
->    where
->      (lDocs,d1) = xmlMapDicc d xmlExpr lArgs
-
-
-> xmlAppArgs :: Expression -> (Expression,[Expression])
-> xmlAppArgs (Apply e1 e2) = (e,lArgs++[e2])
->                            where
->                                (e,lArgs) = (xmlAppArgs e1)
-> xmlAppArgs e             = (e,[])
-> -- =========================================================================
-
-
-> -- =========================================================================
-
-> xmlCase :: [(Int,Ident)] -> Eval -> Expression -> [Alt] -> (Doc,[(Int,Ident)])
-> xmlCase d eval expr lAlt =
->   (heading $$ nest level e1 $$ xmlLines id lDocs$$ end,d2)
->   where
->     sEval      = if eval==Rigid then "\"Rigid\"" else "\"Flex\""
->     heading    = text "<case type=" <> text sEval <> text ">"
->     end        = text "</case>"
->     (e1,d1)    = xmlExpr d expr
->     (lDocs,d2) = xmlMapDicc d xmlBranch  lAlt
-
-> xmlOr :: [(Int,Ident)] -> Expression -> Expression -> (Doc,[(Int,Ident)])
-> xmlOr d  expr1 expr2 =
->    (text "<or>" $$ nest level e1 $$ nest level e2 $$  text "</or>",d2)
->    where
->      (e1,d1) = xmlExpr d expr1
->      (e2,d2) = xmlExpr d1 expr2
-
-
-> xmlBranch :: [(Int,Ident)] -> Alt -> (Doc,[(Int,Ident)])
-> xmlBranch d (Alt pattern expr) =
->    (text "<branch>" $$ nest level e1 $$ nest level e2 $$ text "</branch>",d2)
->    where
->      (e1,d1) = xmlPattern d pattern
->      (e2,d2) = xmlExpr d1 expr
-
-
-> xmlPattern :: [(Int,Ident)] -> ConstrTerm -> (Doc,[(Int,Ident)])
-> xmlPattern d (LiteralPattern lit) = (xmlLitPattern (xmlLit lit),d)
-> xmlPattern d (ConstructorPattern ident lArgs) = xmlConsPattern d ident  lArgs
-> xmlPattern d (VariablePattern _) = error "Variable patterns not allowed in Flat Curry"
-
-> xmlConsPattern :: [(Int,Ident)] -> QualIdent -> [Ident] -> (Doc,[(Int,Ident)])
-> xmlConsPattern d ident lArgs =
->    (heading $$ xmlLines id lDocs $$ end,d2)
->    where
->      heading    = text "<pattern name=\""<> (xmlQualIdent ident) <>
->                   text "\"" <> endh
->      endh       = if (length lArgs)>0 then text ">" else text "/>"
->      end        = if (length lArgs)>0 then text "</pattern>" else empty
->      (lDocs,d2) = xmlMapDicc d xmlExprVar lArgs
-
-> -- =========================================================================
-
-
-> xmlFree :: [(Int,Ident)] -> Ident -> Expression -> (Doc,[(Int,Ident)])
-> xmlFree d ident exp =
->  (text "<freevars>" $$ nest level v $$ nest level e $$ text "</freevars>",d2)
->                    where
->                       (v,d1) = xmlExprVar d  ident
->                       (e,d2) = xmlExpr d1 exp
-
-
-> -- =========================================================================
-
-> xmlLet :: [(Int,Ident)] -> Binding -> Expression -> (Doc,[(Int,Ident)])
-> xmlLet d binding exp =
->   (text "<let>" $$ nest level b $$ nest level e $$ text "</let>", d2)
->   where
->    (b,d1) = xmlBinding d binding
->    (e,d2) = xmlExpr d1 exp
-
-> xmlBinding :: [(Int,Ident)] -> Binding -> (Doc,[(Int,Ident)])
-> xmlBinding d  (Binding ident exp) =
->    (text "<binding>" $$ nest level v $$ nest level e $$ text "</binding>",d2)
->    where
->       (v,d1) = xmlExprVar d ident
->       (e,d2) = xmlExpr d exp
-
-> -- =========================================================================
-
-> xmlLetrec :: [(Int,Ident)] -> [Binding] -> Expression -> (Doc,[(Int,Ident)])
-> xmlLetrec d lB exp =
->   (text "<letrec>" $$ xmlLines id b $$ nest level e $$ text "</letrec>",d2)
->   where
->     (b,d1) = xmlMapDicc d xmlBinding lB
->     (e,d2) = xmlExpr d1 exp
-
-> -- =========================================================================
-
-
-> -- =========================================================================
-> --            A U X I L I A R Y  F U N C T I O N S
-> -- =========================================================================
-
-> splitDecls :: [Decl] -> ([Decl],[Decl])
-> splitDecls []     = ([],[])
-> splitDecls (x:xs) = case x of
->                      DataDecl     _ _ _   -> (functionDecl,x:typeDecl)
->                      NewtypeDecl  _ _ _   -> (x:functionDecl,typeDecl)
->                      FunctionDecl _ _ _ _ -> (x:functionDecl,typeDecl)
->                      ExternalDecl _ _ _ _   -> (x:functionDecl,typeDecl)
->                   where
->                       (functionDecl,typeDecl) = splitDecls xs
-
-
-
-
-> xmlElement :: Eq a => String -> (a -> Doc) -> [a] -> Doc
-> xmlElement name f []     = text ("<"++name++" />")
-> xmlElement name f lDecls = beginElement $$ xmlLines f lDecls $$ endElement
->                            where
->                                beginElement = text ("<"++name++">")
->                                endElement   = text ("</"++name++">")
->
-
-> xmlLines :: (a -> Doc) -> [a] -> Doc
-> xmlLines f = (nest level).vcat.(map f)
-
-
-> xmlMapDicc::[(Int,Ident)] -> ([(Int,Ident)] -> a -> (Doc,[(Int,Ident)])) ->
->              [a] -> ([Doc],[(Int,Ident)])
-> xmlMapDicc d f lArgs = foldl newArg ([],d) lArgs
->                             where
->                               newArg (l,d)  e = (l++[v'],d')
->                                                 where (v',d') = f d e
->
-
-
-> -- The dictionary identifies var names with integers
-> -- it will be ordered starting at the greatest integer
-> xmlBuildDicc :: [Ident] -> [(Int,Ident)]
-> xmlBuildDicc l = reverse (zip [0..((length l)-1)] l)
-
-> -- looks for a ident in the dictorionary. If it appears returns its
-> -- associated value. Otherwise, -1 is returned
-> xmlLookUp :: Ident -> [(Int,Ident)] -> Int
-> xmlLookUp ident []          = -1
-> xmlLookUp ident ((n,name):xs) = if ident==name
->                                 then n
->                                 else xmlLookUp ident xs
-
-> -- generates a integer corresponding to a new var
-> xmlNewVar :: [(Int,Ident)] -> Int
-> xmlNewVar []             = 0
-> xmlNewVar ((n,ident):xs) = n+1
-
-> xmlVar :: Int -> Doc
-> xmlVar n = text "<var>" <> xmlInt n <> text "</var>"
-
-> xmlLiteral :: Doc -> Doc
-> xmlLiteral d =   text "<lit>" $$ nest level d $$ text "</lit>"
-
-> xmlLitPattern :: Doc -> Doc
-> xmlLitPattern d =   text "<lpattern>" $$ nest level d $$ text "</lpattern>"
-
-
-> xmlLit :: Literal -> Doc
-> xmlLit (Char _ c) = text "<charc>" <>  xmlInt (ord c) <> text "</charc>"
-> xmlLit (Int _ n) = text "<intc>" <>  xmlInteger n <> text "</intc>"
-> xmlLit (Float _ n) = text "<floatc>" <>  xmlFloat n <> text "</floatc>"
-
-> xmlOperatorDecl :: CS.IDecl -> Doc
-> xmlOperatorDecl (CS.IInfixDecl _ fixity prec qident) =
->     text "<op fixity=\"" <> xmlFixity fixity 
->     <> text "\" prec=\"" <> xmlInteger prec <> text "\">"
->     <> xmlIdent (unqualify qident)
->     <> text "</op>"
-
-> xmlFixity :: CS.Infix -> Doc
-> xmlFixity CS.InfixL = text "InfixlOp"
-> xmlFixity CS.InfixR = text "InfixrOp"
-> xmlFixity CS.Infix  = text "InfixOp"
-
-
-> xmlTranslationDecl :: QualIdent -> Doc
-> xmlTranslationDecl expId =
->       text "<trans>" 
->    $$ nest level (   text "<name>"    <> xmlIdent (unqualify expId) <> text "</name>"
->                   $$ text "<intname>" <> xmlQualIdent expId         <> text "</intname>")
->    $$ text "</trans>"
-
-
-> xmlIdent :: Ident -> Doc
-> xmlIdent ident = text (xmlFormat (name ident))
-
-> xmlInt :: Int -> Doc
-> xmlInt n = text (show n)
-
-> xmlInteger :: Integer -> Doc
-> xmlInteger n = text (show n)
-
-> xmlFloat :: Double -> Doc
-> xmlFloat n = text (show n)
-
-> xmlQualIdent :: QualIdent -> Doc
-> xmlQualIdent ident = text (xmlFormat (qualName ident))
-
-> xmlModuleIdent:: ModuleIdent -> Doc
-> xmlModuleIdent name = text (xmlFormat (moduleName name))
-
-> xmlFormat :: String -> String
-> xmlFormat []       = []
-> xmlFormat ('>':xs) = "&gt;"++xmlFormat xs
-> xmlFormat ('<':xs) = "&lt;"++xmlFormat xs
-> xmlFormat ('&':xs) = "&amp;"++xmlFormat xs
-> xmlFormat (x:xs)   = x:(xmlFormat xs)
-
-> -- =========================================================================
-
-> qualIDeclId :: ModuleIdent -> [QualIdent] -> CS.IDecl -> [QualIdent]
-> qualIDeclId mid qids (CS.IDataDecl _ qid _ mcdecls)
->    = foldl (qualConstrDeclId mid) (qid:qids) (catMaybes mcdecls)
-> qualIDeclId mid qids (CS.INewtypeDecl _ qid _ ncdecl)
->    = qualNewConstrDeclId mid (qid:qids) ncdecl
-> qualIDeclId mid qids (CS.ITypeDecl _ qid _ _)
->    = qid:qids
-> qualIDeclId mid qids (CS.IFunctionDecl _ qid _ _)
->    = qid:qids
-> qualIDeclId mid qids _ = qids
-
-> qualConstrDeclId :: ModuleIdent -> [QualIdent] -> CS.ConstrDecl 
->	              -> [QualIdent]
-> qualConstrDeclId mid qids (CS.ConstrDecl _ _ id _)
->    = (qualifyWith mid id):qids
-> qualConstrDeclId mid qids (CS.ConOpDecl _ _ _ id _)
->    = (qualifyWith mid id):qids
-
-> qualNewConstrDeclId :: ModuleIdent -> [QualIdent] -> CS.NewConstrDecl 
->	                 -> [QualIdent]
-> qualNewConstrDeclId mid qids (CS.NewConstrDecl _ _ id _)
->    = (qualifyWith mid id):qids
-
-
-\end{verbatim}
diff --git a/src/Ident.lhs b/src/Ident.lhs
deleted file mode 100644
--- a/src/Ident.lhs
+++ /dev/null
@@ -1,415 +0,0 @@
-> {-# LANGUAGE DeriveDataTypeable #-}
-
-% $Id: Ident.lhs,v 1.21 2004/10/29 13:08:09 wlux Exp $
-%
-% Copyright (c) 1999-2004, Wolfgang Lux
-% See LICENSE for the full license.
-%
-\nwfilename{Ident.lhs}
-\section{Identifiers}
-This module provides the implementation of identifiers and some
-utility functions for identifiers, which are used at various places in
-the compiler.
-
-Identifiers comprise the name of the denoted entity and an \emph{id},
-which can be used for renaming identifiers, e.g., in order to resolve
-name conflicts between identifiers from different scopes. An
-identifier with an \emph{id} $0$ is considered as not being renamed
-and, hence, its \emph{id} will not be shown.
-
-\ToDo{Probably we should use \texttt{Integer} for the \emph{id}s.}
-
-Qualified identifiers may optionally be prefixed by a module
-name. \textbf{The order of the cases \texttt{UnqualIdent} and
-\texttt{QualIdent} is important. Some parts of the compiler rely on
-the fact that all qualified identifiers are greater than any
-unqualified identifier.}
-\begin{verbatim}
-
-> module Ident(Ident,QualIdent,ModuleIdent,SrcRefOf(..),
->              mkIdent,name,qualName,uniqueId,renameIdent,unRenameIdent,
->              mkMIdent,moduleName,moduleQualifiers,isInfixOp,isQInfixOp,
->              qualify,qualifyWith,qualQualify,isQualified,
->              unqualify,qualUnqualify,localIdent,splitQualIdent,
->              emptyMIdent,mainMIdent,preludeMIdent,
->              anonId,unitId,boolId,charId,intId,floatId,listId,ioId,
->              successId,trueId,falseId,nilId,consId,mainId,
->              tupleId,isTupleId,tupleArity,
->              minusId,fminusId,updIdentName,
->              qUnitId,qBoolId,qCharId,qIntId,qFloatId,qListId,qIOId,
->              qSuccessId,qTrueId,qFalseId,qNilId,qConsId,
->              qTupleId,isQTupleId,qTupleArity,
->              fpSelectorId,isFpSelectorId,isQualFpSelectorId,
->              recSelectorId,qualRecSelectorId,
->              recUpdateId, qualRecUpdateId, recordExtId, labelExtId,
->              isRecordExtId, isLabelExtId, fromRecordExtId, fromLabelExtId,
->              renameLabel, isLabel, fpSelExt, recSelExt, recUpdExt,
->              recordExt, labelExt, mkLabelIdent,hasPositionIdent,
->              showsIdent,showsQualIdent,showsModuleIdent,
->              addPositionIdent, removePositionIdent, positionOfIdent,
->              addPositionModuleIdent, removePositionModuleIdent,addRef,addRefId,
->              positionOfModuleIdent,positionOfQualIdent,updQualIdent ) where
-
-> import Data.Char
-> import Data.List
-> import Data.Maybe
-> import Data.Generics
-
-> import Position
-
-
-> data Ident = Ident String Int 
->            | IdentPosition Position String Int deriving (Read,Data,Typeable)
-> data QualIdent = UnqualIdent Ident | QualIdent ModuleIdent Ident
->                  deriving (Eq,Ord,Read,Data,Typeable)
-> data ModuleIdent = ModuleIdent [String] 
->                   |ModuleIdentPosition Position [String] deriving (Data,Typeable)
-
-> instance Eq Ident where
->    ident1 == ident2 = name ident1 == name     ident2 && 
->                   uniqueId ident1 == uniqueId ident2
-
-> instance Ord ModuleIdent where
->    mident1 `compare` mident2 =
->        moduleQualifiers mident1 `compare` moduleQualifiers mident2
-
-> instance Eq ModuleIdent where
->    mident1 == mident2 = moduleQualifiers mident1 == moduleQualifiers mident2 
-
-> instance Read ModuleIdent where
->   readsPrec p s = [ (mkMIdent [m],s') | (m,s') <- readsPrec p s ]
-
-> instance Ord Ident where
->    ident1 `compare` ident2 =
->        (name ident1,uniqueId ident1) `compare` (name ident2,uniqueId ident2)
-
-> instance Show Ident where
->   showsPrec _ (Ident x n)
->     | n == 0 = showString x
->     | otherwise = showString x . showChar '.' . shows n
->   showsPrec _ (IdentPosition _ x n)
->     | n == 0 = showString x
->     | otherwise = showString x . showChar '.' . shows n
-> instance Show QualIdent where
->   showsPrec _ (UnqualIdent x) = shows x
->   showsPrec _ (QualIdent m x) = shows m . showChar '.' . shows x
-> instance Show ModuleIdent where
->   showsPrec _ m = showString (moduleName m)
-
-> hasPositionIdent :: Ident -> Bool
-> hasPositionIdent (Ident _ _ ) = False
-> hasPositionIdent (IdentPosition _ _ _) = True
-
-> addPositionIdent :: Position -> Ident -> Ident
-> addPositionIdent pos (Ident x n) = IdentPosition pos x n
-> addPositionIdent AST{ast=sr} (IdentPosition pos x n) = 
->   IdentPosition pos{ast=sr} x n
-> addPositionIdent pos (IdentPosition _ x n) = 
->   IdentPosition pos x n
-
-> removePositionIdent :: Ident -> Ident
-> removePositionIdent (Ident x n) = (Ident x n)
-> removePositionIdent (IdentPosition _ x n) = (Ident x n)
-
-> positionOfIdent :: Ident -> Position
-> positionOfIdent (Ident _ _) = noPos
-> positionOfIdent (IdentPosition pos _ _) = pos
-
-> addPositionModuleIdent :: Position -> ModuleIdent -> ModuleIdent
-> addPositionModuleIdent pos (ModuleIdent x) = ModuleIdentPosition pos x 
-> addPositionModuleIdent pos (ModuleIdentPosition _ x) = ModuleIdentPosition pos x 
-
-> removePositionModuleIdent :: ModuleIdent -> ModuleIdent
-> removePositionModuleIdent (ModuleIdent x) = (ModuleIdent x)
-> removePositionModuleIdent (ModuleIdentPosition _ x) = (ModuleIdent x)
-
-> positionOfModuleIdent :: ModuleIdent -> Position
-> positionOfModuleIdent (ModuleIdent _) = noPos
-> positionOfModuleIdent (ModuleIdentPosition pos _) = pos
-
-> positionOfQualIdent :: QualIdent -> Position
-> positionOfQualIdent = positionOfIdent . snd . splitQualIdent
-
-> mkIdent :: String -> Ident
-> mkIdent x = Ident x 0
-
-> name :: Ident -> String
-> name (Ident x _) = x
-> name (IdentPosition _ x _) = x
-
-> qualName :: QualIdent -> String
-> qualName (UnqualIdent x) = name x
-> qualName (QualIdent m x) = moduleName m ++ "." ++ name x
-
-> uniqueId :: Ident -> Int
-> uniqueId (Ident _ n) = n
-> uniqueId (IdentPosition _ _ n) = n
-
-> renameIdent :: Ident -> Int -> Ident
-> renameIdent (Ident x _) n = Ident x n
-> renameIdent (IdentPosition p x _) n = IdentPosition p x n
-
-> unRenameIdent :: Ident -> Ident
-> unRenameIdent (Ident x _) = Ident x 0
-> unRenameIdent (IdentPosition p x _) = IdentPosition p x 0
-
-> mkMIdent :: [String] -> ModuleIdent
-> mkMIdent = ModuleIdent
-
-> moduleName :: ModuleIdent -> String
-> moduleName (ModuleIdent xs) = concat (intersperse "." xs)
-> moduleName (ModuleIdentPosition _ xs) = concat (intersperse "." xs)
-
-> moduleQualifiers :: ModuleIdent -> [String]
-> moduleQualifiers (ModuleIdent xs) = xs
-> moduleQualifiers (ModuleIdentPosition _ xs) = xs
-
-> isInfixOp :: Ident -> Bool
-> isInfixOp (Ident ('<':c:cs) _)=
->   last (c:cs) /= '>' || not (isAlphaNum c) && c `notElem` "_(["
-> isInfixOp (Ident (c:_) _) = not (isAlphaNum c) && c `notElem` "_(["
-> isInfixOp (Ident _ _) = False -- error "Zero-length identifier"
-> isInfixOp x@(IdentPosition _ _ _) = isInfixOp $ removePositionIdent x
-
-> isQInfixOp :: QualIdent -> Bool
-> isQInfixOp (UnqualIdent x) = isInfixOp x
-> isQInfixOp (QualIdent _ x) = isInfixOp x
-
-\end{verbatim}
-The functions \texttt{qualify} and \texttt{qualifyWith} convert an
-unqualified identifier into a qualified identifier (without and with a
-given module prefix, respectively).
-\begin{verbatim}
-
-> qualify :: Ident -> QualIdent
-> qualify = UnqualIdent
-
-> qualifyWith :: ModuleIdent -> Ident -> QualIdent
-> qualifyWith = QualIdent
-
-> qualQualify :: ModuleIdent -> QualIdent -> QualIdent
-> qualQualify m (UnqualIdent x) = QualIdent m x
-> qualQualify _ x = x
-
-> isQualified :: QualIdent -> Bool
-> isQualified (UnqualIdent _) = False
-> isQualified (QualIdent _ _) = True
-
-> unqualify :: QualIdent -> Ident
-> unqualify (UnqualIdent x) = x
-> unqualify (QualIdent _ x) = x
-
-> qualUnqualify :: ModuleIdent -> QualIdent -> QualIdent
-> qualUnqualify m (UnqualIdent x) = UnqualIdent x
-> qualUnqualify m (QualIdent m' x)
->   | m == m' = UnqualIdent x
->   | otherwise = QualIdent m' x
-
-> localIdent :: ModuleIdent -> QualIdent -> Maybe Ident
-> localIdent _ (UnqualIdent x) = Just x
-> localIdent m (QualIdent m' x)
->   | m == m' = Just x
->   | otherwise = Nothing
-
-> splitQualIdent :: QualIdent -> (Maybe ModuleIdent,Ident)
-> splitQualIdent (UnqualIdent x) = (Nothing,x)
-> splitQualIdent (QualIdent m x) = (Just m,x)
-
-> updQualIdent :: (ModuleIdent -> ModuleIdent) -> (Ident -> Ident) -> QualIdent -> QualIdent
-> updQualIdent _ g (UnqualIdent x) = UnqualIdent (g x)
-> updQualIdent f g (QualIdent m x) = QualIdent (f m) (g x)
-
-> addRef :: SrcRef -> QualIdent -> QualIdent
-> addRef r = updQualIdent id (addRefId r)
-
-> addRefId :: SrcRef -> Ident -> Ident
-> addRefId r = addPositionIdent (AST r)
-
-\end{verbatim}
-A few identifiers a predefined here.
-\begin{verbatim}
-
-> emptyMIdent, mainMIdent, preludeMIdent :: ModuleIdent
-> emptyMIdent   = ModuleIdent []
-> mainMIdent    = ModuleIdent ["main"]
-> preludeMIdent = ModuleIdent ["Prelude"]
-
-> anonId :: Ident
-> anonId = Ident "_" 0
-
-> unitPId :: Position -> Ident
-> unitPId p = IdentPosition p "()" 0
-
-> unitId, boolId, charId, intId, floatId, listId, ioId, successId :: Ident
-> unitId    = Ident "()" 0
-> boolId    = Ident "Bool" 0
-> charId    = Ident "Char" 0
-> intId     = Ident "Int" 0
-> floatId   = Ident "Float" 0
-> listId    = Ident "[]" 0
-> ioId      = Ident "IO" 0
-> successId = Ident "Success" 0
-
-> trueId, falseId, nilId, consId :: Ident
-> trueId  = Ident "True" 0
-> falseId = Ident "False" 0
-> nilId   = Ident "[]" 0
-> consId  = Ident ":" 0
-
-> tupleId :: Int -> Ident
-> tupleId n
->   | n >= 2 = Ident ("(" ++ replicate (n - 1) ',' ++ ")") 0
->   | otherwise = error "internal error: tupleId"
-
-> isTupleId :: Ident -> Bool
-> isTupleId x = n > 1 && x == tupleId n
->   where n = length (name x) - 1
-
-> tupleArity :: Ident -> Int
-> tupleArity x
->   | n > 1 && x == tupleId n = n
->   | otherwise = error "internal error: tupleArity"
->   where n = length (name x) - 1
-
-> mainId, minusId, fminusId :: Ident
-> mainId = Ident "main" 0
-> minusId = Ident "-" 0
-> fminusId = Ident "-." 0
-
-> qUnitId, qNilId, qConsId, qListId :: QualIdent
-> qUnitId = UnqualIdent unitId
-> qListId = UnqualIdent listId
-> qNilId  = UnqualIdent nilId
-> qConsId = UnqualIdent consId
-
-> qBoolId, qCharId, qIntId, qFloatId, qSuccessId, qIOId :: QualIdent
-> qBoolId = QualIdent preludeMIdent boolId
-> qCharId = QualIdent preludeMIdent charId
-> qIntId = QualIdent preludeMIdent intId
-> qFloatId = QualIdent preludeMIdent floatId
-> qSuccessId = QualIdent preludeMIdent successId
-> qIOId = QualIdent preludeMIdent ioId
-
-> qTrueId, qFalseId :: QualIdent
-> qTrueId = QualIdent preludeMIdent trueId
-> qFalseId = QualIdent preludeMIdent falseId
-
-> qTupleId :: Int -> QualIdent
-> qTupleId = UnqualIdent . tupleId
-
-> isQTupleId :: QualIdent -> Bool
-> isQTupleId = isTupleId . unqualify
-
-> qTupleArity :: QualIdent -> Int
-> qTupleArity = tupleArity . unqualify
-
-\end{verbatim}
-Micellaneous function for generating and testing extended identifiers.
-\begin{verbatim}
-
-> fpSelectorId :: Int -> Ident
-> fpSelectorId n = Ident (fpSelExt ++ show n) 0
-
-> isFpSelectorId :: Ident -> Bool
-> isFpSelectorId f = any (fpSelExt `isPrefixOf`) (tails (name f))
-
-> isQualFpSelectorId :: QualIdent -> Bool
-> isQualFpSelectorId = isFpSelectorId . unqualify
-
-> recSelectorId :: QualIdent -> Ident -> Ident
-> recSelectorId r l =
->   mkIdent (recSelExt ++ name (unqualify r) ++ "." ++ name l)
-
-> qualRecSelectorId :: ModuleIdent -> QualIdent -> Ident -> QualIdent
-> qualRecSelectorId m r l = qualifyWith m' (recSelectorId r l)
->   where m' = (fromMaybe m (fst (splitQualIdent r)))
-
-> recUpdateId :: QualIdent -> Ident -> Ident
-> recUpdateId r l = 
->   mkIdent (recUpdExt ++ name (unqualify r) ++ "." ++ name l)
-
-> qualRecUpdateId :: ModuleIdent -> QualIdent -> Ident -> QualIdent
-> qualRecUpdateId m r l = qualifyWith m' (recUpdateId r l)
->   where m' = (fromMaybe m (fst (splitQualIdent r)))
-
-> recordExtId :: Ident -> Ident
-> recordExtId r = mkIdent (recordExt ++ name r)
-
-> labelExtId :: Ident -> Ident
-> labelExtId l = mkIdent (labelExt ++ name l)
-
-> fromRecordExtId :: Ident -> Ident
-> fromRecordExtId r 
->   | p == recordExt = mkIdent r'
->   | otherwise = r
->  where (p,r') = splitAt (length recordExt) (name r)
-
-> fromLabelExtId :: Ident -> Ident
-> fromLabelExtId l 
->   | p == labelExt = mkIdent l'
->   | otherwise = l
->  where (p,l') = splitAt (length labelExt) (name l)
-
-> isRecordExtId :: Ident -> Bool
-> isRecordExtId r = recordExt `isPrefixOf` name r
-
-> isLabelExtId :: Ident -> Bool
-> isLabelExtId l = labelExt `isPrefixOf` name l
-
-> mkLabelIdent :: String -> Ident
-> mkLabelIdent c = renameIdent (mkIdent c) (-1)
-
-> renameLabel :: Ident -> Ident
-> renameLabel l = renameIdent l (-1)
-
-> isLabel :: Ident -> Bool
-> isLabel l = uniqueId l == (-1)
-
-
-> fpSelExt = "_#selFP"
-> recSelExt = "_#selR@"
-> recUpdExt = "_#updR@"
-> recordExt = "_#Rec:"
-> labelExt = "_#Lab:"
-
-> showsString :: String -> ShowS
-> showsString = (++)
-
-> space :: ShowS
-> space = showsString " "
-
-> showsIdent :: Ident -> ShowS
-> showsIdent x@(IdentPosition _ _ _) = showsIdent $ removePositionIdent x
-> showsIdent (Ident name n)
->   = showsString "(Ident " . shows name . space . shows n . showsString ")"
-
-> showsQualIdent :: QualIdent -> ShowS
-> showsQualIdent (UnqualIdent ident)
->   = showsString "(UnqualIdent " . showsIdent ident . showsString ")"
-> showsQualIdent (QualIdent mident ident)
->   = showsString "(QualIdent "
->   . showsModuleIdent mident . space
->   . showsIdent ident
->   . showsString ")"
-
-> showsModuleIdent :: ModuleIdent -> ShowS
-> showsModuleIdent = shows . moduleName
-
-showsModuleIdent x@(ModuleIdentPosition _ _) = 
-    showsModuleIdent $ removePositionModuleIdent x
-showsModuleIdent (ModuleIdent []) = showsString "(ModuleIdent [])"
-showsModuleIdent (ModuleIdent (s:strs))
-  = showsString "(ModuleIdent ["
-  . foldl (\sys y -> sys . showsString "," . shows y) (shows s) strs
-  . showsString "])"
-
-\end{verbatim}
-
-> instance SrcRefOf Ident where srcRefOf = srcRefOf . positionOfIdent
-> instance SrcRefOf QualIdent where srcRefOf = srcRefOf . unqualify
-
-> updIdentName :: (String -> String) -> Ident -> Ident
-> updIdentName f ident = let p=positionOfIdent ident
->                            i=uniqueId ident
->                            n=name ident in
->   addPositionIdent p $ flip renameIdent i $ mkIdent (f n)
diff --git a/src/Imports.lhs b/src/Imports.lhs
--- a/src/Imports.lhs
+++ b/src/Imports.lhs
@@ -16,8 +16,11 @@
 > import qualified Data.Set as Set
 > import qualified Data.Map as Map
 
+> import Curry.Syntax
+> import Types
+> import Curry.Base.Position
+> import Curry.Base.Ident
 > import Base
-> import Env
 > import TopEnv
 
 
@@ -31,10 +34,10 @@
 The same is true for type expressions.
 \begin{verbatim}
 
-> type ExpPEnv = Env Ident PrecInfo
-> type ExpTCEnv = Env Ident TypeInfo
-> type ExpValueEnv = Env Ident ValueInfo
-> type ExpArityEnv = Env Ident ArityInfo
+> type ExpPEnv = Map.Map Ident PrecInfo
+> type ExpTCEnv = Map.Map Ident TypeInfo
+> type ExpValueEnv = Map.Map Ident ValueInfo
+> type ExpArityEnv = Map.Map Ident ArityInfo
 
 \end{verbatim}
 When an interface is imported, the compiler first transforms the
@@ -69,10 +72,10 @@
 > isVisible _ _ = const True
 
 > importEntities :: Entity a => ModuleIdent -> Bool -> (Ident -> Bool)
->                -> (a -> a) -> Env Ident a -> TopEnv a -> TopEnv a
+>                -> (a -> a) -> Map.Map Ident a -> TopEnv a -> TopEnv a
 > importEntities m q isVisible f mEnv env =
 >   foldr (uncurry (if q then qualImportTopEnv m else importUnqual m)) env
->         [(x,f y) | (x,y) <- envToList mEnv, isVisible x]
+>         [(x,f y) | (x,y) <- Map.toList mEnv, isVisible x]
 >   where importUnqual m x y = importTopEnv m x y . qualImportTopEnv m x y
 
 > importData :: (Ident -> Bool) -> TypeInfo -> TypeInfo
@@ -111,18 +114,18 @@
 module name.  
 \begin{verbatim}
 
-> intfEnv :: (ModuleIdent -> IDecl -> Env Ident a -> Env Ident a)
->         -> Interface -> Env Ident a
-> intfEnv bind (Interface m ds) = foldr (bind m) emptyEnv ds
+> intfEnv :: (ModuleIdent -> IDecl -> Map.Map Ident a -> Map.Map Ident a)
+>         -> Interface -> Map.Map Ident a
+> intfEnv bind (Interface m ds) = foldr (bind m) Map.empty ds
 
 > bindPrec :: ModuleIdent -> IDecl -> ExpPEnv -> ExpPEnv
 > bindPrec m (IInfixDecl _ fix p op) =
->   bindEnv (unqualify op) (PrecInfo (qualQualify m op) (OpPrec fix p))
+>   Map.insert (unqualify op) (PrecInfo (qualQualify m op) (OpPrec fix p))
 > bindPrec _ _ = id
 
 > bindTC :: ModuleIdent -> IDecl -> ExpTCEnv -> ExpTCEnv
 > bindTC m (IDataDecl _ tc tvs cs) mTCEnv 
->   | isJust (lookupEnv (unqualify tc) mTCEnv) =
+>   | isJust (Map.lookup (unqualify tc) mTCEnv) =
 >     mTCEnv
 >   | otherwise =
 >     bindType DataType m tc tvs (map (fmap mkData) cs) mTCEnv
@@ -150,7 +153,7 @@
 > bindType :: (QualIdent -> Int -> a -> TypeInfo) -> ModuleIdent -> QualIdent
 >          -> [Ident] -> a -> ExpTCEnv -> ExpTCEnv
 > bindType f m tc tvs =
->   bindEnv (unqualify tc) . f (qualQualify m tc) (length tvs) 
+>   Map.insert (unqualify tc) . f (qualQualify m tc) (length tvs) 
 
 > bindTy :: ModuleIdent -> IDecl -> ExpValueEnv -> ExpValueEnv
 > bindTy m (IDataDecl _ tc tvs cs) =
@@ -163,7 +166,7 @@
 > --  flip (foldr (bindRecLabel m r')) fs
 > --  where r' = qualifyWith m (fromRecordExtId (unqualify r))
 > bindTy m (IFunctionDecl _ f _ ty) =
->   bindEnv (unqualify f)
+>   Map.insert (unqualify f)
 >           (Value (qualQualify m f) (polyType (toQualType m [] ty)))
 > bindTy m _ = id
 
@@ -183,27 +186,27 @@
 > --bindRecLabel :: ModuleIdent -> QualIdent -> ([Ident],TypeExpr)
 > --      -> ExpValueEnv -> ExpValueEnv
 > --bindRecLabel m r ([l],ty) =
-> --  bindEnv l (Label (qualify l) r (polyType (toQualType m [] ty)))
+> --  Map.insert l (Label (qualify l) r (polyType (toQualType m [] ty)))
 
 > bindValue :: (QualIdent -> ExistTypeScheme -> ValueInfo) -> ModuleIdent
 >           -> QualIdent -> [Ident] -> Ident -> [Ident] -> TypeExpr
 >           -> ExpValueEnv -> ExpValueEnv
-> bindValue f m tc tvs c evs ty = bindEnv c (f (qualifyLike tc c) sigma)
+> bindValue f m tc tvs c evs ty = Map.insert c (f (qualifyLike tc c) sigma)
 >   where sigma = ForAllExist (length tvs) (length evs) (toQualType m tvs ty)
->         qualifyLike x = maybe qualify qualifyWith (fst (splitQualIdent x))
+>         qualifyLike x = maybe qualify qualifyWith (qualidMod x)
 
 > bindA :: ModuleIdent -> IDecl -> ExpArityEnv -> ExpArityEnv
 > bindA m (IDataDecl _ _ _ cs) expAEnv
 >    = foldr (bindConstrA m) expAEnv (catMaybes cs)
 > bindA m (IFunctionDecl _ f a _) expAEnv
->    = bindEnv (unqualify f) (ArityInfo (qualQualify m f) a) expAEnv
+>    = Map.insert (unqualify f) (ArityInfo (qualQualify m f) a) expAEnv
 > bindA _ _ expAEnv = expAEnv
 
 > bindConstrA :: ModuleIdent -> ConstrDecl -> ExpArityEnv -> ExpArityEnv
 > bindConstrA m (ConstrDecl _ _ c tys) expAEnv
->    = bindEnv c (ArityInfo (qualifyWith m c) (length tys)) expAEnv
+>    = Map.insert c (ArityInfo (qualifyWith m c) (length tys)) expAEnv
 > bindConstrA m (ConOpDecl _ _ _ c _) expAEnv
->    = bindEnv c (ArityInfo (qualifyWith m c) 2) expAEnv
+>    = Map.insert c (ArityInfo (qualifyWith m c) 2) expAEnv
 
 \end{verbatim}
 After the environments have been initialized, the optional import
@@ -262,14 +265,14 @@
 > expandThing :: ModuleIdent -> ExpTCEnv -> ExpValueEnv -> Ident
 >             -> [Import]
 > expandThing m tcEnv tyEnv tc =
->   case lookupEnv tc tcEnv of
+>   case Map.lookup tc tcEnv of
 >     Just _ -> expandThing' m tyEnv tc (Just [ImportTypeWith tc []])
 >     Nothing -> expandThing' m tyEnv tc Nothing
 
 > expandThing' :: ModuleIdent -> ExpValueEnv -> Ident
 >              -> Maybe [Import] -> [Import]
 > expandThing' m tyEnv f tcImport =
->   case lookupEnv f tyEnv of
+>   case Map.lookup f tyEnv of
 >     Just v
 >       | isConstr v -> maybe (errorAt' (importDataConstr m f)) id tcImport
 >       | otherwise -> Import f : maybe [] id tcImport
@@ -281,21 +284,21 @@
 > expandHide :: ModuleIdent -> ExpTCEnv -> ExpValueEnv -> Ident
 >            -> [Import]
 > expandHide m tcEnv tyEnv tc =
->   case lookupEnv tc tcEnv of
+>   case Map.lookup tc tcEnv of
 >     Just _ -> expandHide' m tyEnv tc (Just [ImportTypeWith tc []])
 >     Nothing -> expandHide' m tyEnv tc Nothing
 
 > expandHide' :: ModuleIdent -> ExpValueEnv -> Ident
 >             -> Maybe [Import] -> [Import]
 > expandHide' m tyEnv f tcImport =
->   case lookupEnv f tyEnv of
+>   case Map.lookup f tyEnv of
 >     Just _ -> Import f : maybe [] id tcImport
 >     Nothing -> maybe (errorAt' (undefinedEntity m f)) id tcImport
 
 > expandTypeWith ::  ModuleIdent -> ExpTCEnv -> Ident -> [Ident]
 >                -> Import
 > expandTypeWith m tcEnv tc cs =
->   case lookupEnv tc tcEnv of
+>   case Map.lookup tc tcEnv of
 >     Just (DataType _ _ cs') ->
 >       ImportTypeWith tc (map (checkConstr [c | Just (Data c _ _) <- cs']) cs)
 >     Just (RenamingType _ _ (Data c _ _)) ->
@@ -308,7 +311,7 @@
 
 > expandTypeAll :: ModuleIdent -> ExpTCEnv -> Ident -> Import
 > expandTypeAll m tcEnv tc =
->   case lookupEnv tc tcEnv of
+>   case Map.lookup tc tcEnv of
 >     Just (DataType _ _ cs) -> ImportTypeWith tc [c | Just (Data c _ _) <- cs]
 >     Just (RenamingType _ _ (Data c _ _)) -> ImportTypeWith tc [c]
 >     Just _ -> errorAt' (nonDataType m tc)
@@ -357,11 +360,6 @@
 > undefinedEntity m x =
 >  (positionOfIdent x,
 >   "Module " ++ moduleName m ++ " does not export " ++ name x)
-
-> undefinedType :: ModuleIdent -> Ident -> (Position,String)
-> undefinedType m tc =
->  (positionOfIdent tc,   
->   "Module " ++ moduleName m ++ " does not export a type " ++ name tc)
 
 > undefinedDataConstr :: ModuleIdent -> Ident -> Ident -> (Position,String)
 > undefinedDataConstr m tc c =
diff --git a/src/InterfaceCheck.hs b/src/InterfaceCheck.hs
--- a/src/InterfaceCheck.hs
+++ b/src/InterfaceCheck.hs
@@ -11,7 +11,7 @@
 
 import Data.List
 
-import ExtendedFlat
+import Curry.ExtendedFlat
 
 
 
diff --git a/src/KindCheck.lhs b/src/KindCheck.lhs
--- a/src/KindCheck.lhs
+++ b/src/KindCheck.lhs
@@ -23,10 +23,13 @@
 is defined more than once.
 \begin{verbatim}
 
-> module KindCheck(kindCheck,kindCheckGoal) where
+> module KindCheck(kindCheck) where
 
 > import Data.Maybe
 
+> import Curry.Syntax
+> import Curry.Base.Position
+> import Curry.Base.Ident
 > import Base hiding (bindArity)
 > import TopEnv
 
@@ -44,16 +47,10 @@
 > kindCheck m tcEnv ds =
 >   case linear (map tconstr ds') of
 >     Linear -> map (checkDecl m kEnv) ds
->     NonLinear (PIdent p tc) -> errorAt' (duplicateType tc)
+>     NonLinear tc -> errorAt' (duplicateType tc)
 >   where ds' = filter isTypeDecl ds
 >         kEnv = foldr (bindArity m) (fmap tcArity tcEnv) ds'
 
-> kindCheckGoal :: TCEnv -> Goal -> Goal
-> kindCheckGoal tcEnv (Goal p e ds) =
->   Goal p (checkExpr m kEnv e) (map (checkDecl m kEnv) ds)
->   where kEnv = fmap tcArity tcEnv
->	  m = mkMIdent []
-
 \end{verbatim}
 The kind environment only needs to record the arity of each type constructor.
 \begin{verbatim}
@@ -113,7 +110,7 @@
 >   | tv `elem` tvs = errorAt' (nonLinear tv)
 >   | otherwise = tv : checkTypeLhs kEnv tvs
 >   where isTypeConstr tv = not (null (lookupKind tv kEnv))
-> checkTypeLhs kEnv [] = []
+> checkTypeLhs _ [] = []
 
 > checkConstrDecl :: ModuleIdent -> KindEnv -> [Ident] -> ConstrDecl -> ConstrDecl
 > checkConstrDecl m kEnv tvs (ConstrDecl p evs c tys) =
@@ -268,10 +265,10 @@
 Auxiliary definitions
 \begin{verbatim}
 
-> tconstr :: Decl -> PIdent
-> tconstr (DataDecl p tc _ _) = PIdent p tc
-> tconstr (NewtypeDecl p tc _ _) = PIdent p tc
-> tconstr (TypeDecl p tc _ _) = PIdent p tc
+> tconstr :: Decl -> Ident
+> tconstr (DataDecl p tc _ _) = tc
+> tconstr (NewtypeDecl p tc _ _) = tc
+> tconstr (TypeDecl p tc _ _) = tc
 > tconstr _ = internalError "tconstr"
 
 \end{verbatim}
diff --git a/src/LLParseComb.lhs b/src/LLParseComb.lhs
deleted file mode 100644
--- a/src/LLParseComb.lhs
+++ /dev/null
@@ -1,292 +0,0 @@
-% -*- LaTeX -*-
-% $Id: LLParseComb.lhs,v 1.26 2004/02/15 23:11:30 wlux Exp $
-%
-% Copyright (c) 1999-2004, Wolfgang Lux
-% See LICENSE for the full license.
-%
-\nwfilename{LLParseComb.lhs}
-\section{Parsing Combinators}\label{sec:ll-parsecomb}
-The parsing combinators implemented in the module \texttt{LLParseComb}
-are based on the LL(1) parsing combinators developed by Swierstra and
-Duponcheel~\cite{SwierstraDuponcheel96:Parsers}. They have been
-adapted to using continuation passing style in order to work with the
-lexing combinators described in the previous section. In addition, the
-facilities for error correction are omitted in this implementation.
-
-The two functions \texttt{applyParser} and \texttt{prefixParser} use
-the specified parser for parsing a string. When \texttt{applyParser}
-is used, an error is reported if the parser does not consume the whole
-string, whereas \texttt{prefixParser} discards the rest of the input
-string in this case.
-\begin{verbatim}
-
-> module LLParseComb(Symbol(..),Parser,
->                    applyParser,prefixParser, position,succeed,symbol,
->                    (<?>),(<|>),(<|?>),(<*>),(<\>),(<\\>),
->                    opt,(<$>),(<$->),(<*->),(<-*>),(<**>),(<??>),(<.>),
->                    many,many1, sepBy,sepBy1, chainr,chainr1,chainl,chainl1,
->                    bracket,ops, layoutOn,layoutOff,layoutEnd) where
-
-> import Control.Monad
-> import Data.Maybe
-> import qualified Data.Set as Set
-> import qualified Data.Map as Map
-
-
-> import Position
-
-
-> import Error
-> import LexComb
-
-> infixl 5 <\>, <\\>
-> infixl 4 <*>, <$>, <$->, <*->, <-*>, <**>, <??>, <.>
-> infixl 3 <|>, <|?>
-> infixl 2 <?>, `opt`
-
-\end{verbatim}
-\paragraph{Parser types}
-\begin{verbatim}
-
-> class (Ord s,Show s) => Symbol s where
->   isEOF :: s -> Bool
-
-> type Empty = Bool
-> type SuccessCont s a = Position -> s -> P a
-> type FailureCont a = Position -> String -> P a
-> type Lexer s a = SuccessCont s a -> FailureCont a -> P a
-> type ParseFun s a b = (a -> SuccessCont s b) -> FailureCont b
->                     -> SuccessCont s b
-
-> data Parser s a b = Parser (Maybe (ParseFun s a b))
->                            (Map.Map s (Lexer s b -> ParseFun s a b))
-
-> instance Symbol s => Show (Parser s a b) where
->   showsPrec p (Parser e ps) = showParen (p >= 10) $                      -- $
->     showString "Parser " . shows (isJust e) .
->     showChar ' ' . shows (Map.keysSet ps)
-
-> applyParser :: Symbol s => Parser s a a -> Lexer s a -> FilePath -> String
->             -> Error a
-> applyParser p lexer = parse (lexer (choose p lexer done failP) failP)
->   where done x pos s
->           | isEOF s = returnP x
->           | otherwise = failP pos (unexpected s)
-
-> prefixParser :: Symbol s => Parser s a a -> Lexer s a -> FilePath -> String
->              -> Error a
-> prefixParser p lexer = parse (lexer (choose p lexer discard failP) failP)
->   where discard x _ _ = returnP x
-
-> choose :: Symbol s => Parser s a b -> Lexer s b -> ParseFun s a b
-> choose (Parser e ps) lexer success fail pos s =
->   case Map.lookup s ps of
->     Just p -> p lexer success fail pos s
->     Nothing ->
->       case e of
->         Just p -> p success fail pos s
->         Nothing -> fail pos (unexpected s)
-
-> unexpected :: Symbol s => s -> String
-> unexpected s
->   | isEOF s = "Unexpected end-of-file"
->   | otherwise = "Unexpected token " ++ show s
-
-\end{verbatim}
-\paragraph{Basic combinators}
-\begin{verbatim}
-
-> position :: Symbol s => Parser s Position b
-> position = Parser (Just p) Map.empty
->   where p success _ pos = success pos pos
-
-> succeed :: Symbol s => a -> Parser s a b
-> succeed x = Parser (Just p) Map.empty
->   where p success _ = success x
-
-> symbol :: Symbol s => s -> Parser s s a
-> symbol s = Parser Nothing (Map.singleton s p)
->   where p lexer success fail pos s = lexer (success s) fail
-
-> (<?>) :: Symbol s => Parser s a b -> String -> Parser s a b
-> p <?> msg = p <|> Parser (Just pfail) Map.empty
->   where pfail _ fail pos _ = fail pos msg
-
-> (<|>) :: Symbol s => Parser s a b -> Parser s a b -> Parser s a b
-> Parser e1 ps1 <|> Parser e2 ps2
->   | isJust e1 && isJust e2 = error "Ambiguous parser for empty word"
->   | not (Set.null common) = error ("Ambiguous parser for " ++ show common)
->   | otherwise = Parser (e1 `mplus` e2) (Map.union ps1 ps2)
->   where common = Map.keysSet ps1 `Set.intersection` Map.keysSet ps2
-
-\end{verbatim}
-The parsing combinators presented so far require that the grammar
-being parsed is LL(1). In some cases it may be difficult or even
-impossible to transform a grammar into LL(1) form. As a remedy, we
-include a non-deterministic version of the choice combinator in
-addition to the deterministic combinator adapted from the paper. For
-every symbol from the intersection of the parser's first sets, the
-combinator \texttt{(<|?>)} applies both parsing functions to the input
-stream and uses that one which processes the longer prefix of the
-input stream irrespective of whether it succeeds or fails. If both
-functions recognize the same prefix, we choose the one that succeeds
-and report an ambiguous parse error if both succeed.
-\begin{verbatim}
-
-> (<|?>) :: Symbol s => Parser s a b -> Parser s a b -> Parser s a b
-> Parser e1 ps1 <|?> Parser e2 ps2
->   | isJust e1 && isJust e2 = error "Ambiguous parser for empty word"
->   | otherwise = Parser (e1 `mplus` e2) (Map.union ps1' ps2)
->   where ps1' = Map.fromList [(s,maybe p (try p) (Map.lookup s ps2))
->                           | (s,p) <- Map.toList ps1]
->         try p1 p2 lexer success fail pos s =
->           closeP1 p2s `thenP` \p2s' ->
->           closeP1 p2f `thenP` \p2f' ->
->           parse p1 (retry p2s') (retry p2f')
->           where p2s r1 = parse p2 (select True r1) (select False r1)
->                 p2f r1 = parse p2 (flip (select False) r1) (select False r1)
->                 parse p psucc pfail =
->                   p lexer (successK psucc) (failK pfail) pos s
->                 successK k x pos s = k (pos,success x pos s)
->                 failK k pos msg = k (pos,fail pos msg)
->                 retry k (pos,p) = closeP0 p `thenP` curry k pos
->         select suc (pos1,p1) (pos2,p2) =
->           case pos1 `compare` pos2 of
->             GT -> p1
->             EQ
->               | suc -> error ("Ambiguous parse before " ++ show pos1)
->               | otherwise -> p1
->             LT -> p2
-
-> (<*>) :: Symbol s => Parser s (a -> b) c -> Parser s a c -> Parser s b c
-> Parser (Just p1) ps1 <*> ~p2@(Parser e2 ps2) =
->   Parser (fmap (seqEE p1) e2)
->          (Map.union (fmap (flip seqPP p2) ps1) (fmap (seqEP p1) ps2))
-> Parser Nothing ps1 <*> p2 = Parser Nothing (fmap (flip seqPP p2) ps1)
-
-> seqEE :: Symbol s => ParseFun s (a -> b) c -> ParseFun s a c
->       -> ParseFun s b c
-> seqEE p1 p2 success fail = p1 (\f -> p2 (success . f) fail) fail
-
-> seqEP :: Symbol s => ParseFun s (a -> b) c -> (Lexer s c -> ParseFun s a c)
->       -> Lexer s c -> ParseFun s b c
-> seqEP p1 p2 lexer success fail = p1 (\f -> p2 lexer (success . f) fail) fail
-
-> seqPP :: Symbol s => (Lexer s c -> ParseFun s (a -> b) c) -> Parser s a c
->       -> Lexer s c -> ParseFun s b c
-> seqPP p1 p2 lexer success fail =
->   p1 lexer (\f -> choose p2 lexer (success . f) fail) fail
-
-\end{verbatim}
-The combinators \verb|<\\>| and \verb|<\>| can be used to restrict
-the first set of a parser. This is useful for combining two parsers
-with an overlapping first set with the deterministic combinator <|>.
-\begin{verbatim}
-
-> (<\>) :: Symbol s => Parser s a c -> Parser s b c -> Parser s a c
-> p <\> Parser _ ps = p <\\> Map.keys ps
-
-> (<\\>) :: Symbol s => Parser s a b -> [s] -> Parser s a b
-> Parser e ps <\\> xs = Parser e (foldr Map.delete ps xs)
-
-\end{verbatim}
-\paragraph{Other combinators.}
-Note that some of these combinators have not been published in the
-paper, but were taken from the implementation found on the web.
-\begin{verbatim}
-
-> opt :: Symbol s => Parser s a b -> a -> Parser s a b
-> p `opt` x = p <|> succeed x
-
-> (<$>) :: Symbol s => (a -> b) -> Parser s a c -> Parser s b c
-> f <$> p = succeed f <*> p
-
-> (<$->) :: Symbol s => a -> Parser s b c -> Parser s a c
-> f <$-> p = const f <$> p {-$-}
-
-> (<*->) :: Symbol s => Parser s a c -> Parser s b c -> Parser s a c
-> p <*-> q = const <$> p <*> q {-$-}
-
-> (<-*>) :: Symbol s => Parser s a c -> Parser s b c -> Parser s b c
-> p <-*> q = const id <$> p <*> q {-$-}
-
-> (<**>) :: Symbol s => Parser s a c -> Parser s (a -> b) c -> Parser s b c
-> p <**> q = flip ($) <$> p <*> q
-
-> (<??>) :: Symbol s => Parser s a b -> Parser s (a -> a) b -> Parser s a b
-> p <??> q = p <**> (q `opt` id)
-
-> (<.>) :: Symbol s => Parser s (a -> b) d -> Parser s (b -> c) d
->       -> Parser s (a -> c) d
-> p1 <.> p2 = p1 <**> ((.) <$> p2)
-
-> many :: Symbol s => Parser s a b -> Parser s [a] b
-> many p = many1 p `opt` []
-
-> many1 :: Symbol s => Parser s a b -> Parser s [a] b
-> -- many1 p = (:) <$> p <*> many p
-> many1 p = (:) <$> p <*> (many1 p `opt` [])
-
-\end{verbatim}
-The first definition of \texttt{many1} is commented out because it
-does not compile under nhc. This is due to a -- known -- bug in the
-type checker of nhc which expects a default declaration when compiling
-mutually recursive functions with class constraints. However, no such
-default can be given in the above case because neither of the types
-involved is a numeric type.
-\begin{verbatim}
-
-> sepBy :: Symbol s => Parser s a c -> Parser s b c -> Parser s [a] c
-> p `sepBy` q = p `sepBy1` q `opt` []
-
-> sepBy1 :: Symbol s => Parser s a c -> Parser s b c -> Parser s [a] c
-> p `sepBy1` q = (:) <$> p <*> many (q <-*> p) {-$-}
-
-> chainr :: Symbol s => Parser s a b -> Parser s (a -> a -> a) b -> a
->        -> Parser s a b
-> chainr p op x = chainr1 p op `opt` x
-
-> chainr1 :: Symbol s => Parser s a b -> Parser s (a -> a -> a) b
->         -> Parser s a b
-> chainr1 p op = r
->   where r = p <**> (flip <$> op <*> r `opt` id) {-$-}
-
-> chainl :: Symbol s => Parser s a b -> Parser s (a -> a -> a) b -> a
->        -> Parser s a b
-> chainl p op x = chainl1 p op `opt` x
-
-> chainl1 :: Symbol s => Parser s a b -> Parser s (a -> a -> a) b
->         -> Parser s a b
-> chainl1 p op = foldF <$> p <*> many (flip <$> op <*> p)
->   where foldF x [] = x
->         foldF x (f:fs) = foldF (f x) fs
-
-> bracket :: Symbol s => Parser s a c -> Parser s b c -> Parser s a c
->         -> Parser s b c
-> bracket open p close = open <-*> p <*-> close
-
-> ops :: Symbol s => [(s,a)] -> Parser s a b
-> ops [] = error "internal error: ops"
-> ops [(s,x)] = x <$-> symbol s
-> ops ((s,x):rest) = x <$-> symbol s <|> ops rest
-
-\end{verbatim}
-\paragraph{Layout combinators}
-Note that the layout functions grab the next token (and its position).
-After modifying the layout context, the continuation is called with
-the same token and an undefined result.
-\begin{verbatim}
-
-> layoutOn :: Symbol s => Parser s a b
-> layoutOn = Parser (Just on) Map.empty
->   where on success _ pos = pushContext (column pos) . success undefined pos
-
-> layoutOff :: Symbol s => Parser s a b
-> layoutOff = Parser (Just off) Map.empty
->   where off success _ pos = pushContext (-1) . success undefined pos
-
-> layoutEnd :: Symbol s => Parser s a b
-> layoutEnd = Parser (Just end) Map.empty
->   where end success _ pos = popContext . success undefined pos
-
-\end{verbatim}
diff --git a/src/LexComb.lhs b/src/LexComb.lhs
deleted file mode 100644
--- a/src/LexComb.lhs
+++ /dev/null
@@ -1,102 +0,0 @@
-% -*- LaTeX -*-
-% $Id: LexComb.lhs,v 1.16 2004/01/20 16:44:14 wlux Exp $
-%
-% Copyright (c) 1999-2004, Wolfgang Lux
-% See LICENSE for the full license.
-%
-\nwfilename{LexComb.lhs}
-\section{Lexing combinators}
-The module \texttt{LexComb} provides the basic types and combinators
-to implement the lexers. The combinators use continuation passing code
-in a monadic style. The first argument of the continuation function is
-the string to be parsed, the second is the current position, and the
-third is a flag which signals the lexer that it is lexing the
-beginning of a line and therefore has to check for layout tokens. The
-fourth argument is a stack of indentations that is used to handle
-nested layout groups.
-\begin{verbatim}
-
-> module LexComb where
-> import Position
-> import Error
-> import Data.Char
-
-> infixl 1 `thenP`, `thenP_`
-
-> type Indent = Int
-> type Context = [Indent]
-> type P a = Position -> String -> Bool -> Context -> Error a
-
-> parse :: P a -> FilePath -> String -> Error a
-> parse p fn s = p (first fn) s False []
-
-\end{verbatim}
-Monad functions for the lexer.
-\begin{verbatim}
-
-> returnP :: a -> P a
-> returnP x _ _ _ _ = Ok x
-
-> thenP :: P a -> (a -> P b) -> P b
-> thenP lex k pos s bol ctxt = lex pos s bol ctxt >>= \x -> k x pos s bol ctxt
-
-> thenP_ :: P a -> P b -> P b
-> p1 `thenP_` p2 = p1 `thenP` \_ -> p2
-
-> failP :: Position -> String -> P a
-> failP pos msg _ _ _ _ = Error (parseError pos msg)
-
-> closeP0 :: P a -> P (P a)
-> closeP0 lex pos s bol ctxt = Ok (\_ _ _ _ -> lex pos s bol ctxt)
-
-> closeP1 :: (a -> P b) -> P (a -> P b)
-> closeP1 f pos s bol ctxt = Ok (\x _ _ _ _ -> f x pos s bol ctxt)
-
-> parseError :: Position -> String -> String
-> parseError p what = "\n" ++ show p ++ ": " ++ what
-
-\end{verbatim}
-Combinators that handle layout.
-\begin{verbatim}
-
-> pushContext :: Int -> P a -> P a
-> pushContext col cont pos s bol ctxt = cont pos s bol (col:ctxt)
-
-> popContext :: P a -> P a
-> popContext cont pos s bol (_:ctxt) = cont pos s bol ctxt
-> popContext cont pos s bol [] = 
->    error "parse error: popping layout from empty context stack. \
->          \Perhaps you have inserted too many '}'?"
-
-\end{verbatim}
-Conversions from strings into numbers.
-\begin{verbatim}
-
-> convertSignedIntegral :: Num a => a -> String -> a
-> convertSignedIntegral b ('+':s) = convertIntegral b s
-> convertSignedIntegral b ('-':s) = - convertIntegral b s
-> convertSignedIntegral b s = convertIntegral b s
-
-> convertIntegral :: Num a => a -> String -> a
-> convertIntegral b = foldl op 0
->   where m `op` n | isDigit n = b * m + fromIntegral (ord n - ord0)
->                  | isUpper n = b * m + fromIntegral (ord n - ordA)
->                  | otherwise = b * m + fromIntegral (ord n - orda)
->         ord0 = ord '0'
->         ordA = ord 'A' - 10
->         orda = ord 'a' - 10
-
-> convertSignedFloating :: Fractional a => String -> String -> Int -> a
-> convertSignedFloating ('+':m) f e = convertFloating m f e
-> convertSignedFloating ('-':m) f e = - convertFloating m f e
-> convertSignedFloating m f e = convertFloating m f e
-
-> convertFloating :: Fractional a => String -> String -> Int -> a
-> convertFloating m f e
->   | e' == 0 = m'
->   | e' > 0  = m' * 10^e'
->   | otherwise = m' / 10^(-e')
->   where m' = convertIntegral 10 (m ++ f)
->         e' = e - length f
-
-\end{verbatim}
diff --git a/src/Lift.lhs b/src/Lift.lhs
--- a/src/Lift.lhs
+++ b/src/Lift.lhs
@@ -20,23 +20,24 @@
 > module Lift(lift) where
 
 > import Control.Monad
+> import qualified Control.Monad.State as S
 > import Data.List
+> import qualified Data.Map as Map
 > import qualified Data.Set as Set
 
+> import Curry.Syntax
+> import Curry.Syntax.Utils
+> import Types
+> import Curry.Base.Ident
 > import Base
-> import Env
 > import TopEnv
-
-
-
-> import Combined
 > import SCC
 
 > lift :: ValueEnv -> EvalEnv -> Module -> (Module,ValueEnv,EvalEnv)
 > lift tyEnv evEnv (Module m es ds) =
 >   (Module m es (concatMap liftFunDecl ds'),tyEnv',evEnv')
 >   where (ds',tyEnv',evEnv') =
->           runSt (callSt (abstractModule m ds) tyEnv) evEnv
+>           S.evalState (S.evalStateT (abstractModule m ds) tyEnv) evEnv
 
 \end{verbatim}
 \paragraph{Abstraction}
@@ -49,16 +50,16 @@
 i.e. the function applied to its free variables.
 \begin{verbatim}
 
-> type AbstractState a = StateT ValueEnv (St EvalEnv) a
-> type AbstractEnv = Env Ident Expression
+> type AbstractState a = S.StateT ValueEnv (S.State EvalEnv) a
+> type AbstractEnv = Map.Map Ident Expression
 
 > abstractModule :: ModuleIdent -> [Decl]
 >                -> AbstractState ([Decl],ValueEnv,EvalEnv)
 > abstractModule m ds =
 >   do
->     ds' <- mapM (abstractDecl m "" [] emptyEnv) ds
->     tyEnv' <- fetchSt
->     evEnv' <- liftSt fetchSt
+>     ds' <- mapM (abstractDecl m "" [] Map.empty) ds
+>     tyEnv' <- S.get
+>     evEnv' <- S.lift S.get
 >     return (ds',tyEnv',evEnv')
 
 > abstractDecl :: ModuleIdent -> String -> [Ident] -> AbstractEnv -> Decl
@@ -149,9 +150,9 @@
 >     return (Let vds' e')
 > abstractFunDecls m pre lvs env (fds:fdss) vds e =
 >   do
->     fs' <- liftM (\tyEnv -> filter (not . isLifted tyEnv) fs) fetchSt
->     updateSt_ (abstractFunTypes m pre fvs fs')
->     liftSt (updateSt_ (abstractFunAnnots m pre fs'))
+>     fs' <- liftM (\tyEnv -> filter (not . isLifted tyEnv) fs) S.get
+>     S.modify (abstractFunTypes m pre fvs fs')
+>     S.lift (S.modify (abstractFunAnnots m pre fs'))
 >     fds' <- mapM (abstractFunDecl m pre fvs lvs env')
 >                  [d | d <- fds, any (`elem` fs') (bv d)]
 >     e' <- abstractFunDecls m pre lvs env' fdss vds e
@@ -160,8 +161,8 @@
 >         fvs = filter (`elem` lvs) (Set.toList fvsRhs)
 >         env' = foldr (bindF (map mkVar fvs)) env fs
 >         fvsRhs = Set.unions
->           [Set.fromList (maybe [v] (qfv m) (lookupEnv v env)) | v <- qfv m fds]
->         bindF fvs f = bindEnv f (apply (mkFun m pre f) fvs)
+>           [Set.fromList (maybe [v] (qfv m) (Map.lookup v env)) | v <- qfv m fds]
+>         bindF fvs f = Map.insert f (apply (mkFun m pre f) fvs)
 >         isLifted tyEnv f = null (lookupValue f tyEnv)
 
 > abstractFunTypes :: ModuleIdent -> String -> [Ident] -> [Ident]
@@ -176,8 +177,8 @@
 > abstractFunAnnots :: ModuleIdent -> String -> [Ident] -> EvalEnv -> EvalEnv
 > abstractFunAnnots m pre fs evEnv = foldr abstractFunAnnot evEnv fs
 >   where abstractFunAnnot f evEnv =
->           case lookupEnv f evEnv of
->             Just ev -> bindEnv (liftIdent pre f) ev (unbindEnv f evEnv)
+>           case Map.lookup f evEnv of
+>             Just ev -> Map.insert (liftIdent pre f) ev (Map.delete f evEnv)
 >             Nothing -> evEnv
 
 > abstractFunDecl :: ModuleIdent -> String -> [Ident] -> [Ident]
@@ -196,7 +197,7 @@
 > abstractExpr m pre lvs env (Variable v)
 >   | isQualified v = return (Variable v)
 >   | otherwise = maybe (return (Variable v)) (abstractExpr m pre lvs env)
->                       (lookupEnv (unqualify v) env)
+>                       (Map.lookup (unqualify v) env)
 > abstractExpr _ _ _ _ (Constructor c) = return (Constructor c)
 > abstractExpr m pre lvs env (Apply e1 e2) =
 >   do
@@ -216,14 +217,6 @@
 > abstractAlt m pre lvs env (Alt p t rhs) =
 >   liftM (Alt p t) (abstractRhs m pre (lvs ++ bv t) env rhs)
 
-> abstractCondExpr :: ModuleIdent -> String -> [Ident] -> AbstractEnv
->                  -> CondExpr -> AbstractState CondExpr
-> abstractCondExpr m pre lvs env (CondExpr p g e) =
->   do
->     g' <- abstractExpr m pre lvs env g
->     e' <- abstractExpr m pre lvs env e
->     return (CondExpr p g' e')
-
 \end{verbatim}
 \paragraph{Lifting}
 After the abstraction pass, all local function declarations are lifted
@@ -273,10 +266,6 @@
 > liftAlt (Alt p t rhs) = (Alt p t rhs',ds')
 >   where (rhs',ds') = liftRhs rhs
 
-> liftCondExpr :: CondExpr -> (CondExpr,[Decl])
-> liftCondExpr (CondExpr p g e) = (CondExpr p g' e',ds' ++ ds'')
->   where (g',ds') = liftExpr g
->         (e',ds'') = liftExpr e
 
 \end{verbatim}
 \paragraph{Auxiliary definitions}
diff --git a/src/Message.hs b/src/Message.hs
deleted file mode 100644
--- a/src/Message.hs
+++ /dev/null
@@ -1,74 +0,0 @@
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
---
--- Message - A library for dealing with compiler messages
---
--- Note: This module overwrites the functions declared in "Message"
---                
--- January 2006,
--- Martin Engelke (men@informatik.uni-kiel.de)
---
-module Message where
-
-import Position
-
-
--------------------------------------------------------------------------------
-
--- Type for representing compiler messages (currently errors and warnings)
-data Message = Message MessageType (Maybe Position) String
-
--- Data type for representing available compiler message types
-data MessageType = Warning WarningType | Error deriving Eq
-
--- the different warnings are categorized by WarningType
-data WarningType = UnrefTypeVar
-                 | UnrefVar
-                 | ShadowingVar
-                 | IdleCaseAlt
-                 | OverlapCase
-                 | OverlapRules
-                 | RulesNotTogether
-                 | MultipleImportModule
-                 | MultipleImportSymbol
-                 | MultipleHiding 
-                 deriving Eq
-
--- An instance of Show for converting messages to readable strings
-instance Show Message where
- show (Message (Warning _) mpos msg) = showMessage "Warning" mpos msg
- show (Message Error   mpos msg) = showMessage "ERROR" mpos msg
-
-
--------------------------------------------------------------------------------
-
---
-message :: MessageType -> Position -> String -> Message
-message mtype pos msg = Message mtype (Just pos) msg
-
---
-message_ :: MessageType -> String -> Message
-message_ mtype msg = Message mtype Nothing msg
-
---
-countMessages :: MessageType -> [Message] -> Int
-countMessages mtype msgs = length (filter (((==) mtype) . messageType) msgs)
-
---
-messageType :: Message -> MessageType
-messageType (Message mtype _ _) = mtype
-
-
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-
---
-showMessage :: String -> (Maybe Position) -> String -> String
-showMessage what mpos msg
-   = what ++ ": " ++ pos ++ msg
- where
- pos = maybe "" (\p -> show p ++ ": ") mpos
-
-
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
diff --git a/src/Modules.lhs b/src/Modules.lhs
--- a/src/Modules.lhs
+++ b/src/Modules.lhs
@@ -15,54 +15,59 @@
 import declarations are commented out
 \begin{verbatim}
 
-> module Modules(compileModule, compileModule_,
+> module Modules(compileModule,
+>                importPrelude, patchModuleId,
 >	         loadInterfaces, transModule,
 >	         simpleCheckModule, checkModule
 >	        ) where
 
+
 > import Data.List
+> import qualified Data.Map as Map
 > import System.IO
 > import Data.Maybe
 > import Control.Monad
 
+> import Curry.Base.MessageMonad
+> import Curry.Base.Position
+> import Curry.Base.Ident
+> import Curry.Syntax
+> import Curry.Syntax.Pretty(ppModule,ppIDecl)
+> import Curry.Syntax.ShowModule(showModule)
+
 > import Base
-> import Unlit(unlit)
-> import CurryParser(parseSource,parseGoal) -- xxxGoal entfernen
-> import ShowCurrySyntax(showModule)
-> import KindCheck(kindCheck,kindCheckGoal)
+> import Types
+> import KindCheck(kindCheck)
 > import SyntaxCheck(syntaxCheck)
-> import PrecCheck(precCheck,precCheckGoal)
-> import TypeCheck(typeCheck,typeCheckGoal)
-> import WarnCheck
-> import Message
+> import PrecCheck(precCheck)
+> import TypeCheck(typeCheck)
+> import WarnCheck(warnCheck)
 > import Arity
 > import Imports(importInterface,importInterfaceIntf,importUnifyData)
 > import Exports(expandInterface,exportInterface)
-> import Eval(evalEnv,evalEnvGoal)
-> import Qual(qual,qualGoal)
-> import Desugar(desugar,desugarGoal)
+> import Eval(evalEnv)
+> import Qual(qual)
+> import Desugar(desugar)
 > import Simplify(simplify)
 > import Lift(lift)
-> import qualified IL
-> import ILTrans(ilTrans,ilTransIntf)
-> import ILxml(xmlModule) -- check
-> import ExtendedFlat
+> import qualified IL.Type as IL
+> import IL.CurryToIL(ilTrans)
+> import IL.XML(xmlModule)
+> import Curry.ExtendedFlat
 > import GenFlatCurry (genFlatCurry,genFlatInterface)
-> import AbstractCurry
+> import qualified Curry.AbstractCurry as AC
 > import GenAbstractCurry
 > import InterfaceCheck
 > import CurryEnv
-> import CurryPP(ppModule,ppInterface,ppIDecl,ppGoal)
-> import qualified ILPP(ppModule)
+> import qualified IL.Pretty(ppModule)
 > import CurryCompilerOpts(Options(..),Dump(..))
-> import CompilerResults
 > import CaseCompletion
 > import PathUtils
+> import Filenames
 > import TypeSubst
-> import Pretty
-> import Error
-> import Env
+> import PrettyCombinators
 > import TopEnv
+> import qualified Curry.ExtendedFlat as EF 
 
 \end{verbatim}
 The function \texttt{compileModule} is the main entry-point of this
@@ -88,13 +93,10 @@
 code are obsolete and commented out.
 \begin{verbatim}
 
-> compileModule :: Options -> FilePath -> IO ()
-> compileModule opts fn = compileModule_ opts fn >> return ()
-
-> compileModule_ :: Options -> FilePath -> IO CompilerResults
-> compileModule_ opts fn =
+> compileModule :: Options -> FilePath -> IO (Maybe FilePath)
+> compileModule opts fn =
 >   do
->     mod <- liftM (parseModule likeFlat fn) (readModule fn)
+>     mod <- liftM (importPrelude fn . ok . parseModule likeFlat fn) (readModule fn)
 >     let m = patchModuleId fn mod
 >     checkModuleId fn m
 >     mEnv <- loadInterfaces (importPaths opts) m
@@ -103,12 +105,12 @@
 >          do (tyEnv, tcEnv, aEnv, m', intf, _) <- simpleCheckModule opts mEnv m
 >             if uacy then genAbstract opts fn tyEnv tcEnv m'
 >                     else do
->                       let outputFile = maybe (replaceExtension fn sourceRepExt) 
+>                       let outputFile = maybe (sourceRepName fn)
 >                                              id 
 >                                              (output opts)
 >                           outputMod = showModule m'
 >                       writeModule outputFile outputMod
->                       return defaultResults
+>                       return Nothing
 >        else
 >          do (tyEnv, tcEnv, aEnv, m', intf, _) <- checkModule opts mEnv m
 >             let (il,aEnv',dumps) = transModule fcy False False 
@@ -125,15 +127,11 @@
 >         genCode opts fn mEnv tyEnv tcEnv aEnv intf m il
 >            | fcy || xml = genFlat opts fn mEnv tyEnv tcEnv aEnv intf m il
 >            | acy        = genAbstract opts fn tyEnv tcEnv m
->            | otherwise  = return defaultResults
-
-> parseModule :: Bool -> FilePath -> String -> Module
-> parseModule likeFlat fn =
->   importPrelude fn . ok . parseSource likeFlat fn . unlitLiterate fn
+>            | otherwise  = return Nothing
 
 > loadInterfaces :: [FilePath] -> Module -> IO ModuleEnv
 > loadInterfaces paths (Module m _ ds) =
->   foldM (loadInterface paths [m]) emptyEnv
+>   foldM (loadInterface paths [m]) Map.empty
 >         [(p,m) | ImportDecl p m _ _ _ <- ds]
 
 > checkModuleId :: Monad m => FilePath -> Module -> m ()
@@ -146,7 +144,7 @@
 >	        ++ ".curry\"")
 
 > simpleCheckModule :: Options -> ModuleEnv -> Module 
->	    -> IO (ValueEnv,TCEnv,ArityEnv,Module,Interface,[Message])
+>	    -> IO (ValueEnv,TCEnv,ArityEnv,Module,Interface,[WarnMsg])
 > simpleCheckModule opts mEnv (Module m es ds) =
 >   do unless (noWarn opts) (printMessages msgs)
 >      return (tyEnv'', tcEnv, aEnv'', modul, intf, msgs)
@@ -160,12 +158,12 @@
 >			   $ kindCheck m tcEnv topDs
 >         ds' = impDs ++ qual m tyEnv topDs'
 >         modul = (Module m es ds') --expandInterface (Module m es ds') tcEnv tyEnv
->         (pEnv'',tcEnv'',tyEnv'',aEnv'') 
+>         (_,tcEnv'',tyEnv'',aEnv'') 
 >            = qualifyEnv mEnv pEnv' tcEnv tyEnv aEnv
 >         intf = exportInterface modul pEnv' tcEnv'' tyEnv''
 
 > checkModule :: Options -> ModuleEnv -> Module 
->      -> IO (ValueEnv,TCEnv,ArityEnv,Module,Interface,[Message])
+>      -> IO (ValueEnv,TCEnv,ArityEnv,Module,Interface,[WarnMsg])
 > checkModule opts mEnv (Module m es ds) =
 >   do unless (noWarn opts) (printMessages msgs)
 >      when (m == mkMIdent ["field114..."])
@@ -216,8 +214,8 @@
 >	           (DumpDesugared,ppModule desugared),
 >                  (DumpSimplified,ppModule simplified),
 >                  (DumpLifted,ppModule lifted),
->                  (DumpIL,ILPP.ppModule il),
->	           (DumpCase,ILPP.ppModule il')
+>                  (DumpIL,IL.Pretty.ppModule il),
+>	           (DumpCase,IL.Pretty.ppModule il')
 >	          ]
 
 > qualifyEnv :: ModuleEnv -> PEnv -> TCEnv -> ValueEnv -> ArityEnv
@@ -228,7 +226,7 @@
 >    foldr bindGlobal tyEnv' (localBindings tyEnv),
 >    foldr bindQual aEnv' (localBindings aEnv))
 >   where (pEnv',tcEnv',tyEnv',aEnv') =
->           foldl importInterface initEnvs (envToList mEnv)
+>           foldl importInterface initEnvs (Map.toList mEnv)
 >         importInterface (pEnv,tcEnv,tyEnv,aEnv) (m,ds) =
 >           importInterfaceIntf (Interface m ds) pEnv tcEnv tyEnv aEnv
 >         bindQual (_,y) = qualBindTopEnv "Modules.qualifyEnv" (origName y) y
@@ -236,30 +234,18 @@
 >           | uniqueId x == 0 = bindQual (x,y)
 >           | otherwise = bindTopEnv "Modules.qualifyEnv" x y
 
-> --ilImports :: ValueEnv -> TCEnv -> ModuleEnv -> IL.Module -> [IL.Decl]
-> --ilImports tyEnv tcEnv mEnv (IL.Module _ is _) =
-> --  concat [ilTransIntf tyEnv tcEnv (Interface m ds) 
-> --           | (m,ds) <- envToList mEnv, m `elem` is]
-
 > writeXML :: Maybe FilePath -> FilePath -> CurryEnv -> IL.Module -> IO ()
 > writeXML tfn sfn cEnv il = writeModule ofn (showln code)
->   where ofn  = fromMaybe (replaceExtension sfn xmlExt) tfn
+>   where ofn  = fromMaybe (xmlName sfn) tfn
 >         code = (xmlModule cEnv il)
 
 > writeFlat :: Options -> Maybe FilePath -> FilePath -> CurryEnv -> ModuleEnv 
 >              -> ValueEnv -> TCEnv -> ArityEnv -> IL.Module -> IO Prog
 > writeFlat opts tfn sfn cEnv mEnv tyEnv tcEnv aEnv il
 >   = writeFlatFile opts (genFlatCurry opts cEnv mEnv tyEnv tcEnv aEnv il)
->                        (fromMaybe (replaceExtension sfn flatExt) tfn)
-
-> writeFInt :: Options -> Maybe FilePath -> FilePath -> CurryEnv -> ModuleEnv
->              -> ValueEnv -> TCEnv -> ArityEnv -> IL.Module -> IO Prog
-> writeFInt opts tfn sfn cEnv mEnv tyEnv tcEnv aEnv il 
->   = writeFlatFile opts{extendedFlat=False}
->                  (genFlatInterface opts cEnv mEnv tyEnv tcEnv aEnv il)
->                  (fromMaybe (takeBaseName sfn ++ fintExt) tfn)
+>                        (fromMaybe (flatName sfn) tfn)
 
-> writeFlatFile :: (Show a) => Options -> (Prog, [a]) -> String -> IO Prog
+> writeFlatFile :: Options -> (Prog, [WarnMsg]) -> String -> IO Prog
 > writeFlatFile opts@Options{extendedFlat=ext} (res,msgs) fname = do
 >         unless (noWarn opts) (printMessages msgs)
 >	  if ext then writeExtendedFlat fname res
@@ -270,125 +256,20 @@
 > writeTypedAbs :: Maybe FilePath -> FilePath -> ValueEnv -> TCEnv -> Module
 >	           -> IO ()
 > writeTypedAbs tfn sfn tyEnv tcEnv mod
->    = writeCurry fname (genTypedAbstract tyEnv tcEnv mod)
->  where fname = fromMaybe (replaceExtension sfn acyExt) tfn
+>    = AC.writeCurry fname (genTypedAbstract tyEnv tcEnv mod)
+>  where fname = fromMaybe (acyName sfn) tfn
 
 > writeUntypedAbs :: Maybe FilePath -> FilePath -> ValueEnv -> TCEnv  
 >	             -> Module -> IO ()
 > writeUntypedAbs tfn sfn tyEnv tcEnv mod
->    = writeCurry fname (genUntypedAbstract tyEnv tcEnv mod)
->  where fname = fromMaybe (replaceExtension sfn uacyExt) tfn
+>    = AC.writeCurry fname (genUntypedAbstract tyEnv tcEnv mod)
+>  where fname = fromMaybe (uacyName sfn) tfn
 
 > showln :: Show a => a -> String
 > showln x = shows x "\n"
 
 \end{verbatim}
-A goal is compiled with respect to a given module. If no module is
-specified the Curry prelude is used. The source module has to be
-parsed and type checked before the goal can be compiled.  Otherwise
-compilation of a goal is similar to that of a module.
 
-\em{Note:} These functions are obsolete when using the MCC as frontend
-for PAKCS.
-\begin{verbatim}
-
-> --compileGoal :: Options -> Maybe String -> Maybe FilePath -> IO ()
-> --compileGoal opts g fn =
-> --  do
-> --    (ccode,dumps) <- maybe (return startupCode) goalCode g
-> --    mapM_ (doDump opts) dumps
-> --    writeCCode ofn ccode
-> --  where ofn = fromMaybe (internalError "No filename for startup code")
-> --                        (output opts)
-> --        startupCode = (genMain "curry_run",[])
-> --        goalCode = doCompileGoal (debug opts) (importPath opts) fn
-
-> --doCompileGoal :: Bool -> [FilePath] -> Maybe FilePath -> String
-> --              -> IO (CFile,[(Dump,Doc)])
-> --doCompileGoal debug paths fn g =
-> --  do
-> --    (mEnv,_,ds) <- loadGoalModule paths fn
-> --    let (tyEnv,g') = checkGoal mEnv ds (ok (parseGoal g))
-> --        (ccode,dumps) =
-> --          transGoal debug runGoal mEnv tyEnv (mkIdent "goal") g'
-> --        ccode' = genMain runGoal
-> --    return (mergeCFile ccode ccode',dumps)
-> --  where runGoal = "curry_runGoal"
-
-> --typeGoal :: Options -> String -> Maybe FilePath -> IO ()
-> --typeGoal opts g fn =
-> --  do
-> --    (mEnv,m,ds) <- loadGoalModule (importPath opts) fn
-> --    let (tyEnv,Goal _ e _) = checkGoal mEnv ds (ok (parseGoal g))
-> --    print (ppType m (typeOf tyEnv e))
-
-> --loadGoalModule :: [FilePath] -> Maybe FilePath
-> --               -> IO (ModuleEnv,ModuleIdent,[Decl])
-> --loadGoalModule paths fn =
-> --  do
-> --    Module m _ ds <- maybe (return emptyModule) parseGoalModule fn
-> --    mEnv <- loadInterfaces paths (Module m Nothing ds)
-> --    let (_,_,_,_,intf) = checkModule mEnv (Module m Nothing ds)
-> --    return (bindModule intf mEnv,m,filter isImportDecl ds ++ [importMain m])
-> --  where emptyModule = importPrelude "" (Module emptyMIdent Nothing [])
-> --        parseGoalModule fn = liftM (parseModule False fn) (readFile fn)
-> --        importMain m = ImportDecl (first "") m False Nothing Nothing
-
-> --checkGoal :: ModuleEnv -> [Decl] -> Goal -> (ValueEnv,Goal)
-> --checkGoal mEnv impDs g = (tyEnv'',qualGoal tyEnv' g')
-> --  where (pEnv,tcEnv,tyEnv,aEnv) = importModules mEnv impDs
-> --        g' = precCheckGoal pEnv $ syntaxCheckGoal tyEnv
-> --                                $ kindCheckGoal tcEnv g
-> --        tyEnv' = typeCheckGoal tcEnv tyEnv g'
-> --        (_,_,tyEnv'',_) = qualifyEnv mEnv pEnv tcEnv tyEnv' emptyTopEnv
-
-> --transGoal :: Bool -> String -> ModuleEnv -> ValueEnv -> Ident -> Goal
-> --          -> (CFile,[(Dump,Doc)])
-> --transGoal debug run mEnv tyEnv goalId g = (ccode,dumps)
-> --  where qGoalId = qualifyWith emptyMIdent goalId
-> --        evEnv = evalEnvGoal g
-> --        (vs,desugared,tyEnv') = desugarGoal debug tyEnv emptyMIdent goalId g
-> --        (simplified,tyEnv'') = simplify False tyEnv' evEnv desugared
-> --        (lifted,tyEnv''',evEnv') = lift tyEnv'' evEnv simplified
-> --        il = ilTrans False tyEnv''' evEnv' lifted
-> --        ilDbg = if debug then dAddMain goalId (dTransform False il) else il
-> --        ilNormal = liftProg ilDbg
-> --        cam = camCompile ilNormal
-> --        imports = camCompileData (ilImports mEnv ilDbg)
-> --        ccode =
-> --          genModule imports cam ++
-> --          genEntry run (fun qGoalId) (fmap (map name) vs)
-> --        dumps = [
-> --            (DumpRenamed,ppGoal g),
-> --            (DumpTypes,ppTypes emptyMIdent (localBindings tyEnv)),
-> --            (DumpDesugared,ppModule desugared),
-> --            (DumpSimplified,ppModule simplified),
-> --            (DumpLifted,ppModule lifted),
-> --            (DumpIL,ILPP.ppModule il),
-> --            (DumpTransformed,ILPP.ppModule ilDbg),
-> --            (DumpNormalized,ILPP.ppModule ilNormal),
-> --            (DumpCam,CamPP.ppModule cam)
-> --          ]
-
-\end{verbatim}
-The compiler adds a startup function for the default goal
-\texttt{main.main} to the \texttt{main} module. Thus, there is no need
-to determine the type of the goal when linking the program.
-\begin{verbatim}
-
-> --compileDefaultGoal :: Bool -> ModuleEnv -> Interface -> Maybe CFile
-> --compileDefaultGoal debug mEnv (Interface m ds)
-> --  | m == mainMIdent && any (qMainId ==) [f | IFunctionDecl _ f _ _ <- ds] =
-> --      Just ccode
-> --  | otherwise = Nothing
-> --  where qMainId = qualify mainId
-> --        mEnv' = bindModule (Interface m ds) mEnv
-> --        (tyEnv,g) =
-> --          checkGoal mEnv' [ImportDecl (first "") m False Nothing Nothing]
-> --                    (Goal (first "") (Variable qMainId) [])
-> --        (ccode,_) = transGoal debug "curry_run" mEnv' tyEnv mainId g
-
-\end{verbatim}
 The function \texttt{importModules} brings the declarations of all
 imported modules into scope for the current module.
 \begin{verbatim}
@@ -397,7 +278,7 @@
 > importModules mEnv ds = (pEnv,importUnifyData tcEnv,tyEnv,aEnv)
 >   where (pEnv,tcEnv,tyEnv,aEnv) = foldl importModule initEnvs ds
 >         importModule (pEnv,tcEnv,tyEnv,aEnv) (ImportDecl p m q asM is) =
->           case lookupModule m mEnv of
+>           case Map.lookup m mEnv of
 >             Just ds -> importInterface p (fromMaybe m asM) q is
 >                                        (Interface m ds) pEnv tcEnv tyEnv aEnv
 >             Nothing -> internalError "importModule"
@@ -421,7 +302,7 @@
 > importLabels mEnv ds = foldl importLabelTypes initLabelEnv ds
 >   where
 >   importLabelTypes lEnv (ImportDecl p m _ asM is) =
->     case (lookupModule m mEnv) of
+>     case (Map.lookup m mEnv) of
 >       Just ds' -> foldl (importLabelType p (fromMaybe m asM) is) lEnv ds'
 >       Nothing -> internalError "importLabels"
 >   importLabelTypes lEnv _ = lEnv
@@ -449,10 +330,10 @@
 
 > addImportedLabels :: ModuleIdent -> LabelEnv -> ValueEnv -> ValueEnv
 > addImportedLabels m lEnv tyEnv = 
->   foldr addLabelType tyEnv (concatMap snd (envToList lEnv))
+>   foldr addLabelType tyEnv (concatMap snd (Map.toList lEnv))
 >   where
 >   addLabelType (LabelType l r ty) tyEnv = 
->     let m' = fromMaybe m (fst (splitQualIdent r))
+>     let m' = fromMaybe m (qualidMod r)
 >     in  importTopEnv m' l 
 >                      (Label (qualify l) (qualQualify m' r) (polyType ty)) 
 >	               tyEnv
@@ -511,7 +392,7 @@
 > importPrelude :: FilePath -> Module -> Module
 > importPrelude fn (Module m es ds) =
 >   Module m es (if m == preludeMIdent then ds else ds')
->   where ids = filter isImportDecl ds
+>   where ids = [decl | decl@(ImportDecl _ _ _ _ _) <- ds]
 >         ds' = ImportDecl (first fn) preludeMIdent
 >                          (preludeMIdent `elem` map importedModule ids)
 >                          Nothing Nothing : ds
@@ -536,7 +417,7 @@
 >       lookupInterface paths m >>=
 >       maybe (errorAt p (interfaceNotFound m))
 >             (compileInterface paths ctxt mEnv m)
->   where isLoaded m mEnv = maybe False (const True) (lookupModule m mEnv)
+>   where isLoaded m mEnv = maybe False (const True) (Map.lookup m mEnv)
 
 \end{verbatim}
 After reading an interface, all imported interfaces are recursively
@@ -571,18 +452,7 @@
 >         (map (\i -> (p, mkMIdent [i])) is)
 >  where p = first m
 
-> --checkInterface :: ModuleEnv -> Interface -> Interface
-> --checkInterface mEnv (Interface m ds) =
-> --  intfCheck pEnv tcEnv tyEnv (Interface m ds)
-> --  where (pEnv,tcEnv,tyEnv) = foldl importInterface initEnvs ds
-> --        importInterface (pEnv,tcEnv,tyEnv) (IImportDecl p m) =
-> --          case lookupModule m mEnv of
-> --            Just ds -> importInterfaceIntf (Interface m ds) pEnv tcEnv tyEnv
-> --            Nothing -> internalError "importInterface"
-> --        importInterface (pEnv,tcEnv,tyEnv) _ = (pEnv,tcEnv,tyEnv)
 
-
-\end{verbatim}
 Interface files are updated by the Curry builder when necessary.
 (see module \texttt{CurryBuilder}).
 
@@ -601,25 +471,6 @@
 the file is closed.
 \begin{verbatim}
 
-> --updateInterface :: FilePath -> Interface -> IO ()
-> --updateInterface sfn i =
-> --  do
-> --    eq <- catch (matchInterface ifn i) (const (return False))
-> --    unless eq (writeInterface ifn i)
-> --  where ifn = dropExtension sfn ++ intfExt
-
-> --matchInterface :: FilePath -> Interface -> IO Bool
-> --matchInterface ifn i =
-> --  do
-> --    h <- openFile ifn ReadMode
-> --    s <- hGetContents h
-> --    case parseInterface ifn s of
-> --      Ok i' | i `intfEquiv` fixInterface i' -> return True
-> --      _ -> hClose h >> return False
-
-> --writeInterface :: FilePath -> Interface -> IO ()
-> --writeInterface ifn = writeFile ifn . showln . ppInterface
-
 \end{verbatim}
 The compiler searches for interface files in the import search path
 using the extension \texttt{".fint"}. Note that the current
@@ -627,24 +478,10 @@
 \begin{verbatim}
 
 > lookupInterface :: [FilePath] -> ModuleIdent -> IO (Maybe FilePath)
-> lookupInterface paths m = lookupFile ("":paths) [fintExt] ifn
+> lookupInterface paths m = lookupFile ("":paths) [flatIntExt] ifn
 >   where ifn = foldr1 catPath (moduleQualifiers m)
 
 \end{verbatim}
-Literate source files use the extension \texttt{".lcurry"}.
-\begin{verbatim}
-
-> unlitLiterate :: FilePath -> String -> String
-> unlitLiterate fn s
->   | not (isLiterateSource fn) = s
->   | null es = s'
->   | otherwise = error es
->   where (es,s') = unlit fn s
-
-> isLiterateSource :: FilePath -> Bool
-> isLiterateSource fn = litExt `isSuffixOf` fn
-
-\end{verbatim}
 The \texttt{doDump} function writes the selected information to the
 standard output.
 \begin{verbatim}
@@ -678,7 +515,7 @@
 \begin{verbatim}
 
 > genFlat :: Options -> FilePath -> ModuleEnv -> ValueEnv -> TCEnv -> ArityEnv 
->            -> Interface -> Module -> IL.Module -> IO CompilerResults
+>            -> Interface -> Module -> IL.Module -> IO (Maybe FilePath)
 > genFlat opts fname mEnv tyEnv tcEnv aEnv intf mod il
 >   | flat opts
 >     = do writeFlat opts Nothing fname cEnv mEnv tyEnv tcEnv aEnv il
@@ -686,7 +523,7 @@
 >          if force opts
 >            then 
 >              do writeInterface flatInterface intMsgs
->                 return defaultResults
+>                 return Nothing
 >            else 
 >               do mfint <- readFlatInterface fintName
 >                  let flatIntf = fromMaybe emptyIntf mfint
@@ -694,14 +531,14 @@
 >                        && not (interfaceCheck flatIntf flatInterface)
 >                     then 
 >                        do writeInterface flatInterface intMsgs
->                           return defaultResults
->                     else return defaultResults
+>                           return Nothing
+>                     else return Nothing
 >   | flatXml opts
->     = writeXML (output opts) fname cEnv il >> return defaultResults
+>     = writeXML (output opts) fname cEnv il >> return Nothing
 >   | otherwise
 >     = internalError "@Modules.genFlat: illegal option"
 >  where
->    fintName = replaceExtension fname fintExt
+>    fintName = flatIntName fname
 >    cEnv = curryEnv mEnv tcEnv intf mod
 >    emptyIntf = Prog "" [] [] [] []
 >    writeInterface intf msgs = do
@@ -710,20 +547,20 @@
 
 
 > genAbstract :: Options -> FilePath  -> ValueEnv -> TCEnv -> Module 
->                -> IO CompilerResults
+>                -> IO (Maybe FilePath)
 > genAbstract opts fname tyEnv tcEnv mod
 >    | abstract opts
 >      = do writeTypedAbs Nothing fname tyEnv tcEnv mod 
->           return defaultResults
+>           return Nothing
 >    | untypedAbstract opts
 >      = do writeUntypedAbs Nothing fname tyEnv tcEnv mod
->           return defaultResults
+>           return Nothing
 >    | otherwise
 >      = internalError "@Modules.genAbstract: illegal option"
 
-> printMessages :: Show a => [a] -> IO ()
+> printMessages :: [WarnMsg] -> IO ()
 > printMessages []   = return ()
-> printMessages msgs = hPutStrLn stderr $ unlines $ map show msgs
+> printMessages msgs = hPutStrLn stderr $ unlines $ map showWarning msgs
 
 \end{verbatim}
 The function \texttt{ppTypes} is used for pretty-printing the types
@@ -756,20 +593,6 @@
 
 
 \end{verbatim}
-Various filename extensions
-\begin{verbatim}
-
-> cExt = ".c"
-> xmlExt = "_flat.xml"
-> flatExt = ".fcy"
-> fintExt = ".fint"
-> acyExt = ".acy"
-> uacyExt = ".uacy"
-> sourceRepExt = ".cy"
-> intfExt = ".icurry"
-> litExt = ".lcurry"
-
-\end{verbatim}
 Error functions.
 \begin{verbatim}
 
@@ -789,3 +612,78 @@
 >   "Expected interface for " ++ show m ++ " but found " ++ show m'
 
 \end{verbatim}
+
+
+
+
+> bindFlatInterface :: Prog -> ModuleEnv -> ModuleEnv
+> bindFlatInterface (Prog m imps ts fs os)
+>    = Map.insert (mkMIdent [m])
+>      ((map genIImportDecl imps)
+>       ++ (map genITypeDecl ts')
+>       ++ (map genIFuncDecl fs)
+>       ++ (map genIOpDecl os))
+>  where
+>  genIImportDecl :: String -> IDecl
+>  genIImportDecl imp = IImportDecl pos (mkMIdent [imp])
+>
+>  genITypeDecl :: TypeDecl -> IDecl
+>  genITypeDecl (Type qn _ is cs)
+>     | recordExt `isPrefixOf` localName qn
+>       = ITypeDecl pos
+>                   (genQualIdent qn)
+>	            (map (genVarIndexIdent "a") is)
+>	            (RecordType (map genLabeledType cs) Nothing)
+>     | otherwise
+>       = IDataDecl pos 
+>                   (genQualIdent qn) 
+>                   (map (genVarIndexIdent "a") is) 
+>                   (map (Just . genConstrDecl) cs)
+>  genITypeDecl (TypeSyn qn _ is t)
+>     = ITypeDecl pos
+>                 (genQualIdent qn)
+>                 (map (genVarIndexIdent "a") is)
+>                 (genTypeExpr t)
+>
+>  genIFuncDecl :: FuncDecl -> IDecl
+>  genIFuncDecl (Func qn a _ t _) 
+>     = IFunctionDecl pos (genQualIdent qn) a (genTypeExpr t)
+>
+>  genIOpDecl :: OpDecl -> IDecl
+>  genIOpDecl (Op qn f p) = IInfixDecl pos (genInfix f) p  (genQualIdent qn)
+>
+>  genConstrDecl :: ConsDecl -> ConstrDecl
+>  genConstrDecl (Cons qn _ _ ts)
+>     = ConstrDecl pos [] (mkIdent (localName qn)) (map genTypeExpr ts)
+>
+>  genLabeledType :: EF.ConsDecl -> ([Ident],Curry.Syntax.TypeExpr)
+>  genLabeledType (Cons qn _ _ [t])
+>     = ([renameLabel (fromLabelExtId (mkIdent $ localName qn))], genTypeExpr t)
+>
+>  genTypeExpr :: EF.TypeExpr -> Curry.Syntax.TypeExpr
+>  genTypeExpr (TVar i)
+>     = VariableType (genVarIndexIdent "a" i)
+>  genTypeExpr (FuncType t1 t2) 
+>     = ArrowType (genTypeExpr t1) (genTypeExpr t2)
+>  genTypeExpr (TCons qn ts) 
+>     = ConstructorType (genQualIdent qn) (map genTypeExpr ts)
+>
+>  genInfix :: EF.Fixity -> Infix
+>  genInfix EF.InfixOp  = Infix
+>  genInfix EF.InfixlOp = InfixL
+>  genInfix EF.InfixrOp = InfixR
+>
+>  genQualIdent :: EF.QName -> QualIdent
+>  genQualIdent EF.QName{modName=mod,localName=name} = 
+>    qualifyWith (mkMIdent [mod]) (mkIdent name)
+>
+>  genVarIndexIdent :: String -> Int -> Ident
+>  genVarIndexIdent v i = mkIdent (v ++ show i)
+>
+>  isSpecialPreludeType :: TypeDecl -> Bool
+>  isSpecialPreludeType (Type EF.QName{modName=mod,localName=name} _ _ _) 
+>     = (name == "[]" || name == "()") && mod == "Prelude"
+>  isSpecialPreludeType _ = False
+>
+>  pos = first m
+>  ts' = filter (not . isSpecialPreludeType) ts
diff --git a/src/NestEnv.lhs b/src/NestEnv.lhs
--- a/src/NestEnv.lhs
+++ b/src/NestEnv.lhs
@@ -18,13 +18,17 @@
 > module NestEnv(module TopEnv, NestEnv, bindNestEnv,qualBindNestEnv,
 >                lookupNestEnv,qualLookupNestEnv,
 >                toplevelEnv,globalEnv,nestEnv) where
-> import Env
+
+> import qualified Data.Map as Map
+
+> import Curry.Base.Ident
+
 > import TopEnv
-> import Ident
 
-> data NestEnv a = GlobalEnv (TopEnv a) | LocalEnv (NestEnv a) (Env Ident a)
->                  deriving Show
 
+> data NestEnv a = GlobalEnv (TopEnv a) | LocalEnv (NestEnv a) (Map.Map Ident a)
+> --                 deriving Show
+
 > instance Functor NestEnv where
 >   fmap f (GlobalEnv env) = GlobalEnv (fmap f env)
 >   fmap f (LocalEnv genv env) = LocalEnv (fmap f genv) (fmap f env)
@@ -33,9 +37,9 @@
 > bindNestEnv x y (GlobalEnv env) 
 >   = GlobalEnv (bindTopEnv "NestEnv.bindNestEnv" x y env)
 > bindNestEnv x y (LocalEnv genv env) =
->   case lookupEnv x env of
+>   case Map.lookup x env of
 >     Just _ -> error "internal error: bindNestEnv"
->     Nothing -> LocalEnv genv (bindEnv x y env)
+>     Nothing -> LocalEnv genv (Map.insert x y env)
 
 > qualBindNestEnv :: QualIdent -> a -> NestEnv a -> NestEnv a
 > qualBindNestEnv x y (GlobalEnv env) 
@@ -43,15 +47,15 @@
 > qualBindNestEnv x y (LocalEnv genv env)
 >   | isQualified x = error "internal error: qualBindNestEnv"
 >   | otherwise =
->       case lookupEnv x' env of
+>       case Map.lookup x' env of
 >         Just _ -> error "internal error: qualBindNestEnv"
->         Nothing -> LocalEnv genv (bindEnv x' y env)
+>         Nothing -> LocalEnv genv (Map.insert x' y env)
 >   where x' = unqualify x
 
 > lookupNestEnv :: Ident -> NestEnv a -> [a]
 > lookupNestEnv x (GlobalEnv env) = lookupTopEnv x env
 > lookupNestEnv x (LocalEnv genv env) =
->   case lookupEnv x env of
+>   case Map.lookup x env of
 >     Just y -> [y]
 >     Nothing -> lookupNestEnv x genv
 
@@ -68,6 +72,6 @@
 > globalEnv = GlobalEnv
 
 > nestEnv :: NestEnv a -> NestEnv a
-> nestEnv env = LocalEnv env emptyEnv
+> nestEnv env = LocalEnv env Map.empty
 
 \end{verbatim}
diff --git a/src/OldScopeEnv.hs b/src/OldScopeEnv.hs
--- a/src/OldScopeEnv.hs
+++ b/src/OldScopeEnv.hs
@@ -7,10 +7,9 @@
 		    genIdent, genIdentList) where
 
 import Data.Maybe
-
-import Ident
-import Env
+import qualified Data.Map as Map
 
+import Curry.Base.Ident
 
 
 -------------------------------------------------------------------------------
@@ -23,7 +22,7 @@
 
 -- Generates a new instance of a scope table
 newScopeEnv :: ScopeEnv
-newScopeEnv = (newIdEnv, [], 0)
+newScopeEnv = (Map.empty, [], 0)
 
 
 -- Inserts an identifier into the current level of the scope environment
@@ -66,7 +65,7 @@
 beginScope (topleveltab, leveltabs, level)
    = case leveltabs of
        (lt:lts) -> (topleveltab, (lt:lt:lts), level + 1)
-       []       -> (topleveltab, [newIdEnv], 1)
+       []       -> (topleveltab, [Map.empty], 1)
 
 
 -- Decreases the level of the scope. Identifier from higher levels
@@ -116,24 +115,20 @@
 -------------------------------------------------------------------------------
 -- Private declarations...
 
-type IdEnv = Env IdRep Int
+type IdEnv = Map.Map IdRep Int
 
 data IdRep = Name String | Index Int deriving (Eq, Ord)
 
 
 -------------------------------------------------------------------------------
 
---
-newIdEnv :: IdEnv
-newIdEnv = emptyEnv
 
-
 --
 insertId :: Int -> Ident -> IdEnv -> IdEnv
 insertId level ident env
-   = bindEnv (Name (name ident)) 
+   = Map.insert (Name (name ident)) 
              level 
-	     (bindEnv (Index (uniqueId ident)) level env)
+	     (Map.insert (Index (uniqueId ident)) level env)
 
 
 --
@@ -143,7 +138,7 @@
 
 --
 getIdLevel :: Ident -> IdEnv -> Maybe Int
-getIdLevel ident env = lookupEnv (Index (uniqueId ident)) env
+getIdLevel ident env = Map.lookup (Index (uniqueId ident)) env
 
 
 --
@@ -158,12 +153,12 @@
 
 --
 nameExists :: String -> IdEnv -> Bool
-nameExists name env = isJust (lookupEnv (Name name) env)
+nameExists name env = isJust (Map.lookup (Name name) env)
 
 
 --
 indexExists :: Int -> IdEnv -> Bool
-indexExists index env = isJust (lookupEnv (Index index) env)
+indexExists index env = isJust (Map.lookup (Index index) env)
 
 
 -------------------------------------------------------------------------------
diff --git a/src/PatchPrelude.hs b/src/PatchPrelude.hs
--- a/src/PatchPrelude.hs
+++ b/src/PatchPrelude.hs
@@ -1,7 +1,7 @@
 module PatchPrelude where
 
 
-import ExtendedFlat
+import Curry.ExtendedFlat
 
 
 -- the prelude has to be extended by data declarations for list and tuples
diff --git a/src/PathUtils.hs b/src/PathUtils.hs
--- a/src/PathUtils.hs
+++ b/src/PathUtils.hs
@@ -6,12 +6,13 @@
 -}
 
 module PathUtils(-- re-exports from System.FilePath:
-                 takeBaseName, replaceExtension, dropExtension,
+                 takeBaseName, -- replaceExtension,
+                 dropExtension,
                  takeDirectory, takeExtension, 
                  pathSeparator,
                  catPath,
 
-                 lookupFile,
+                 lookupModule, lookupFile, getCurryPath,
                  writeModule,readModule,
                  doesModuleExist,maybeReadModule,getModuleModTime) where
 
@@ -21,7 +22,16 @@
 
 import Control.Monad (unless)
 
+import Curry.Base.Ident
+import Filenames
 
+
+lookupModule :: [FilePath] -> [FilePath] -> ModuleIdent
+             -> IO (Maybe FilePath)
+lookupModule paths libraryPaths m
+    = lookupFile ("" : paths ++ libraryPaths) moduleExts fn
+      where fn = foldr1 catPath (moduleQualifiers m)
+
 catPath :: FilePath -> FilePath -> FilePath
 catPath = combine
 
@@ -65,7 +75,7 @@
 writeModule filename contents = do
   let filename' = inCurrySubdir filename
       subdir = takeDirectory filename'
-  ensureDirectoryExists (takeDirectory filename')
+  ensureDirectoryExists subdir
   writeFile filename' contents
 
 ensureDirectoryExists :: FilePath -> IO ()
@@ -93,3 +103,20 @@
 
 getModuleModTime :: FilePath -> IO ClockTime
 getModuleModTime = onExistingFileDo getModificationTime
+
+
+{-
+  The function \verb|getCurryPath| searches in predefined paths
+  for the corresponding \texttt{.curry} or \texttt{.lcurry} file, 
+  if the given file name has no extension.
+-}
+getCurryPath :: [FilePath] -> FilePath -> IO (Maybe FilePath)
+getCurryPath paths fn = lookupFile filepaths exts fn
+    where
+      filepaths = "":paths'
+      fnext = takeExtension fn
+      exts | null fnext = sourceExts
+           | otherwise  = [fnext]
+      paths' | pathSeparator `elem` fn = []
+             | otherwise               = paths
+
diff --git a/src/Position.lhs b/src/Position.lhs
deleted file mode 100644
--- a/src/Position.lhs
+++ /dev/null
@@ -1,94 +0,0 @@
-> {-# LANGUAGE DeriveDataTypeable #-}
-
-% -*- LaTeX -*-
-% $Id: Position.lhs,v 1.2 2000/10/08 09:55:43 lux Exp $
-%
-% $Log: Position.lhs,v $
-% Revision 1.2  2000/10/08 09:55:43  lux
-% Column numbers now start at 1. If the column number is less than 1 it
-% will not be shown.
-%
-% Revision 1.1  2000/07/23 11:03:37  lux
-% Positions now implemented in a separate module.
-%
-%
-\nwfilename{Position.lhs}
-\section{Positions}
-A source file position consists of a filename, a line number, and a
-column number. A tab stop is assumed at every eighth column.
-\begin{verbatim}
-
-> module Position where
-> import Data.Generics
-
-> newtype SrcRef = SrcRef [Int] deriving (Typeable,Data) -- a pointer to the origin
-
--- the instances for standard classes or such that SrcRefs are invisible
-
-> instance Show SrcRef where show _ = ""
-> instance Read SrcRef where readsPrec _ s = [(noRef,s)]
-> instance Eq SrcRef   where _ == _ = True
-> instance Ord SrcRef  where compare _ _ = EQ
-
-> noRef :: SrcRef
-> noRef = SrcRef []
->
-> incSrcRef :: SrcRef -> Int -> SrcRef
-> incSrcRef (SrcRef [i]) j = SrcRef [i+j]
-> incSrcRef is  _ = error $ "internal error; increment source ref: " ++ show is
-
-> data Position 
->   = Position{ file :: FilePath, line :: Int, column :: Int, ast :: SrcRef }
->   | AST { ast :: SrcRef }
->   deriving (Eq, Ord,Data,Typeable)
->
-> incPosition :: Position -> Int -> Position
-> incPosition p j = p{ast=incSrcRef (ast p) j}
-
-> instance Read Position where
->   readsPrec p s = 
->     [ (Position{file="",line=i,column=j,ast=noRef},s')  | ((i,j),s') <- readsPrec p s]
-
-> instance Show Position where
->   showsPrec _ Position{file=fn,line=l,column=c} =
->     (if null fn then id else shows fn . showString ", ") .
->     showString "line " . shows l .
->     (if c > 0 then showChar '.' . shows c else id)
->   showsPrec _ AST{} = id
-
-> tabWidth :: Int
-> tabWidth = 8
-
-> first :: FilePath -> Position
-> first fn = Position fn 1 1 noRef
-
-> incr :: Position -> Int -> Position
-> incr p@Position{column=c} n = p{column=c + n}
-
-> next :: Position -> Position
-> next = flip incr 1
-
-> tab :: Position -> Position
-> tab p@Position{column=c} = p{column=c + tabWidth - (c - 1) `mod` tabWidth}
-
-> nl :: Position -> Position
-> nl p@Position{line=l} = p{line=l + 1, column=1}
-
-> noPos, noPos' :: Position
-> noPos  = Position{ file = "", line = 0, column = 0, ast = noRef }
-> noPos' = AST noRef
-
-> showLine :: Position -> String
-> showLine x@Position{line=l,column=c} 
->      | x == noPos = ""
->      | otherwise = "(line " ++ show l ++ "." ++ show c ++ ") "
-
-\end{verbatim}
-
-> class SrcRefOf a where
->   srcRefsOf :: a -> [SrcRef]
->   srcRefsOf = (:[]) . srcRefOf
->   srcRefOf :: a -> SrcRef
->   srcRefOf = head . srcRefsOf
-
-> instance SrcRefOf Position where srcRefOf = ast
diff --git a/src/PrecCheck.lhs b/src/PrecCheck.lhs
--- a/src/PrecCheck.lhs
+++ b/src/PrecCheck.lhs
@@ -16,10 +16,15 @@
 of the operators involved.
 \begin{verbatim}
 
-> module PrecCheck(precCheck,precCheckGoal) where
+> module PrecCheck(precCheck) where
 
 > import Data.List
 
+> import Curry.Base.Position
+> import Curry.Base.Ident
+> import Curry.Syntax
+> import Curry.Syntax.Utils
+
 > import Base
 
 \end{verbatim}
@@ -34,13 +39,13 @@
 > bindPrecs m ds pEnv =
 >   case linear ops of
 >     Linear ->
->       case [PIdent p op | PIdent p op <- ops, op `notElem` bvs] of
+>       case [ op | op <- ops, op `notElem` bvs] of
 >         [] -> foldr bindPrec pEnv fixDs
->         PIdent p op : _ -> errorAt' (undefinedOperator op)
->     NonLinear (PIdent p op) -> errorAt' (duplicatePrecedence op)
+>         op : _ -> errorAt' (undefinedOperator op)
+>     NonLinear op -> errorAt' (duplicatePrecedence op)
 >   where (fixDs,nonFixDs) = partition isInfixDecl ds
 >         bvs = concatMap boundValues nonFixDs
->         ops = [PIdent p op | InfixDecl p _ _ ops <- fixDs, op <- ops]
+>         ops = [ op | InfixDecl p _ _ ops <- fixDs, op <- ops]
 >         bindPrec (InfixDecl _ fix pr ops) pEnv
 >           | p == defaultP = pEnv
 >           | otherwise = foldr (flip (bindP m) p) pEnv ops
@@ -72,11 +77,6 @@
 > precCheck :: ModuleIdent -> PEnv -> [Decl] -> (PEnv,[Decl])
 > precCheck = checkDecls
 
-> precCheckGoal :: PEnv -> Goal -> Goal
-> precCheckGoal pEnv (Goal p e ds) = Goal p (checkExpr m pEnv' e) ds'
->   where (pEnv',ds') = checkDecls m pEnv ds
->         m = emptyMIdent
-
 > checkDecls :: ModuleIdent -> PEnv -> [Decl] -> (PEnv,[Decl])
 > checkDecls m pEnv ds = pEnv' `seq` (pEnv',ds')
 >   where pEnv' = bindPrecs m ds pEnv
@@ -247,8 +247,7 @@
 >       InfixApply (fixUPrec pEnv uop e1 op1 e2) op2 e3
 >   | pr2 > 6 = UnaryMinus uop (fixRPrec pEnv e1 op1 (InfixApply e2 op2 e3))
 >   | otherwise = errorAt' $ ambiguousParse "unary" (qualify uop) (opName op2)
->   where OpPrec fix1 pr1 = opPrec op1 pEnv
->         OpPrec fix2 pr2 = opPrec op2 pEnv
+>   where OpPrec fix2 pr2 = opPrec op2 pEnv
 > fixUPrec _ uop e1 op e2 = UnaryMinus uop (InfixApply e1 op e2)
 
 > fixRPrec :: PEnv -> Expression -> InfixOp -> Expression
diff --git a/src/Pretty.lhs b/src/Pretty.lhs
deleted file mode 100644
--- a/src/Pretty.lhs
+++ /dev/null
@@ -1,905 +0,0 @@
-Hand converted to standard Haskell     -- jcp
-
-*********************************************************************************
-*                                                                               *
-*       John Hughes's and Simon Peyton Jones's Pretty Printer Combinators       *
-*                                                                               *
-*               based on "The Design of a Pretty-printing Library"              *
-*               in Advanced Functional Programming,                             *
-*               Johan Jeuring and Erik Meijer (eds), LNCS 925                   *
-*               http://www.cs.chalmers.se/~rjmh/Papers/pretty.ps                *
-*                                                                               *
-*               Heavily modified by Simon Peyton Jones, Dec 96                  *
-*                                                                               *
-*********************************************************************************
-
-Version 3.0     28 May 1997
-  * Cured massive performance bug.  If you write
-
-        foldl <> empty (map (text.show) [1..10000])
-
-    you get quadratic behaviour with V2.0.  Why?  For just the same reason as you get
-    quadratic behaviour with left-associated (++) chains.
-
-    This is really bad news.  One thing a pretty-printer abstraction should
-    certainly guarantee is insensivity to associativity.  It matters: suddenly
-    GHC's compilation times went up by a factor of 100 when I switched to the
-    new pretty printer.
- 
-    I fixed it with a bit of a hack (because I wanted to get GHC back on the
-    road).  I added two new constructors to the Doc type, Above and Beside:
- 
-         <> = Beside
-         $$ = Above
- 
-    Then, where I need to get to a "TextBeside" or "NilAbove" form I "force"
-    the Doc to squeeze out these suspended calls to Beside and Above; but in so
-    doing I re-associate. It's quite simple, but I'm not satisfied that I've done
-    the best possible job.  I'll send you the code if you are interested.
-
-  * Added new exports:
-        punctuate, hang
-        int, integer, float, double, rational,
-        lparen, rparen, lbrack, rbrack, lbrace, rbrace,
-
-  * fullRender's type signature has changed.  Rather than producing a string it
-    now takes an extra couple of arguments that tells it how to glue fragments
-    of output together:
-
-        fullRender :: Mode
-                   -> Int                       -- Line length
-                   -> Float                     -- Ribbons per line
-                   -> (TextDetails -> a -> a)   -- What to do with text
-                   -> a                         -- What to do at the end
-                   -> Doc
-                   -> a                         -- Result
-
-    The "fragments" are encapsulated in the TextDetails data type:
-        data TextDetails = Chr  Char
-                         | Str  String
-                         | PStr FAST_STRING
-
-    The Chr and Str constructors are obvious enough.  The PStr constructor has a packed
-    string (FAST_STRING) inside it.  It's generated by using the new "ptext" export.
-
-    An advantage of this new setup is that you can get the renderer to do output
-    directly (by passing in a function of type (TextDetails -> IO () -> IO ()),
-    rather than producing a string that you then print.
-
-
-Version 2.0     24 April 1997
-  * Made empty into a left unit for <> as well as a right unit;
-    it is also now true that
-        nest k empty = empty
-    which wasn't true before.
-
-  * Fixed an obscure bug in sep that occassionally gave very wierd behaviour
-
-  * Added $+$
-
-  * Corrected and tidied up the laws and invariants
-
-======================================================================
-Relative to John's original paper, there are the following new features:
-
-1.  There's an empty document, "empty".  It's a left and right unit for 
-    both <> and $$, and anywhere in the argument list for
-    sep, hcat, hsep, vcat, fcat etc.
-
-    It is Really Useful in practice.
-
-2.  There is a paragraph-fill combinator, fsep, that's much like sep,
-    only it keeps fitting things on one line until itc can't fit any more.
-
-3.  Some random useful extra combinators are provided.  
-        <+> puts its arguments beside each other with a space between them,
-            unless either argument is empty in which case it returns the other
-
-
-        hcat is a list version of <>
-        hsep is a list version of <+>
-        vcat is a list version of $$
-
-        sep (separate) is either like hsep or like vcat, depending on what fits
-
-        cat  is behaves like sep,  but it uses <> for horizontal conposition
-        fcat is behaves like fsep, but it uses <> for horizontal conposition
-
-        These new ones do the obvious things:
-                char, semi, comma, colon, space,
-                parens, brackets, braces, 
-                quotes, doubleQuotes
-        
-4.      The "above" combinator, $$, now overlaps its two arguments if the
-        last line of the top argument stops before the first line of the second begins.
-        For example:  text "hi" $$ nest 5 "there"
-        lays out as
-                        hi   there
-        rather than
-                        hi
-                             there
-
-        There are two places this is really useful
-
-        a) When making labelled blocks, like this:
-                Left ->   code for left
-                Right ->  code for right
-                LongLongLongLabel ->
-                          code for longlonglonglabel
-           The block is on the same line as the label if the label is
-           short, but on the next line otherwise.
-
-        b) When laying out lists like this:
-                [ first
-                , second
-                , third
-                ]
-           which some people like.  But if the list fits on one line
-           you want [first, second, third].  You can't do this with
-           John's original combinators, but it's quite easy with the
-           new $$.
-
-        The combinator $+$ gives the original "never-overlap" behaviour.
-
-5.      Several different renderers are provided:
-                * a standard one
-                * one that uses cut-marks to avoid deeply-nested documents 
-                        simply piling up in the right-hand margin
-                * one that ignores indentation (fewer chars output; good for machines)
-                * one that ignores indentation and newlines (ditto, only more so)
-
-6.      Numerous implementation tidy-ups
-        Use of unboxed data types to speed up the implementation
-
-
-
-\begin{code}
-module Pretty (
-        Doc,            -- Abstract
-        Mode(..), TextDetails(..),
-	Style,
-
-        empty, nest,
-
-        text, char, ptext,
-        int, integer, float, double, rational,
-        parens, brackets, braces, quotes, doubleQuotes,
-        semi, comma, colon, space, equals,
-        lparen, rparen, lbrack, rbrack, lbrace, rbrace,
-
-        (<>), (<+>), hcat, hsep, 
-        ($$), ($+$), vcat, 
-        sep, cat, 
-        fsep, fcat, 
-
-        hang, punctuate,
-        
-        renderStyle, 
-        render, fullRender
-  ) where
-
--- Don't import Util( assertPanic ) because it makes a loop in the module structure
-
-import Data.Ratio
-infixl 6 <> 
-infixl 6 <+>
-infixl 5 $$, $+$
-\end{code}
-
-
-
-*********************************************************
-*                                                       *
-\subsection{CPP magic so that we can compile with both GHC and Hugs}
-*                                                       *
-*********************************************************
-
-The library uses unboxed types to get a bit more speed, but these CPP macros
-allow you to use either GHC or Hugs.  To get GHC, just set the CPP variable
-        __GLASGOW_HASKELL__
-
-
-*********************************************************
-*                                                       *
-\subsection{The interface}
-*                                                       *
-*********************************************************
-
-The primitive @Doc@ values
-
-\begin{code}
-empty                     :: Doc
-text                      :: String -> Doc 
-char                      :: Char -> Doc
-
-semi, comma, colon, space, equals              :: Doc
-lparen, rparen, lbrack, rbrack, lbrace, rbrace :: Doc
-
-parens, brackets, braces  :: Doc -> Doc 
-quotes, doubleQuotes      :: Doc -> Doc
-
-int      :: Int -> Doc
-integer  :: Integer -> Doc
-float    :: Float -> Doc
-double   :: Double -> Doc
-rational :: Rational -> Doc
-\end{code}
-
-
-Combining @Doc@ values
-
-\begin{code}
-(<>)   :: Doc -> Doc -> Doc     -- Beside
-hcat   :: [Doc] -> Doc          -- List version of <>
-(<+>)  :: Doc -> Doc -> Doc     -- Beside, separated by space
-hsep   :: [Doc] -> Doc          -- List version of <+>
-
-($$)   :: Doc -> Doc -> Doc     -- Above; if there is no
-                                -- overlap it "dovetails" the two
-vcat   :: [Doc] -> Doc          -- List version of $$
-
-cat    :: [Doc] -> Doc          -- Either hcat or vcat
-sep    :: [Doc] -> Doc          -- Either hsep or vcat
-fcat   :: [Doc] -> Doc          -- ``Paragraph fill'' version of cat
-fsep   :: [Doc] -> Doc          -- ``Paragraph fill'' version of sep
-
-nest   :: Int -> Doc -> Doc     -- Nested
-\end{code}
-
-GHC-specific ones.
-
-\begin{code}
-hang :: Doc -> Int -> Doc -> Doc
-punctuate :: Doc -> [Doc] -> [Doc]      -- punctuate p [d1, ... dn] = [d1 <> p, d2 <> p, ... dn-1 <> p, dn]
-\end{code}
-
-Displaying @Doc@ values. 
-
-\begin{code}
-instance Show Doc where
-  showsPrec prec doc cont = showDoc doc cont
-
-render     :: Doc -> String             -- Uses default style
-fullRender :: Mode
-           -> Int                       -- Line length
-           -> Float                     -- Ribbons per line
-           -> (TextDetails -> a -> a)   -- What to do with text
-           -> a                         -- What to do at the end
-           -> Doc
-           -> a                         -- Result
-
-renderStyle  :: Style -> Doc -> String
-data Style = Style { lineLength     :: Int,     -- In chars
-                     ribbonsPerLine :: Float,   -- Ratio of ribbon length to line length
-                     mode :: Mode
-             }
-style :: Style          -- The default style
-style = Style { lineLength = 100, ribbonsPerLine = 2.5, mode = PageMode }
-
-data Mode = PageMode            -- Normal 
-          | ZigZagMode          -- With zig-zag cuts
-          | LeftMode            -- No indentation, infinitely long lines
-          | OneLineMode         -- All on one line
-
-\end{code}
-
-
-*********************************************************
-*                                                       *
-\subsection{The @Doc@ calculus}
-*                                                       *
-*********************************************************
-
-The @Doc@ combinators satisfy the following laws:
-\begin{verbatim}
-Laws for $$
-~~~~~~~~~~~
-<a1>    (x $$ y) $$ z   = x $$ (y $$ z)
-<a2>    empty $$ x      = x
-<a3>    x $$ empty      = x
-
-        ...ditto $+$...
-
-Laws for <>
-~~~~~~~~~~~
-<b1>    (x <> y) <> z   = x <> (y <> z)
-<b2>    empty <> x      = empty
-<b3>    x <> empty      = x
-
-        ...ditto <+>...
-
-Laws for text
-~~~~~~~~~~~~~
-<t1>    text s <> text t        = text (s++t)
-<t2>    text "" <> x            = x, if x non-empty
-
-Laws for nest
-~~~~~~~~~~~~~
-<n1>    nest 0 x                = x
-<n2>    nest k (nest k' x)      = nest (k+k') x
-<n3>    nest k (x <> y)         = nest k z <> nest k y
-<n4>    nest k (x $$ y)         = nest k x $$ nest k y
-<n5>    nest k empty            = empty
-<n6>    x <> nest k y           = x <> y, if x non-empty
-
-** Note the side condition on <n6>!  It is this that
-** makes it OK for empty to be a left unit for <>.
-
-Miscellaneous
-~~~~~~~~~~~~~
-<m1>    (text s <> x) $$ y = text s <> ((text "" <> x)) $$ 
-                                         nest (-length s) y)
-
-<m2>    (x $$ y) <> z = x $$ (y <> z)
-        if y non-empty
-
-
-Laws for list versions
-~~~~~~~~~~~~~~~~~~~~~~
-<l1>    sep (ps++[empty]++qs)   = sep (ps ++ qs)
-        ...ditto hsep, hcat, vcat, fill...
-
-<l2>    nest k (sep ps) = sep (map (nest k) ps)
-        ...ditto hsep, hcat, vcat, fill...
-
-Laws for oneLiner
-~~~~~~~~~~~~~~~~~
-<o1>    oneLiner (nest k p) = nest k (oneLiner p)
-<o2>    oneLiner (x <> y)   = oneLiner x <> oneLiner y 
-\end{verbatim}
-
-
-You might think that the following verion of <m1> would
-be neater:
-\begin{verbatim}
-<3 NO>  (text s <> x) $$ y = text s <> ((empty <> x)) $$ 
-                                         nest (-length s) y)
-\end{verbatim}
-But it doesn't work, for if x=empty, we would have
-\begin{verbatim}
-        text s $$ y = text s <> (empty $$ nest (-length s) y)
-                    = text s <> nest (-length s) y
-\end{verbatim}
-
-
-
-*********************************************************
-*                                                       *
-\subsection{Simple derived definitions}
-*                                                       *
-*********************************************************
-
-\begin{code}
-semi  = char ';'
-colon = char ':'
-comma = char ','
-space = char ' '
-equals = char '='
-lparen = char '('
-rparen = char ')'
-lbrack = char '['
-rbrack = char ']'
-lbrace = char '{'
-rbrace = char '}'
-
-int      n = text (show n)
-integer  n = text (show n)
-float    n = text (show n)
-double   n = text (show n)
-rational n = text (show n)
--- SIGBJORN wrote instead:
--- rational n = text (show (fromRationalX n))
-
-quotes p        = char '`' <> p <> char '\''
-doubleQuotes p  = char '"' <> p <> char '"'
-parens p        = char '(' <> p <> char ')'
-brackets p      = char '[' <> p <> char ']'
-braces p        = char '{' <> p <> char '}'
-
-
-hcat = foldr (<>)  empty
-hsep = foldr (<+>) empty
-vcat = foldr ($$)  empty
-
-hang d1 n d2 = d1 $$ (nest n d2)
-
-punctuate p []     = []
-punctuate p (d:ds) = go d ds
-                   where
-                     go d [] = [d]
-                     go d (e:es) = (d <> p) : go e es
-\end{code}
-
-
-*********************************************************
-*                                                       *
-\subsection{The @Doc@ data type}
-*                                                       *
-*********************************************************
-
-A @Doc@ represents a {\em set} of layouts.  A @Doc@ with
-no occurrences of @Union@ or @NoDoc@ represents just one layout.
-\begin{code}
-data Doc
- = Empty                                -- empty
- | NilAbove Doc                         -- text "" $$ x
- | TextBeside TextDetails Int Doc       -- text s <> x  
- | Nest Int Doc                         -- nest k x
- | Union Doc Doc                        -- ul `union` ur
- | NoDoc                                -- The empty set of documents
- | Beside Doc Bool Doc                  -- True <=> space between
- | Above  Doc Bool Doc                  -- True <=> never overlap
-
-type RDoc = Doc         -- RDoc is a "reduced Doc", guaranteed not to have a top-level Above or Beside
-
-
-reduceDoc :: Doc -> RDoc
-reduceDoc (Beside p g q) = beside p g (reduceDoc q)
-reduceDoc (Above  p g q) = above  p g (reduceDoc q)
-reduceDoc p              = p
-
-
-data TextDetails = Chr  Char
-                 | Str  String
-                 | PStr String
-space_text = Chr ' '
-nl_text    = Chr '\n'
-\end{code}
-
-Here are the invariants:
-\begin{itemize}
-\item
-The argument of @NilAbove@ is never @Empty@. Therefore
-a @NilAbove@ occupies at least two lines.
-
-\item
-The arugment of @TextBeside@ is never @Nest@.
-
-\item 
-The layouts of the two arguments of @Union@ both flatten to the same string.
-
-\item 
-The arguments of @Union@ are either @TextBeside@, or @NilAbove@.
-
-\item
-The right argument of a union cannot be equivalent to the empty set (@NoDoc@).
-If the left argument of a union is equivalent to the empty set (@NoDoc@),
-then the @NoDoc@ appears in the first line.
-
-\item 
-An empty document is always represented by @Empty@.
-It can't be hidden inside a @Nest@, or a @Union@ of two @Empty@s.
-
-\item 
-The first line of every layout in the left argument of @Union@
-is longer than the first line of any layout in the right argument.
-(1) ensures that the left argument has a first line.  In view of (3),
-this invariant means that the right argument must have at least two
-lines.
-\end{itemize}
-
-\begin{code}
-        -- Arg of a NilAbove is always an RDoc
-nilAbove_ p = NilAbove p
-
-        -- Arg of a TextBeside is always an RDoc
-textBeside_ s sl p = TextBeside s sl p
-
-        -- Arg of Nest is always an RDoc
-nest_ k p = Nest k p
-
-        -- Args of union are always RDocs
-union_ p q = Union p q
-
-\end{code}
-
-
-Notice the difference between
-        * NoDoc (no documents)
-        * Empty (one empty document; no height and no width)
-        * text "" (a document containing the empty string;
-                   one line high, but has no width)
-
-
-
-*********************************************************
-*                                                       *
-\subsection{@empty@, @text@, @nest@, @union@}
-*                                                       *
-*********************************************************
-
-\begin{code}
-empty = Empty
-
-char  c = textBeside_ (Chr c) 1 Empty
-text  s = case length   s of {sl -> textBeside_ (Str s)  sl Empty}
-ptext s = case length s of {sl -> textBeside_ (PStr s) sl Empty}
-
-nest k  p = mkNest k (reduceDoc p)        -- Externally callable version
-
--- mkNest checks for Nest's invariant that it doesn't have an Empty inside it
-mkNest k       (Nest k1 p) = mkNest (k + k1) p
-mkNest k       NoDoc       = NoDoc
-mkNest k       Empty       = Empty
-mkNest 0       p           = p                  -- Worth a try!
-mkNest k       p           = nest_ k p
-
--- mkUnion checks for an empty document
-mkUnion Empty q = Empty
-mkUnion p q     = p `union_` q
-\end{code}
-
-*********************************************************
-*                                                       *
-\subsection{Vertical composition @$$@}
-*                                                       *
-*********************************************************
-
-
-\begin{code}
-p $$  q = Above p False q
-p $+$ q = Above p True q
-
-above :: Doc -> Bool -> RDoc -> RDoc
-above (Above p g1 q1)  g2 q2 = above p g1 (above q1 g2 q2)
-above p@(Beside _ _ _) g  q  = aboveNest (reduceDoc p) g 0 (reduceDoc q)
-above p g q                  = aboveNest p             g 0 (reduceDoc q)
-
-aboveNest :: RDoc -> Bool -> Int -> RDoc -> RDoc
--- Specfication: aboveNest p g k q = p $g$ (nest k q)
-
-aboveNest NoDoc               g k q = NoDoc
-aboveNest (p1 `Union` p2)     g k q = aboveNest p1 g k q `union_` 
-                                      aboveNest p2 g k q
-                                
-aboveNest Empty               g k q = mkNest k q
-aboveNest (Nest k1 p)         g k q = nest_ k1 (aboveNest p g (k - k1) q)
-                                  -- p can't be Empty, so no need for mkNest
-                                
-aboveNest (NilAbove p)        g k q = nilAbove_ (aboveNest p g k q)
-aboveNest (TextBeside s sl p) g k q = textBeside_ s sl rest
-                                    where
-                                      k1   = k - sl
-                                      rest = case p of
-                                                Empty -> nilAboveNest g k1 q
-                                                other -> aboveNest  p g k1 q
-\end{code}
-
-\begin{code}
-nilAboveNest :: Bool -> Int -> RDoc -> RDoc
--- Specification: text s <> nilaboveNest g k q 
---              = text s <> (text "" $g$ nest k q)
-
-nilAboveNest g k Empty       = Empty    -- Here's why the "text s <>" is in the spec!
-nilAboveNest g k (Nest k1 q) = nilAboveNest g (k + k1) q
-
-nilAboveNest g k q           | (not g) && (k > 0)        -- No newline if no overlap
-                             = textBeside_ (Str (spaces k)) k q
-                             | otherwise                        -- Put them really above
-                             = nilAbove_ (mkNest k q)
-\end{code}
-
-
-*********************************************************
-*                                                       *
-\subsection{Horizontal composition @<>@}
-*                                                       *
-*********************************************************
-
-\begin{code}
-p <>  q = Beside p False q
-p <+> q = Beside p True  q
-
-beside :: Doc -> Bool -> RDoc -> RDoc
--- Specification: beside g p q = p <g> q
- 
-beside NoDoc               g q   = NoDoc
-beside (p1 `Union` p2)     g q   = (beside p1 g q) `union_` (beside p2 g q)
-beside Empty               g q   = q
-beside (Nest k p)          g q   = nest_ k (beside p g q)       -- p non-empty
-beside p@(Beside p1 g1 q1) g2 q2 
-           {- (A `op1` B) `op2` C == A `op1` (B `op2` C)  iff op1 == op2 
-                                                 [ && (op1 == <> || op1 == <+>) ] -}
-         | g1 == g2              = beside p1 g1 (beside q1 g2 q2)
-         | otherwise             = beside (reduceDoc p) g2 q2
-beside p@(Above _ _ _)     g q   = beside (reduceDoc p) g q
-beside (NilAbove p)        g q   = nilAbove_ (beside p g q)
-beside (TextBeside s sl p) g q   = textBeside_ s sl rest
-                               where
-                                  rest = case p of
-                                           Empty -> nilBeside g q
-                                           other -> beside p g q
-\end{code}
-
-\begin{code}
-nilBeside :: Bool -> RDoc -> RDoc
--- Specification: text "" <> nilBeside g p 
---              = text "" <g> p
-
-nilBeside g Empty      = Empty  -- Hence the text "" in the spec
-nilBeside g (Nest _ p) = nilBeside g p
-nilBeside g p          | g         = textBeside_ space_text 1 p
-                       | otherwise = p
-\end{code}
-
-*********************************************************
-*                                                       *
-\subsection{Separate, @sep@, Hughes version}
-*                                                       *
-*********************************************************
-
-\begin{code}
--- Specification: sep ps  = oneLiner (hsep ps)
---                         `union`
---                          vcat ps
-
-sep = sepX True         -- Separate with spaces
-cat = sepX False        -- Don't
-
-sepX x []     = empty
-sepX x (p:ps) = sep1 x (reduceDoc p) 0 ps
-
-
--- Specification: sep1 g k ys = sep (x : map (nest k) ys)
---                            = oneLiner (x <g> nest k (hsep ys))
---                              `union` x $$ nest k (vcat ys)
-
-sep1 :: Bool -> RDoc -> Int -> [Doc] -> RDoc
-sep1 g NoDoc               k ys = NoDoc
-sep1 g (p `Union` q)       k ys = sep1 g p k ys
-                                  `union_`
-                                  (aboveNest q False k (reduceDoc (vcat ys)))
-
-sep1 g Empty               k ys = mkNest k (sepX g ys)
-sep1 g (Nest n p)          k ys = nest_ n (sep1 g p (k - n) ys)
-
-sep1 g (NilAbove p)        k ys = nilAbove_ (aboveNest p False k (reduceDoc (vcat ys)))
-sep1 g (TextBeside s sl p) k ys = textBeside_ s sl (sepNB g p (k - sl) ys)
-
--- Specification: sepNB p k ys = sep1 (text "" <> p) k ys
--- Called when we have already found some text in the first item
--- We have to eat up nests
-
-sepNB g (Nest _ p)  k ys  = sepNB g p k ys
-
-sepNB g Empty k ys        = oneLiner (nilBeside g (reduceDoc rest))
-                                `mkUnion` 
-                            nilAboveNest False k (reduceDoc (vcat ys))
-                          where
-                            rest | g         = hsep ys
-                                 | otherwise = hcat ys
-
-sepNB g p k ys            = sep1 g p k ys
-\end{code}
-
-*********************************************************
-*                                                       *
-\subsection{@fill@}
-*                                                       *
-*********************************************************
-
-\begin{code}
-fsep = fill True
-fcat = fill False
-
--- Specification: 
---   fill []  = empty
---   fill [p] = p
---   fill (p1:p2:ps) = oneLiner p1 <#> nest (length p1) 
---                                          (fill (oneLiner p2 : ps))
---                     `union`
---                      p1 $$ fill ps
-
-fill g []     = empty
-fill g (p:ps) = fill1 g (reduceDoc p) 0 ps
-
-
-fill1 :: Bool -> RDoc -> Int -> [Doc] -> Doc
-fill1 g NoDoc               k ys = NoDoc
-fill1 g (p `Union` q)       k ys = fill1 g p k ys
-                                   `union_`
-                                   (aboveNest q False k (fill g ys))
-
-fill1 g Empty               k ys = mkNest k (fill g ys)
-fill1 g (Nest n p)          k ys = nest_ n (fill1 g p (k - n) ys)
-
-fill1 g (NilAbove p)        k ys = nilAbove_ (aboveNest p False k (fill g ys))
-fill1 g (TextBeside s sl p) k ys = textBeside_ s sl (fillNB g p (k - sl) ys)
-
-fillNB g (Nest _ p)  k ys  = fillNB g p k ys
-fillNB g Empty k []        = Empty
-fillNB g Empty k (y:ys)    = nilBeside g (fill1 g (oneLiner (reduceDoc y)) k1 ys)
-                             `mkUnion` 
-                             nilAboveNest False k (fill g (y:ys))
-                           where
-                             k1 | g         = k - 1
-                                | otherwise = k
-
-fillNB g p k ys            = fill1 g p k ys
-\end{code}
-
-
-*********************************************************
-*                                                       *
-\subsection{Selecting the best layout}
-*                                                       *
-*********************************************************
-
-\begin{code}
-best :: Mode
-     -> Int             -- Line length
-     -> Int             -- Ribbon length
-     -> RDoc
-     -> RDoc            -- No unions in here!
-
-best OneLineMode w r p
-  = get p
-  where
-    get Empty               = Empty
-    get NoDoc               = NoDoc
-    get (NilAbove p)        = nilAbove_ (get p)
-    get (TextBeside s sl p) = textBeside_ s sl (get p)
-    get (Nest k p)          = get p             -- Elide nest
-    get (p `Union` q)       = first (get p) (get q)
-
-best mode w r p
-  = get w p
-  where
-    get :: Int          -- (Remaining) width of line
-        -> Doc -> Doc
-    get w Empty               = Empty
-    get w NoDoc               = NoDoc
-    get w (NilAbove p)        = nilAbove_ (get w p)
-    get w (TextBeside s sl p) = textBeside_ s sl (get1 w sl p)
-    get w (Nest k p)          = nest_ k (get (w - k) p)
-    get w (p `Union` q)       = nicest w r (get w p) (get w q)
-
-    get1 :: Int         -- (Remaining) width of line
-         -> Int         -- Amount of first line already eaten up
-         -> Doc         -- This is an argument to TextBeside => eat Nests
-         -> Doc         -- No unions in here!
-
-    get1 w sl Empty               = Empty
-    get1 w sl NoDoc               = NoDoc
-    get1 w sl (NilAbove p)        = nilAbove_ (get (w - sl) p)
-    get1 w sl (TextBeside t tl p) = textBeside_ t tl (get1 w (sl + tl) p)
-    get1 w sl (Nest k p)          = get1 w sl p
-    get1 w sl (p `Union` q)       = nicest1 w r sl (get1 w sl p) 
-                                                   (get1 w sl q)
-
-nicest w r p q = nicest1 w r 0 p q
-nicest1 w r sl p q | fits ((w `minn` r) - sl) p = p
-                   | otherwise                   = q
-
-fits :: Int     -- Space available
-     -> Doc
-     -> Bool    -- True if *first line* of Doc fits in space available
- 
-fits n p    | n < 0 = False
-fits n NoDoc               = False
-fits n Empty               = True
-fits n (NilAbove _)        = True
-fits n (TextBeside _ sl p) = fits (n - sl) p
-
-minn x y | x < y    = x
-         | otherwise = y
-\end{code}
-
-@first@ and @nonEmptySet@ are similar to @nicest@ and @fits@, only simpler.
-@first@ returns its first argument if it is non-empty, otherwise its second.
-
-\begin{code}
-first p q | nonEmptySet p = p 
-          | otherwise     = q
-
-nonEmptySet NoDoc           = False
-nonEmptySet (p `Union` q)      = True
-nonEmptySet Empty              = True
-nonEmptySet (NilAbove p)       = True           -- NoDoc always in first line
-nonEmptySet (TextBeside _ _ p) = nonEmptySet p
-nonEmptySet (Nest _ p)         = nonEmptySet p
-\end{code}
-
-@oneLiner@ returns the one-line members of the given set of @Doc@s.
-
-\begin{code}
-oneLiner :: Doc -> Doc
-oneLiner NoDoc               = NoDoc
-oneLiner Empty               = Empty
-oneLiner (NilAbove p)        = NoDoc
-oneLiner (TextBeside s sl p) = textBeside_ s sl (oneLiner p)
-oneLiner (Nest k p)          = nest_ k (oneLiner p)
-oneLiner (p `Union` q)       = oneLiner p
-\end{code}
-
-
-
-*********************************************************
-*                                                       *
-\subsection{Displaying the best layout}
-*                                                       *
-*********************************************************
-
-
-\begin{code}
-renderStyle Style{mode=mode, lineLength=lineLength, ribbonsPerLine=ribbonsPerLine} doc 
-  = fullRender mode lineLength ribbonsPerLine string_txt "" doc
-
-render doc       = showDoc doc ""
-showDoc doc rest = fullRender PageMode 100 1.5 string_txt rest doc
-
-string_txt (Chr c)   s  = c:s
-string_txt (Str s1)  s2 = s1 ++ s2
-string_txt (PStr s1) s2 = s1 ++ s2
-\end{code}
-
-\begin{code}
-
-fullRender OneLineMode _ _ txt end doc = easy_display space_text txt end (reduceDoc doc)
-fullRender LeftMode    _ _ txt end doc = easy_display nl_text    txt end (reduceDoc doc)
-
-fullRender mode line_length ribbons_per_line txt end doc
-  = display mode line_length ribbon_length txt end best_doc
-  where 
-    best_doc = best mode hacked_line_length ribbon_length (reduceDoc doc)
-
-    hacked_line_length, ribbon_length :: Int
-    ribbon_length = round (fromIntegral line_length / ribbons_per_line)
-    hacked_line_length = case mode of { ZigZagMode -> maxBound; other -> line_length }
-
-display mode page_width ribbon_width txt end doc
-  = case page_width - ribbon_width of { gap_width ->
-    case gap_width `quot` 2 of { shift ->
-    let
-        lay k (Nest k1 p)  = lay (k + k1) p
-        lay k Empty        = end
-    
-        lay k (NilAbove p) = nl_text `txt` lay k p
-    
-        lay k (TextBeside s sl p)
-            = case mode of
-                    ZigZagMode |  k >= gap_width
-                               -> nl_text `txt` (
-                                  Str (multi_ch shift '/') `txt` (
-                                  nl_text `txt` (
-                                  lay1 (k - shift) s sl p)))
-
-                               |  k < 0
-                               -> nl_text `txt` (
-                                  Str (multi_ch shift '\\') `txt` (
-                                  nl_text `txt` (
-                                  lay1 (k + shift) s sl p )))
-
-                    other -> lay1 k s sl p
-    
-        lay1 k s sl p = Str (indent k) `txt` (s `txt` lay2 (k + sl) p)
-    
-        lay2 k (NilAbove p)        = nl_text `txt` lay k p
-        lay2 k (TextBeside s sl p) = s `txt` (lay2 (k + sl) p)
-        lay2 k (Nest _ p)          = lay2 k p
-        lay2 k Empty               = end
-    in
-    lay 0 doc
-    }}
-
-cant_fail = error "easy_display: NoDoc"
-easy_display nl_text txt end doc 
-  = lay doc cant_fail
-  where
-    lay NoDoc               no_doc = no_doc
-    lay (Union p q)         no_doc = {- lay p -} (lay q cant_fail)              -- Second arg can't be NoDoc
-    lay (Nest k p)          no_doc = lay p no_doc
-    lay Empty               no_doc = end
-    lay (NilAbove p)        no_doc = nl_text `txt` lay p cant_fail      -- NoDoc always on first line
-    lay (TextBeside s sl p) no_doc = s `txt` lay p no_doc
-
-indent n | n >= 8 = '\t' : indent (n - 8)
-         | otherwise      = spaces n
-
-multi_ch 0 ch = ""
-multi_ch n       ch = ch : multi_ch (n - 1) ch
-
-spaces 0 = ""
-spaces n       = ' ' : spaces (n - 1)
-\end{code}
-
diff --git a/src/PrettyCombinators.lhs b/src/PrettyCombinators.lhs
new file mode 100644
--- /dev/null
+++ b/src/PrettyCombinators.lhs
@@ -0,0 +1,905 @@
+Hand converted to standard Haskell     -- jcp
+
+*********************************************************************************
+*                                                                               *
+*       John Hughes's and Simon Peyton Jones's Pretty Printer Combinators       *
+*                                                                               *
+*               based on "The Design of a Pretty-printing Library"              *
+*               in Advanced Functional Programming,                             *
+*               Johan Jeuring and Erik Meijer (eds), LNCS 925                   *
+*               http://www.cs.chalmers.se/~rjmh/Papers/pretty.ps                *
+*                                                                               *
+*               Heavily modified by Simon Peyton Jones, Dec 96                  *
+*                                                                               *
+*********************************************************************************
+
+Version 3.0     28 May 1997
+  * Cured massive performance bug.  If you write
+
+        foldl <> empty (map (text.show) [1..10000])
+
+    you get quadratic behaviour with V2.0.  Why?  For just the same reason as you get
+    quadratic behaviour with left-associated (++) chains.
+
+    This is really bad news.  One thing a pretty-printer abstraction should
+    certainly guarantee is insensivity to associativity.  It matters: suddenly
+    GHC's compilation times went up by a factor of 100 when I switched to the
+    new pretty printer.
+ 
+    I fixed it with a bit of a hack (because I wanted to get GHC back on the
+    road).  I added two new constructors to the Doc type, Above and Beside:
+ 
+         <> = Beside
+         $$ = Above
+ 
+    Then, where I need to get to a "TextBeside" or "NilAbove" form I "force"
+    the Doc to squeeze out these suspended calls to Beside and Above; but in so
+    doing I re-associate. It's quite simple, but I'm not satisfied that I've done
+    the best possible job.  I'll send you the code if you are interested.
+
+  * Added new exports:
+        punctuate, hang
+        int, integer, float, double, rational,
+        lparen, rparen, lbrack, rbrack, lbrace, rbrace,
+
+  * fullRender's type signature has changed.  Rather than producing a string it
+    now takes an extra couple of arguments that tells it how to glue fragments
+    of output together:
+
+        fullRender :: Mode
+                   -> Int                       -- Line length
+                   -> Float                     -- Ribbons per line
+                   -> (TextDetails -> a -> a)   -- What to do with text
+                   -> a                         -- What to do at the end
+                   -> Doc
+                   -> a                         -- Result
+
+    The "fragments" are encapsulated in the TextDetails data type:
+        data TextDetails = Chr  Char
+                         | Str  String
+                         | PStr FAST_STRING
+
+    The Chr and Str constructors are obvious enough.  The PStr constructor has a packed
+    string (FAST_STRING) inside it.  It's generated by using the new "ptext" export.
+
+    An advantage of this new setup is that you can get the renderer to do output
+    directly (by passing in a function of type (TextDetails -> IO () -> IO ()),
+    rather than producing a string that you then print.
+
+
+Version 2.0     24 April 1997
+  * Made empty into a left unit for <> as well as a right unit;
+    it is also now true that
+        nest k empty = empty
+    which wasn't true before.
+
+  * Fixed an obscure bug in sep that occassionally gave very wierd behaviour
+
+  * Added $+$
+
+  * Corrected and tidied up the laws and invariants
+
+======================================================================
+Relative to John's original paper, there are the following new features:
+
+1.  There's an empty document, "empty".  It's a left and right unit for 
+    both <> and $$, and anywhere in the argument list for
+    sep, hcat, hsep, vcat, fcat etc.
+
+    It is Really Useful in practice.
+
+2.  There is a paragraph-fill combinator, fsep, that's much like sep,
+    only it keeps fitting things on one line until itc can't fit any more.
+
+3.  Some random useful extra combinators are provided.  
+        <+> puts its arguments beside each other with a space between them,
+            unless either argument is empty in which case it returns the other
+
+
+        hcat is a list version of <>
+        hsep is a list version of <+>
+        vcat is a list version of $$
+
+        sep (separate) is either like hsep or like vcat, depending on what fits
+
+        cat  is behaves like sep,  but it uses <> for horizontal conposition
+        fcat is behaves like fsep, but it uses <> for horizontal conposition
+
+        These new ones do the obvious things:
+                char, semi, comma, colon, space,
+                parens, brackets, braces, 
+                quotes, doubleQuotes
+        
+4.      The "above" combinator, $$, now overlaps its two arguments if the
+        last line of the top argument stops before the first line of the second begins.
+        For example:  text "hi" $$ nest 5 "there"
+        lays out as
+                        hi   there
+        rather than
+                        hi
+                             there
+
+        There are two places this is really useful
+
+        a) When making labelled blocks, like this:
+                Left ->   code for left
+                Right ->  code for right
+                LongLongLongLabel ->
+                          code for longlonglonglabel
+           The block is on the same line as the label if the label is
+           short, but on the next line otherwise.
+
+        b) When laying out lists like this:
+                [ first
+                , second
+                , third
+                ]
+           which some people like.  But if the list fits on one line
+           you want [first, second, third].  You can't do this with
+           John's original combinators, but it's quite easy with the
+           new $$.
+
+        The combinator $+$ gives the original "never-overlap" behaviour.
+
+5.      Several different renderers are provided:
+                * a standard one
+                * one that uses cut-marks to avoid deeply-nested documents 
+                        simply piling up in the right-hand margin
+                * one that ignores indentation (fewer chars output; good for machines)
+                * one that ignores indentation and newlines (ditto, only more so)
+
+6.      Numerous implementation tidy-ups
+        Use of unboxed data types to speed up the implementation
+
+
+
+\begin{code}
+module PrettyCombinators (
+        Doc,            -- Abstract
+        Mode(..), TextDetails(..),
+	Style,
+
+        empty, nest,
+
+        text, char, ptext,
+        int, integer, float, double, rational,
+        parens, brackets, braces, quotes, doubleQuotes,
+        semi, comma, colon, space, equals,
+        lparen, rparen, lbrack, rbrack, lbrace, rbrace,
+
+        (<>), (<+>), hcat, hsep, 
+        ($$), ($+$), vcat, 
+        sep, cat, 
+        fsep, fcat, 
+
+        hang, punctuate,
+        
+        renderStyle, 
+        render, fullRender
+  ) where
+
+-- Don't import Util( assertPanic ) because it makes a loop in the module structure
+
+import Data.Ratio
+infixl 6 <> 
+infixl 6 <+>
+infixl 5 $$, $+$
+\end{code}
+
+
+
+*********************************************************
+*                                                       *
+\subsection{CPP magic so that we can compile with both GHC and Hugs}
+*                                                       *
+*********************************************************
+
+The library uses unboxed types to get a bit more speed, but these CPP macros
+allow you to use either GHC or Hugs.  To get GHC, just set the CPP variable
+        __GLASGOW_HASKELL__
+
+
+*********************************************************
+*                                                       *
+\subsection{The interface}
+*                                                       *
+*********************************************************
+
+The primitive @Doc@ values
+
+\begin{code}
+empty                     :: Doc
+text                      :: String -> Doc 
+char                      :: Char -> Doc
+
+semi, comma, colon, space, equals              :: Doc
+lparen, rparen, lbrack, rbrack, lbrace, rbrace :: Doc
+
+parens, brackets, braces  :: Doc -> Doc 
+quotes, doubleQuotes      :: Doc -> Doc
+
+int      :: Int -> Doc
+integer  :: Integer -> Doc
+float    :: Float -> Doc
+double   :: Double -> Doc
+rational :: Rational -> Doc
+\end{code}
+
+
+Combining @Doc@ values
+
+\begin{code}
+(<>)   :: Doc -> Doc -> Doc     -- Beside
+hcat   :: [Doc] -> Doc          -- List version of <>
+(<+>)  :: Doc -> Doc -> Doc     -- Beside, separated by space
+hsep   :: [Doc] -> Doc          -- List version of <+>
+
+($$)   :: Doc -> Doc -> Doc     -- Above; if there is no
+                                -- overlap it "dovetails" the two
+vcat   :: [Doc] -> Doc          -- List version of $$
+
+cat    :: [Doc] -> Doc          -- Either hcat or vcat
+sep    :: [Doc] -> Doc          -- Either hsep or vcat
+fcat   :: [Doc] -> Doc          -- ``Paragraph fill'' version of cat
+fsep   :: [Doc] -> Doc          -- ``Paragraph fill'' version of sep
+
+nest   :: Int -> Doc -> Doc     -- Nested
+\end{code}
+
+GHC-specific ones.
+
+\begin{code}
+hang :: Doc -> Int -> Doc -> Doc
+punctuate :: Doc -> [Doc] -> [Doc]      -- punctuate p [d1, ... dn] = [d1 <> p, d2 <> p, ... dn-1 <> p, dn]
+\end{code}
+
+Displaying @Doc@ values. 
+
+\begin{code}
+instance Show Doc where
+  showsPrec prec doc cont = showDoc doc cont
+
+render     :: Doc -> String             -- Uses default style
+fullRender :: Mode
+           -> Int                       -- Line length
+           -> Float                     -- Ribbons per line
+           -> (TextDetails -> a -> a)   -- What to do with text
+           -> a                         -- What to do at the end
+           -> Doc
+           -> a                         -- Result
+
+renderStyle  :: Style -> Doc -> String
+data Style = Style { lineLength     :: Int,     -- In chars
+                     ribbonsPerLine :: Float,   -- Ratio of ribbon length to line length
+                     mode :: Mode
+             }
+style :: Style          -- The default style
+style = Style { lineLength = 100, ribbonsPerLine = 2.5, mode = PageMode }
+
+data Mode = PageMode            -- Normal 
+          | ZigZagMode          -- With zig-zag cuts
+          | LeftMode            -- No indentation, infinitely long lines
+          | OneLineMode         -- All on one line
+
+\end{code}
+
+
+*********************************************************
+*                                                       *
+\subsection{The @Doc@ calculus}
+*                                                       *
+*********************************************************
+
+The @Doc@ combinators satisfy the following laws:
+\begin{verbatim}
+Laws for $$
+~~~~~~~~~~~
+<a1>    (x $$ y) $$ z   = x $$ (y $$ z)
+<a2>    empty $$ x      = x
+<a3>    x $$ empty      = x
+
+        ...ditto $+$...
+
+Laws for <>
+~~~~~~~~~~~
+<b1>    (x <> y) <> z   = x <> (y <> z)
+<b2>    empty <> x      = empty
+<b3>    x <> empty      = x
+
+        ...ditto <+>...
+
+Laws for text
+~~~~~~~~~~~~~
+<t1>    text s <> text t        = text (s++t)
+<t2>    text "" <> x            = x, if x non-empty
+
+Laws for nest
+~~~~~~~~~~~~~
+<n1>    nest 0 x                = x
+<n2>    nest k (nest k' x)      = nest (k+k') x
+<n3>    nest k (x <> y)         = nest k z <> nest k y
+<n4>    nest k (x $$ y)         = nest k x $$ nest k y
+<n5>    nest k empty            = empty
+<n6>    x <> nest k y           = x <> y, if x non-empty
+
+** Note the side condition on <n6>!  It is this that
+** makes it OK for empty to be a left unit for <>.
+
+Miscellaneous
+~~~~~~~~~~~~~
+<m1>    (text s <> x) $$ y = text s <> ((text "" <> x)) $$ 
+                                         nest (-length s) y)
+
+<m2>    (x $$ y) <> z = x $$ (y <> z)
+        if y non-empty
+
+
+Laws for list versions
+~~~~~~~~~~~~~~~~~~~~~~
+<l1>    sep (ps++[empty]++qs)   = sep (ps ++ qs)
+        ...ditto hsep, hcat, vcat, fill...
+
+<l2>    nest k (sep ps) = sep (map (nest k) ps)
+        ...ditto hsep, hcat, vcat, fill...
+
+Laws for oneLiner
+~~~~~~~~~~~~~~~~~
+<o1>    oneLiner (nest k p) = nest k (oneLiner p)
+<o2>    oneLiner (x <> y)   = oneLiner x <> oneLiner y 
+\end{verbatim}
+
+
+You might think that the following verion of <m1> would
+be neater:
+\begin{verbatim}
+<3 NO>  (text s <> x) $$ y = text s <> ((empty <> x)) $$ 
+                                         nest (-length s) y)
+\end{verbatim}
+But it doesn't work, for if x=empty, we would have
+\begin{verbatim}
+        text s $$ y = text s <> (empty $$ nest (-length s) y)
+                    = text s <> nest (-length s) y
+\end{verbatim}
+
+
+
+*********************************************************
+*                                                       *
+\subsection{Simple derived definitions}
+*                                                       *
+*********************************************************
+
+\begin{code}
+semi  = char ';'
+colon = char ':'
+comma = char ','
+space = char ' '
+equals = char '='
+lparen = char '('
+rparen = char ')'
+lbrack = char '['
+rbrack = char ']'
+lbrace = char '{'
+rbrace = char '}'
+
+int      n = text (show n)
+integer  n = text (show n)
+float    n = text (show n)
+double   n = text (show n)
+rational n = text (show n)
+-- SIGBJORN wrote instead:
+-- rational n = text (show (fromRationalX n))
+
+quotes p        = char '`' <> p <> char '\''
+doubleQuotes p  = char '"' <> p <> char '"'
+parens p        = char '(' <> p <> char ')'
+brackets p      = char '[' <> p <> char ']'
+braces p        = char '{' <> p <> char '}'
+
+
+hcat = foldr (<>)  empty
+hsep = foldr (<+>) empty
+vcat = foldr ($$)  empty
+
+hang d1 n d2 = d1 $$ (nest n d2)
+
+punctuate p []     = []
+punctuate p (d:ds) = go d ds
+                   where
+                     go d [] = [d]
+                     go d (e:es) = (d <> p) : go e es
+\end{code}
+
+
+*********************************************************
+*                                                       *
+\subsection{The @Doc@ data type}
+*                                                       *
+*********************************************************
+
+A @Doc@ represents a {\em set} of layouts.  A @Doc@ with
+no occurrences of @Union@ or @NoDoc@ represents just one layout.
+\begin{code}
+data Doc
+ = Empty                                -- empty
+ | NilAbove Doc                         -- text "" $$ x
+ | TextBeside TextDetails Int Doc       -- text s <> x  
+ | Nest Int Doc                         -- nest k x
+ | Union Doc Doc                        -- ul `union` ur
+ | NoDoc                                -- The empty set of documents
+ | Beside Doc Bool Doc                  -- True <=> space between
+ | Above  Doc Bool Doc                  -- True <=> never overlap
+
+type RDoc = Doc         -- RDoc is a "reduced Doc", guaranteed not to have a top-level Above or Beside
+
+
+reduceDoc :: Doc -> RDoc
+reduceDoc (Beside p g q) = beside p g (reduceDoc q)
+reduceDoc (Above  p g q) = above  p g (reduceDoc q)
+reduceDoc p              = p
+
+
+data TextDetails = Chr  Char
+                 | Str  String
+                 | PStr String
+space_text = Chr ' '
+nl_text    = Chr '\n'
+\end{code}
+
+Here are the invariants:
+\begin{itemize}
+\item
+The argument of @NilAbove@ is never @Empty@. Therefore
+a @NilAbove@ occupies at least two lines.
+
+\item
+The arugment of @TextBeside@ is never @Nest@.
+
+\item 
+The layouts of the two arguments of @Union@ both flatten to the same string.
+
+\item 
+The arguments of @Union@ are either @TextBeside@, or @NilAbove@.
+
+\item
+The right argument of a union cannot be equivalent to the empty set (@NoDoc@).
+If the left argument of a union is equivalent to the empty set (@NoDoc@),
+then the @NoDoc@ appears in the first line.
+
+\item 
+An empty document is always represented by @Empty@.
+It can't be hidden inside a @Nest@, or a @Union@ of two @Empty@s.
+
+\item 
+The first line of every layout in the left argument of @Union@
+is longer than the first line of any layout in the right argument.
+(1) ensures that the left argument has a first line.  In view of (3),
+this invariant means that the right argument must have at least two
+lines.
+\end{itemize}
+
+\begin{code}
+        -- Arg of a NilAbove is always an RDoc
+nilAbove_ p = NilAbove p
+
+        -- Arg of a TextBeside is always an RDoc
+textBeside_ s sl p = TextBeside s sl p
+
+        -- Arg of Nest is always an RDoc
+nest_ k p = Nest k p
+
+        -- Args of union are always RDocs
+union_ p q = Union p q
+
+\end{code}
+
+
+Notice the difference between
+        * NoDoc (no documents)
+        * Empty (one empty document; no height and no width)
+        * text "" (a document containing the empty string;
+                   one line high, but has no width)
+
+
+
+*********************************************************
+*                                                       *
+\subsection{@empty@, @text@, @nest@, @union@}
+*                                                       *
+*********************************************************
+
+\begin{code}
+empty = Empty
+
+char  c = textBeside_ (Chr c) 1 Empty
+text  s = case length   s of {sl -> textBeside_ (Str s)  sl Empty}
+ptext s = case length s of {sl -> textBeside_ (PStr s) sl Empty}
+
+nest k  p = mkNest k (reduceDoc p)        -- Externally callable version
+
+-- mkNest checks for Nest's invariant that it doesn't have an Empty inside it
+mkNest k       (Nest k1 p) = mkNest (k + k1) p
+mkNest k       NoDoc       = NoDoc
+mkNest k       Empty       = Empty
+mkNest 0       p           = p                  -- Worth a try!
+mkNest k       p           = nest_ k p
+
+-- mkUnion checks for an empty document
+mkUnion Empty q = Empty
+mkUnion p q     = p `union_` q
+\end{code}
+
+*********************************************************
+*                                                       *
+\subsection{Vertical composition @$$@}
+*                                                       *
+*********************************************************
+
+
+\begin{code}
+p $$  q = Above p False q
+p $+$ q = Above p True q
+
+above :: Doc -> Bool -> RDoc -> RDoc
+above (Above p g1 q1)  g2 q2 = above p g1 (above q1 g2 q2)
+above p@(Beside _ _ _) g  q  = aboveNest (reduceDoc p) g 0 (reduceDoc q)
+above p g q                  = aboveNest p             g 0 (reduceDoc q)
+
+aboveNest :: RDoc -> Bool -> Int -> RDoc -> RDoc
+-- Specfication: aboveNest p g k q = p $g$ (nest k q)
+
+aboveNest NoDoc               g k q = NoDoc
+aboveNest (p1 `Union` p2)     g k q = aboveNest p1 g k q `union_` 
+                                      aboveNest p2 g k q
+                                
+aboveNest Empty               g k q = mkNest k q
+aboveNest (Nest k1 p)         g k q = nest_ k1 (aboveNest p g (k - k1) q)
+                                  -- p can't be Empty, so no need for mkNest
+                                
+aboveNest (NilAbove p)        g k q = nilAbove_ (aboveNest p g k q)
+aboveNest (TextBeside s sl p) g k q = textBeside_ s sl rest
+                                    where
+                                      k1   = k - sl
+                                      rest = case p of
+                                                Empty -> nilAboveNest g k1 q
+                                                other -> aboveNest  p g k1 q
+\end{code}
+
+\begin{code}
+nilAboveNest :: Bool -> Int -> RDoc -> RDoc
+-- Specification: text s <> nilaboveNest g k q 
+--              = text s <> (text "" $g$ nest k q)
+
+nilAboveNest g k Empty       = Empty    -- Here's why the "text s <>" is in the spec!
+nilAboveNest g k (Nest k1 q) = nilAboveNest g (k + k1) q
+
+nilAboveNest g k q           | (not g) && (k > 0)        -- No newline if no overlap
+                             = textBeside_ (Str (spaces k)) k q
+                             | otherwise                        -- Put them really above
+                             = nilAbove_ (mkNest k q)
+\end{code}
+
+
+*********************************************************
+*                                                       *
+\subsection{Horizontal composition @<>@}
+*                                                       *
+*********************************************************
+
+\begin{code}
+p <>  q = Beside p False q
+p <+> q = Beside p True  q
+
+beside :: Doc -> Bool -> RDoc -> RDoc
+-- Specification: beside g p q = p <g> q
+ 
+beside NoDoc               g q   = NoDoc
+beside (p1 `Union` p2)     g q   = (beside p1 g q) `union_` (beside p2 g q)
+beside Empty               g q   = q
+beside (Nest k p)          g q   = nest_ k (beside p g q)       -- p non-empty
+beside p@(Beside p1 g1 q1) g2 q2 
+           {- (A `op1` B) `op2` C == A `op1` (B `op2` C)  iff op1 == op2 
+                                                 [ && (op1 == <> || op1 == <+>) ] -}
+         | g1 == g2              = beside p1 g1 (beside q1 g2 q2)
+         | otherwise             = beside (reduceDoc p) g2 q2
+beside p@(Above _ _ _)     g q   = beside (reduceDoc p) g q
+beside (NilAbove p)        g q   = nilAbove_ (beside p g q)
+beside (TextBeside s sl p) g q   = textBeside_ s sl rest
+                               where
+                                  rest = case p of
+                                           Empty -> nilBeside g q
+                                           other -> beside p g q
+\end{code}
+
+\begin{code}
+nilBeside :: Bool -> RDoc -> RDoc
+-- Specification: text "" <> nilBeside g p 
+--              = text "" <g> p
+
+nilBeside g Empty      = Empty  -- Hence the text "" in the spec
+nilBeside g (Nest _ p) = nilBeside g p
+nilBeside g p          | g         = textBeside_ space_text 1 p
+                       | otherwise = p
+\end{code}
+
+*********************************************************
+*                                                       *
+\subsection{Separate, @sep@, Hughes version}
+*                                                       *
+*********************************************************
+
+\begin{code}
+-- Specification: sep ps  = oneLiner (hsep ps)
+--                         `union`
+--                          vcat ps
+
+sep = sepX True         -- Separate with spaces
+cat = sepX False        -- Don't
+
+sepX x []     = empty
+sepX x (p:ps) = sep1 x (reduceDoc p) 0 ps
+
+
+-- Specification: sep1 g k ys = sep (x : map (nest k) ys)
+--                            = oneLiner (x <g> nest k (hsep ys))
+--                              `union` x $$ nest k (vcat ys)
+
+sep1 :: Bool -> RDoc -> Int -> [Doc] -> RDoc
+sep1 g NoDoc               k ys = NoDoc
+sep1 g (p `Union` q)       k ys = sep1 g p k ys
+                                  `union_`
+                                  (aboveNest q False k (reduceDoc (vcat ys)))
+
+sep1 g Empty               k ys = mkNest k (sepX g ys)
+sep1 g (Nest n p)          k ys = nest_ n (sep1 g p (k - n) ys)
+
+sep1 g (NilAbove p)        k ys = nilAbove_ (aboveNest p False k (reduceDoc (vcat ys)))
+sep1 g (TextBeside s sl p) k ys = textBeside_ s sl (sepNB g p (k - sl) ys)
+
+-- Specification: sepNB p k ys = sep1 (text "" <> p) k ys
+-- Called when we have already found some text in the first item
+-- We have to eat up nests
+
+sepNB g (Nest _ p)  k ys  = sepNB g p k ys
+
+sepNB g Empty k ys        = oneLiner (nilBeside g (reduceDoc rest))
+                                `mkUnion` 
+                            nilAboveNest False k (reduceDoc (vcat ys))
+                          where
+                            rest | g         = hsep ys
+                                 | otherwise = hcat ys
+
+sepNB g p k ys            = sep1 g p k ys
+\end{code}
+
+*********************************************************
+*                                                       *
+\subsection{@fill@}
+*                                                       *
+*********************************************************
+
+\begin{code}
+fsep = fill True
+fcat = fill False
+
+-- Specification: 
+--   fill []  = empty
+--   fill [p] = p
+--   fill (p1:p2:ps) = oneLiner p1 <#> nest (length p1) 
+--                                          (fill (oneLiner p2 : ps))
+--                     `union`
+--                      p1 $$ fill ps
+
+fill g []     = empty
+fill g (p:ps) = fill1 g (reduceDoc p) 0 ps
+
+
+fill1 :: Bool -> RDoc -> Int -> [Doc] -> Doc
+fill1 g NoDoc               k ys = NoDoc
+fill1 g (p `Union` q)       k ys = fill1 g p k ys
+                                   `union_`
+                                   (aboveNest q False k (fill g ys))
+
+fill1 g Empty               k ys = mkNest k (fill g ys)
+fill1 g (Nest n p)          k ys = nest_ n (fill1 g p (k - n) ys)
+
+fill1 g (NilAbove p)        k ys = nilAbove_ (aboveNest p False k (fill g ys))
+fill1 g (TextBeside s sl p) k ys = textBeside_ s sl (fillNB g p (k - sl) ys)
+
+fillNB g (Nest _ p)  k ys  = fillNB g p k ys
+fillNB g Empty k []        = Empty
+fillNB g Empty k (y:ys)    = nilBeside g (fill1 g (oneLiner (reduceDoc y)) k1 ys)
+                             `mkUnion` 
+                             nilAboveNest False k (fill g (y:ys))
+                           where
+                             k1 | g         = k - 1
+                                | otherwise = k
+
+fillNB g p k ys            = fill1 g p k ys
+\end{code}
+
+
+*********************************************************
+*                                                       *
+\subsection{Selecting the best layout}
+*                                                       *
+*********************************************************
+
+\begin{code}
+best :: Mode
+     -> Int             -- Line length
+     -> Int             -- Ribbon length
+     -> RDoc
+     -> RDoc            -- No unions in here!
+
+best OneLineMode w r p
+  = get p
+  where
+    get Empty               = Empty
+    get NoDoc               = NoDoc
+    get (NilAbove p)        = nilAbove_ (get p)
+    get (TextBeside s sl p) = textBeside_ s sl (get p)
+    get (Nest k p)          = get p             -- Elide nest
+    get (p `Union` q)       = first (get p) (get q)
+
+best mode w r p
+  = get w p
+  where
+    get :: Int          -- (Remaining) width of line
+        -> Doc -> Doc
+    get w Empty               = Empty
+    get w NoDoc               = NoDoc
+    get w (NilAbove p)        = nilAbove_ (get w p)
+    get w (TextBeside s sl p) = textBeside_ s sl (get1 w sl p)
+    get w (Nest k p)          = nest_ k (get (w - k) p)
+    get w (p `Union` q)       = nicest w r (get w p) (get w q)
+
+    get1 :: Int         -- (Remaining) width of line
+         -> Int         -- Amount of first line already eaten up
+         -> Doc         -- This is an argument to TextBeside => eat Nests
+         -> Doc         -- No unions in here!
+
+    get1 w sl Empty               = Empty
+    get1 w sl NoDoc               = NoDoc
+    get1 w sl (NilAbove p)        = nilAbove_ (get (w - sl) p)
+    get1 w sl (TextBeside t tl p) = textBeside_ t tl (get1 w (sl + tl) p)
+    get1 w sl (Nest k p)          = get1 w sl p
+    get1 w sl (p `Union` q)       = nicest1 w r sl (get1 w sl p) 
+                                                   (get1 w sl q)
+
+nicest w r p q = nicest1 w r 0 p q
+nicest1 w r sl p q | fits ((w `minn` r) - sl) p = p
+                   | otherwise                   = q
+
+fits :: Int     -- Space available
+     -> Doc
+     -> Bool    -- True if *first line* of Doc fits in space available
+ 
+fits n p    | n < 0 = False
+fits n NoDoc               = False
+fits n Empty               = True
+fits n (NilAbove _)        = True
+fits n (TextBeside _ sl p) = fits (n - sl) p
+
+minn x y | x < y    = x
+         | otherwise = y
+\end{code}
+
+@first@ and @nonEmptySet@ are similar to @nicest@ and @fits@, only simpler.
+@first@ returns its first argument if it is non-empty, otherwise its second.
+
+\begin{code}
+first p q | nonEmptySet p = p 
+          | otherwise     = q
+
+nonEmptySet NoDoc           = False
+nonEmptySet (p `Union` q)      = True
+nonEmptySet Empty              = True
+nonEmptySet (NilAbove p)       = True           -- NoDoc always in first line
+nonEmptySet (TextBeside _ _ p) = nonEmptySet p
+nonEmptySet (Nest _ p)         = nonEmptySet p
+\end{code}
+
+@oneLiner@ returns the one-line members of the given set of @Doc@s.
+
+\begin{code}
+oneLiner :: Doc -> Doc
+oneLiner NoDoc               = NoDoc
+oneLiner Empty               = Empty
+oneLiner (NilAbove p)        = NoDoc
+oneLiner (TextBeside s sl p) = textBeside_ s sl (oneLiner p)
+oneLiner (Nest k p)          = nest_ k (oneLiner p)
+oneLiner (p `Union` q)       = oneLiner p
+\end{code}
+
+
+
+*********************************************************
+*                                                       *
+\subsection{Displaying the best layout}
+*                                                       *
+*********************************************************
+
+
+\begin{code}
+renderStyle Style{mode=mode, lineLength=lineLength, ribbonsPerLine=ribbonsPerLine} doc 
+  = fullRender mode lineLength ribbonsPerLine string_txt "" doc
+
+render doc       = showDoc doc ""
+showDoc doc rest = fullRender PageMode 100 1.5 string_txt rest doc
+
+string_txt (Chr c)   s  = c:s
+string_txt (Str s1)  s2 = s1 ++ s2
+string_txt (PStr s1) s2 = s1 ++ s2
+\end{code}
+
+\begin{code}
+
+fullRender OneLineMode _ _ txt end doc = easy_display space_text txt end (reduceDoc doc)
+fullRender LeftMode    _ _ txt end doc = easy_display nl_text    txt end (reduceDoc doc)
+
+fullRender mode line_length ribbons_per_line txt end doc
+  = display mode line_length ribbon_length txt end best_doc
+  where 
+    best_doc = best mode hacked_line_length ribbon_length (reduceDoc doc)
+
+    hacked_line_length, ribbon_length :: Int
+    ribbon_length = round (fromIntegral line_length / ribbons_per_line)
+    hacked_line_length = case mode of { ZigZagMode -> maxBound; other -> line_length }
+
+display mode page_width ribbon_width txt end doc
+  = case page_width - ribbon_width of { gap_width ->
+    case gap_width `quot` 2 of { shift ->
+    let
+        lay k (Nest k1 p)  = lay (k + k1) p
+        lay k Empty        = end
+    
+        lay k (NilAbove p) = nl_text `txt` lay k p
+    
+        lay k (TextBeside s sl p)
+            = case mode of
+                    ZigZagMode |  k >= gap_width
+                               -> nl_text `txt` (
+                                  Str (multi_ch shift '/') `txt` (
+                                  nl_text `txt` (
+                                  lay1 (k - shift) s sl p)))
+
+                               |  k < 0
+                               -> nl_text `txt` (
+                                  Str (multi_ch shift '\\') `txt` (
+                                  nl_text `txt` (
+                                  lay1 (k + shift) s sl p )))
+
+                    other -> lay1 k s sl p
+    
+        lay1 k s sl p = Str (indent k) `txt` (s `txt` lay2 (k + sl) p)
+    
+        lay2 k (NilAbove p)        = nl_text `txt` lay k p
+        lay2 k (TextBeside s sl p) = s `txt` (lay2 (k + sl) p)
+        lay2 k (Nest _ p)          = lay2 k p
+        lay2 k Empty               = end
+    in
+    lay 0 doc
+    }}
+
+cant_fail = error "easy_display: NoDoc"
+easy_display nl_text txt end doc 
+  = lay doc cant_fail
+  where
+    lay NoDoc               no_doc = no_doc
+    lay (Union p q)         no_doc = {- lay p -} (lay q cant_fail)              -- Second arg can't be NoDoc
+    lay (Nest k p)          no_doc = lay p no_doc
+    lay Empty               no_doc = end
+    lay (NilAbove p)        no_doc = nl_text `txt` lay p cant_fail      -- NoDoc always on first line
+    lay (TextBeside s sl p) no_doc = s `txt` lay p no_doc
+
+indent n | n >= 8 = '\t' : indent (n - 8)
+         | otherwise      = spaces n
+
+multi_ch 0 ch = ""
+multi_ch n       ch = ch : multi_ch (n - 1) ch
+
+spaces 0 = ""
+spaces n       = ' ' : spaces (n - 1)
+\end{code}
+
diff --git a/src/Qual.lhs b/src/Qual.lhs
--- a/src/Qual.lhs
+++ b/src/Qual.lhs
@@ -19,17 +19,16 @@
 \em{Note:} The modified version also qualifies type constructors
 \begin{verbatim}
 
-> module Qual(qual,qualGoal) where
+> module Qual(qual) where
+
+> import Curry.Base.Ident
+> import Curry.Syntax
+
 > import Base
 > import TopEnv
 
 > qual :: ModuleIdent -> ValueEnv -> [Decl] -> [Decl]
 > qual m tyEnv ds = map (qualDecl m tyEnv) ds
-
-> qualGoal :: ValueEnv -> Goal -> Goal
-> qualGoal tyEnv (Goal p e ds) =
->   Goal p (qualExpr (mkMIdent []) tyEnv e) 
->          (map (qualDecl (mkMIdent []) tyEnv) ds)
 
 > qualDecl :: ModuleIdent -> ValueEnv -> Decl -> Decl
 > qualDecl m tyEnv (FunctionDecl p f eqs) =
diff --git a/src/ScopeEnv.hs b/src/ScopeEnv.hs
--- a/src/ScopeEnv.hs
+++ b/src/ScopeEnv.hs
@@ -15,7 +15,7 @@
 		 level, exists, beginScope, endScope, endScopeUp,
 		 toList, toLevelList, currentLevel) where
 
-import Env
+import qualified Data.Map as Map
 import Prelude hiding (lookup)
 
 -------------------------------------------------------------------------------
@@ -23,14 +23,14 @@
 
 -- Returns an empty scope environment
 new :: Ord a => ScopeEnv a b
-new = ScopeEnv 0 emptyEnv []
+new = ScopeEnv 0 Map.empty []
 
 
 -- Inserts a value under a key into the environment of the current scope
 insert :: Ord a => a -> b -> ScopeEnv a b -> ScopeEnv a b
 insert key val env = modifySE insertLev env
  where
- insertLev lev local = bindEnv key (val,lev) local
+ insertLev lev local = Map.insert key (val,lev) local
 
 
 -- Updates the value stored under an existing key in the environment of 
@@ -39,8 +39,8 @@
 update key val env = modifySE updateLev env
  where
  updateLev lev local = maybe local 
-		             (\ (_,lev') ->  bindEnv key (val,lev') local)
-			     (lookupEnv key local)
+		             (\ (_,lev') ->  Map.insert key (val,lev') local)
+			     (Map.lookup key local)
 
 -- Modifies the value of an existing key by applying the function 'fun'
 -- in the environment of the current scope
@@ -49,8 +49,8 @@
  where
  modifyLev lev local 
     = maybe local
-            (\ (val',lev') -> bindEnv key (fun val', lev') local)
-	    (lookupEnv key local)
+            (\ (val',lev') -> Map.insert key (fun val', lev') local)
+	    (Map.lookup key local)
 
 
 -- Looks up the value which is stored under a key from the environment of
@@ -58,7 +58,7 @@
 lookup :: Ord a => a -> ScopeEnv a b -> Maybe b
 lookup key env = selectSE lookupLev env
  where
- lookupLev lev local = maybe Nothing (Just . fst) (lookupEnv key local)
+ lookupLev lev local = maybe Nothing (Just . fst) (Map.lookup key local)
 
 
 -- Similar to 'lookup', but returns an alternative value, if the key
@@ -71,14 +71,14 @@
 level :: Ord a => a -> ScopeEnv a b -> Int
 level key env = selectSE levelLev env
  where
- levelLev lev local = maybe (-1) snd (lookupEnv key local)
+ levelLev lev local = maybe (-1) snd (Map.lookup key local)
 
 
 -- Checks, whether a key exists in the environment of the current scope
 exists :: Ord a => a -> ScopeEnv a b -> Bool
 exists key env = selectSE existsLev env
  where
- existsLev lev local = maybe False (const True) (lookupEnv key local)
+ existsLev lev local = maybe False (const True) (Map.lookup key local)
 
 
 -- Switches to the next scope (i.e. pushes the environment of the current
@@ -106,18 +106,18 @@
 endScopeUp (ScopeEnv _ top [])
    = ScopeEnv 0 top []
 endScopeUp (ScopeEnv lev top (local:[]))
-   = ScopeEnv 0 (foldr (updateSE local) top (envToList top)) []
+   = ScopeEnv 0 (foldr (updateSE local) top (Map.toList top)) []
 endScopeUp (ScopeEnv lev top (local:local':locals))
    = ScopeEnv (lev - 1) 
               top 
-	      ((foldr (updateSE local) local' (envToList local')):locals)
+	      ((foldr (updateSE local) local' (Map.toList local')):locals)
 
 
 -- Returns the environment of current scope as a (key,value) list
 toList :: Ord a => ScopeEnv a b -> [(a,b)]
 toList env = selectSE toListLev env
  where
- toListLev lev local = map (\ (key,(val,_)) -> (key,val)) (envToList local)
+ toListLev lev local = map (\ (key,(val,_)) -> (key,val)) (Map.toList local)
 
 
 -- Returns all (key,value) pairs from the environment of the current scope 
@@ -127,7 +127,7 @@
  where
  toLevelListLev lev local
     = map (\ (key,(val,_)) -> (key,val))
-          (filter (\ (_,(_,lev')) -> lev' == lev) (envToList local))
+          (filter (\ (_,(_,lev')) -> lev' == lev) (Map.toList local))
 
 
 -- Returns the current level
@@ -140,7 +140,7 @@
 -- Privates...
 
 --
-modifySE :: (Int -> Env a (b,Int) -> Env a (b,Int)) -> ScopeEnv a b 
+modifySE :: (Int -> Map.Map a (b,Int) -> Map.Map a (b,Int)) -> ScopeEnv a b 
           -> ScopeEnv a b
 modifySE f (ScopeEnv _ top []) 
    = ScopeEnv 0 (f 0 top) []
@@ -148,19 +148,19 @@
    = ScopeEnv lev top ((f lev local):locals)
 
 --
-selectSE :: (Int -> Env a (b,Int) -> c) -> ScopeEnv a b -> c
+selectSE :: (Int -> Map.Map a (b,Int) -> c) -> ScopeEnv a b -> c
 selectSE f (ScopeEnv _ top [])        = f 0 top
 selectSE f (ScopeEnv lev _ (local:_)) = f lev local
 
 --
-updateSE :: Ord a => Env a (b,Int) -> (a,(b,Int)) ->  Env a (b,Int) 
-          -> Env a (b,Int)
+updateSE :: Ord a => Map.Map a (b,Int) -> (a,(b,Int)) ->  Map.Map a (b,Int) 
+          -> Map.Map a (b,Int)
 updateSE local (key,(_,lev)) local'
    = maybe local' 
            (\ (val',lev') 
-	    -> if lev == lev' then bindEnv key (val',lev) local' 
+	    -> if lev == lev' then Map.insert key (val',lev) local' 
                               else local')
-	   (lookupEnv key local)
+	   (Map.lookup key local)
 
 
 
@@ -168,7 +168,7 @@
 -------------------------------------------------------------------------------
 
 -- Data type for representing information in nested scopes.
-data ScopeEnv a b = ScopeEnv Int (Env a (b,Int)) [Env a (b,Int)]
+data ScopeEnv a b = ScopeEnv Int (Map.Map a (b,Int)) [Map.Map a (b,Int)]
 		    deriving Show
 
 
diff --git a/src/ShowCurrySyntax.hs b/src/ShowCurrySyntax.hs
deleted file mode 100644
--- a/src/ShowCurrySyntax.hs
+++ /dev/null
@@ -1,493 +0,0 @@
---- Transform a CurrySyntax module into a string representation without any
---- pretty printing.
---- Behaves like a derived Show instance even on parts with a specific one.
---- 
---- @author Sebastian Fischer (sebf@informatik.uni-kiel.de)
---- @version December 2008
---- bug fixed by bbr
-
-
-module ShowCurrySyntax ( showModule ) where
-
-import Ident
-import Position
-import CurrySyntax
-
-showModule :: Module -> String
-showModule m = showsModule m "\n"
-
-showsModule :: Module -> ShowS
-showsModule (Module mident espec decls)
-  = showsString "Module "
-  . showsModuleIdent mident . newline
-  . showsMaybe showsExportSpec espec . newline
-  . showsList (\d -> showsDecl d . newline) decls
-
-showsPosition :: Position -> ShowS
-showsPosition Position{line=row,column=col} = showsPair shows shows (row,col)
--- showsPosition (Position file row col)
---   = showsString "(Position "
---   . shows file . space
---   . shows row . space
---   . shows col
---   . showsString ")"
-
-showsExportSpec :: ExportSpec -> ShowS
-showsExportSpec (Exporting pos exports)
-  = showsString "(Exporting "
-  . showsPosition pos . space
-  . showsList showsExport exports
-  . showsString ")"
-
-showsExport :: Export -> ShowS
-showsExport (Export qident)
-  = showsString "(Export " . showsQualIdent qident . showsString ")"
-showsExport (ExportTypeWith qident ids)
-  = showsString "(ExportTypeWith "
-  . showsQualIdent qident . space
-  . showsList showsIdent ids
-  . showsString ")"
-showsExport (ExportTypeAll qident)
-  = showsString "(ExportTypeAll " . showsQualIdent qident . showsString ")"
-showsExport (ExportModule m) 
-  = showsString "(ExportModule " . showsModuleIdent m . showChar ')'
-
-showsImportSpec :: ImportSpec -> ShowS
-showsImportSpec (Importing pos imports)
-  = showsString "(Importing "
-  . showsPosition pos . space
-  . showsList showsImport imports
-  . showsString ")"
-showsImportSpec (Hiding pos imports)
-  = showsString "(Hiding "
-  . showsPosition pos . space
-  . showsList showsImport imports
-  . showsString ")"
-
-showsImport :: Import -> ShowS
-showsImport (Import ident)
-  = showsString "(Import " . showsIdent ident . showsString ")"
-showsImport (ImportTypeWith ident idents)
-  = showsString "(ImportTypeWith "
-  . showsIdent ident . space
-  . showsList showsIdent idents
-  . showsString ")"
-showsImport (ImportTypeAll ident)
-  = showsString "(ImportTypeAll " . showsIdent ident . showsString ")"
-
-showsDecl :: Decl -> ShowS
-showsDecl (ImportDecl pos mident quali mmident mimpspec)
-  = showsString "(ImportDecl "
-  . showsPosition pos . space
-  . showsModuleIdent mident . space
-  . shows quali . space
-  . showsMaybe showsModuleIdent mmident . space
-  . showsMaybe showsImportSpec mimpspec
-  . showsString ")"
-showsDecl (InfixDecl pos infx prec idents)
-  = showsString "(InfixDecl "
-  . showsPosition pos . space
-  . shows infx . space
-  . shows prec . space
-  . showsList showsIdent idents
-  . showsString ")"
-showsDecl (DataDecl pos ident idents consdecls)
-  = showsString "(DataDecl "
-  . showsPosition pos . space
-  . showsIdent ident . space
-  . showsList showsIdent idents . space
-  . showsList showsConsDecl consdecls
-  . showsString ")"
-showsDecl (NewtypeDecl pos ident idents newconsdecl)
-  = showsString "(NewtypeDecl "
-  . showsPosition pos . space
-  . showsIdent ident . space
-  . showsList showsIdent idents . space
-  . showsNewConsDecl newconsdecl
-  . showsString ")"
-showsDecl (TypeDecl pos ident idents typ)
-  = showsString "(TypeDecl "
-  . showsPosition pos . space
-  . showsIdent ident . space
-  . showsList showsIdent idents . space
-  . showsTypeExpr typ
-  . showsString ")"
-showsDecl (TypeSig pos idents typ)
-  = showsString "(TypeSig "
-  . showsPosition pos . space
-  . showsList showsIdent idents . space
-  . showsTypeExpr typ
-  . showsString ")"
-showsDecl (EvalAnnot pos idents annot)
-  = showsString "(EvalAnnot "
-  . showsPosition pos . space
-  . showsList showsIdent idents . space
-  . shows annot
-  . showsString ")"
-showsDecl (FunctionDecl pos ident eqs)
-  = showsString "(FunctionDecl "
-  . showsPosition pos . space
-  . showsIdent ident . space
-  . showsList showsEquation eqs
-  . showsString ")"
-showsDecl (ExternalDecl pos cconv mstr ident typ)
-  = showsString "(ExternalDecl "
-  . showsPosition pos . space
-  . shows cconv . space
-  . shows mstr . space
-  . showsIdent ident . space
-  . showsTypeExpr typ
-  . showsString ")"
-showsDecl (FlatExternalDecl pos idents)
-  = showsString "(FlatExternalDecl "
-  . showsPosition pos . space
-  . showsList showsIdent idents
-  . showsString ")"
-showsDecl (PatternDecl pos cons rhs)
-  = showsString "(PatternDecl "
-  . showsPosition pos . space
-  . showsConsTerm cons . space
-  . showsRhs rhs
-  . showsString ")"
-showsDecl (ExtraVariables pos idents)
-  = showsString "(ExtraVariables "
-  . showsPosition pos . space
-  . showsList showsIdent idents
-  . showsString ")"
-
-showsConsDecl :: ConstrDecl -> ShowS
-showsConsDecl (ConstrDecl pos idents ident types)
-  = showsString "(ConstrDecl "
-  . showsPosition pos . space
-  . showsList showsIdent idents . space
-  . showsIdent ident . space
-  . showsList showsTypeExpr types
-  . showsString ")"
-showsConstrDecl (ConOpDecl pos idents rtyp ident ltyp)
-  = showsString "(ConOpDecl "
-  . showsPosition pos . space
-  . showsList showsIdent idents . space
-  . showsTypeExpr rtyp . space
-  . showsIdent ident . space
-  . showsTypeExpr ltyp
-  . showsString ")"
-
-showsNewConsDecl :: NewConstrDecl -> ShowS
-showsNewConsDecl (NewConstrDecl pos idents ident typ)
-  = showsString "(NewConstrDecl "
-  . showsPosition pos . space
-  . showsList showsIdent idents . space
-  . showsIdent ident . space
-  . showsTypeExpr typ
-  . showsString ")"
-
-showsTypeExpr :: TypeExpr -> ShowS
-showsTypeExpr (ConstructorType qident types)
-  = showsString "(ConstructorType "
-  . showsQualIdent qident . space
-  . showsList showsTypeExpr types
-  . showsString ")"
-showsTypeExpr (VariableType ident)
-  = showsString "(VariableType " . showsIdent ident . showsString ")"
-showsTypeExpr (TupleType types)
-  = showsString "(TupleType " . showsList showsTypeExpr types . showsString ")"
-showsTypeExpr (ListType typ)
-  = showsString "(ListType " . showsTypeExpr typ . showsString ")"
-showsTypeExpr (ArrowType dom ran)
-  = showsString "(ArrowType "
-  . showsTypeExpr dom . space
-  . showsTypeExpr ran
-  . showsString ")"
-showsTypeExpr (RecordType fieldts mtyp)
-  = showsString "(RecordType "
-  . showsList (showsPair (showsList showsIdent) showsTypeExpr) fieldts . space
-  . showsMaybe showsTypeExpr mtyp
-  . showsString ")"
-
-showsEquation :: Equation -> ShowS
-showsEquation (Equation pos lhs rhs)
-  = showsString "(Equation "
-  . showsPosition pos . space
-  . showsLhs lhs . space
-  . showsRhs rhs
-  . showsString ")"
-
-showsLhs :: Lhs -> ShowS
-showsLhs (FunLhs ident conss)
-  = showsString "(FunLhs "
-  . showsIdent ident . space
-  . showsList showsConsTerm conss
-  . showsString ")"
-showsLhs (OpLhs cons1 ident cons2)
-  = showsString "(OpLhs "
-  . showsConsTerm cons1 . space
-  . showsIdent ident . space
-  . showsConsTerm cons2
-  . showsString ")"
-showsLhs (ApLhs lhs conss)
-  = showsString "(ApLhs "
-  . showsLhs lhs . space
-  . showsList showsConsTerm conss
-  . showsString ")"
-
-showsRhs :: Rhs -> ShowS
-showsRhs (SimpleRhs pos exp decls)
-  = showsString "(SimpleRhs "
-  . showsPosition pos . space
-  . showsExpression exp . space
-  . showsList showsDecl decls
-  . showsString ")"
-showsRhs (GuardedRhs cexps decls)
-  = showsString "(GuardedRhs "
-  . showsList showsCondExpr cexps . space
-  . showsList showsDecl decls
-  . showsString ")"
-
-showsCondExpr :: CondExpr -> ShowS
-showsCondExpr (CondExpr pos exp1 exp2)
-  = showsString "(CondExpr "
-  . showsPosition pos . space
-  . showsExpression exp1 . space
-  . showsExpression exp2
-  . showsString ")"
-
-showsLiteral :: Literal -> ShowS
-showsLiteral (Char _ c) = showsString "(Char " . shows c . showsString ")"
-showsLiteral (Int ident n)
-  = showsString "(Int "
-  . showsIdent ident . space
-  . shows n
-  . showsString ")"
-showsLiteral (Float _ x) = showsString "(Float " . shows x . showsString ")"
-showsLiteral (String _ s) = showsString "(String " . shows s . showsString ")"
-
-showsConsTerm :: ConstrTerm -> ShowS
-showsConsTerm (LiteralPattern lit)
-  = showsString "(LiteralPattern "
-  . showsLiteral lit
-  . showsString ")"
-showsConsTerm (NegativePattern ident lit)
-  = showsString "(NegativePattern "
-  . showsIdent ident . space
-  . showsLiteral lit
-  . showsString ")"
-showsConsTerm (VariablePattern ident)
-  = showsString "(VariablePattern "
-  . showsIdent ident 
-  . showsString ")"
-showsConsTerm (ConstructorPattern qident conss)
-  = showsString "(ConstructorPattern "
-  . showsQualIdent qident . space
-  . showsList showsConsTerm conss
-  . showsString ")"
-showsConsTerm (InfixPattern cons1 qident cons2)
-  = showsString "(InfixPattern "
-  . showsConsTerm cons1 . space
-  . showsQualIdent qident . space
-  . showsConsTerm cons2
-  . showsString ")"
-showsConsTerm (ParenPattern cons)
-  = showsString "(ParenPattern "
-  . showsConsTerm cons
-  . showsString ")"
-showsConsTerm (TuplePattern _ conss)
-  = showsString "(TuplePattern "
-  . showsList showsConsTerm conss
-  . showsString ")"
-showsConsTerm (ListPattern _ conss)
-  = showsString "(ListPattern "
-  . showsList showsConsTerm conss
-  . showsString ")"
-showsConsTerm (AsPattern ident cons)
-  = showsString "(AsPattern "
-  . showsIdent ident . space
-  . showsConsTerm cons
-  . showsString ")"
-showsConsTerm (LazyPattern _ cons)
-  = showsString "(LazyPattern "
-  . showsConsTerm cons
-  . showsString ")"
-showsConsTerm (FunctionPattern qident conss)
-  = showsString "(FunctionPattern "
-  . showsQualIdent qident . space
-  . showsList showsConsTerm conss
-  . showsString ")"
-showsConsTerm (InfixFuncPattern cons1 qident cons2)
-  = showsString "(InfixFuncPattern "
-  . showsConsTerm cons1 . space
-  . showsQualIdent qident . space
-  . showsConsTerm cons2
-  . showsString ")"
-showsConsTerm (RecordPattern cfields mcons)
-  = shows "(RecordPattern "
-  . showsList (showsField showsConsTerm) cfields . space
-  . showsMaybe showsConsTerm mcons
-  . showsString ")"
-
-showsExpression :: Expression -> ShowS
-showsExpression (Literal lit)
-  = showsString "(Literal " . showsLiteral lit . showsString ")"
-showsExpression (Variable qident)
-  = showsString "(Variable " . showsQualIdent qident . showsString ")"
-showsExpression (Constructor qident)
-  = showsString "(Constructor " . showsQualIdent qident . showsString ")"
-showsExpression (Paren exp)
-  = showsString "(Paren " . showsExpression exp . showsString ")"
-showsExpression (Typed exp typ)
-  = showsString "(Typed "
-  . showsExpression exp . space
-  . showsTypeExpr typ
-  . showsString ")"
-showsExpression (Tuple _ exps)
-  = showsString "(Tuple " . showsList showsExpression exps . showsString ")"
-showsExpression (List _ exps)
-  = showsString "(List " . showsList showsExpression exps . showsString ")"
-showsExpression (ListCompr _ exp stmts)
-  = showsString "(ListCompr "
-  . showsExpression exp . space
-  . showsList showsStatement stmts
-  . showsString ")"
-showsExpression (EnumFrom exp)
-  = showsString "(EnumFrom " . showsExpression exp . showsString ")"
-showsExpression (EnumFromThen exp1 exp2)
-  = showsString "(EnumFromThen "
-  . showsExpression exp1 . space
-  . showsExpression exp2
-  . showsString ")"
-showsExpression (EnumFromTo exp1 exp2)
-  = showsString "(EnumFromTo "
-  . showsExpression exp1 . space
-  . showsExpression exp2
-  . showsString ")"
-showsExpression (EnumFromThenTo exp1 exp2 exp3)
-  = showsString "(EnumFromThenTo "
-  . showsExpression exp1 . space
-  . showsExpression exp2 . space
-  . showsExpression exp3
-  . showsString ")"
-showsExpression (UnaryMinus ident exp)
-  = showsString "(UnaryMinus "
-  . showsIdent ident . space
-  . showsExpression exp
-  . showsString ")"
-showsExpression (Apply exp1 exp2)
-  = showsString "(Apply "
-  . showsExpression exp1 . space
-  . showsExpression exp2
-  . showsString ")"
-showsExpression (InfixApply exp1 op exp2)
-  = showsString "(InfixApply "
-  . showsExpression exp1 . space
-  . showsInfixOp op . space
-  . showsExpression exp2
-  . showsString ")"
-showsExpression (LeftSection exp op)
-  = showsString "(LeftSection "
-  . showsExpression exp . space
-  . showsInfixOp op
-  . showsString ")"
-showsExpression (RightSection op exp)
-  = showsString "(RightSection "
-  . showsInfixOp op . space
-  . showsExpression exp
-  . showsString ")"
-showsExpression (Lambda _ conss exp)
-  = showsString "(Lambda "
-  . showsList showsConsTerm conss . space
-  . showsExpression exp 
-  . showsString ")"
-showsExpression (Let decls exp)
-  = showsString "(Let "
-  . showsList showsDecl decls . space
-  . showsExpression exp 
-  . showsString ")"
-showsExpression (Do stmts exp)
-  = showsString "(Do "
-  . showsList showsStatement stmts . space
-  . showsExpression exp
-  . showsString ")"
-showsExpression (IfThenElse _ exp1 exp2 exp3)
-  = showsString "(IfThenElse "
-  . showsExpression exp1 . space
-  . showsExpression exp2 . space
-  . showsExpression exp3
-  . showsString ")"
-showsExpression (Case _ exp alts)
-  = showsString "(Case "
-  . showsExpression exp . space
-  . showsList showsAlt alts
-  . showsString ")"
-showsExpression (RecordConstr efields)
-  = showsString "(RecordConstr "
-  . showsList (showsField showsExpression) efields
-  . showsString ")"
-showsExpression (RecordSelection exp ident)
-  = showsString "(RecordSelection "
-  . showsExpression exp . space
-  . showsIdent ident
-  . showsString ")"
-showsExpression (RecordUpdate efields exp)
-  = showsString "(RecordUpdate "
-  . showsList (showsField showsExpression) efields . space
-  . showsExpression exp
-  . showsString ")"
-
-showsInfixOp :: InfixOp -> ShowS
-showsInfixOp (InfixOp qident)
-  = showsString "(InfixOp " . showsQualIdent qident . showsString ")"
-showsInfixOp (InfixConstr qident)
-  = showsString "(InfixConstr " . showsQualIdent qident . showsString ")"
-
-showsStatement :: Statement -> ShowS
-showsStatement (StmtExpr _ exp)
-  = showsString "(StmtExpr " . showsExpression exp . showsString ")"
-showsStatement (StmtDecl decls)
-  = showsString "(StmtDecl " . showsList showsDecl decls . showsString ")"
-showsStatement (StmtBind _ cons exp)
-  = showsString "(StmtBind "
-  . showsConsTerm cons . space
-  . showsExpression exp
-  . showsString ")"
-
-showsAlt :: Alt -> ShowS
-showsAlt (Alt pos cons rhs)
-  = showsString "(Alt "
-  . showsPosition pos . space
-  . showsConsTerm cons . space
-  . showsRhs rhs
-  . showsString ")"
-
-showsField :: (a -> ShowS) -> Field a -> ShowS
-showsField sa (Field pos ident a)
-  = showsString "(Field "
-  . showsPosition pos . space
-  . showsIdent ident . space
-  . sa a
-  . showsString ")"
-
-showsString :: String -> ShowS
-showsString = (++)
-
-space :: ShowS
-space = showsString " "
-
-newline :: ShowS
-newline = showsString "\n"
-
-showsMaybe :: (a -> ShowS) -> Maybe a -> ShowS
-showsMaybe shs
-  = maybe (showsString "Nothing")
-          (\x -> showsString "(Just " . shs x . showsString ")")
-
-showsList :: (a -> ShowS) -> [a] -> ShowS
-showsList _ [] = showsString "[]"
-showsList shs (x:xs)
-  = showsString "["
-  . foldl (\sys y -> sys . showsString "," . shs y) (shs x) xs
-  . showsString "]"
-
-showsPair :: (a -> ShowS) -> (b -> ShowS) -> (a,b) -> ShowS
-showsPair sa sb (a,b)
-  = showsString "(" . sa a . showsString "," . sb b . showsString ")"
-
-
diff --git a/src/Simplify.lhs b/src/Simplify.lhs
--- a/src/Simplify.lhs
+++ b/src/Simplify.lhs
@@ -24,17 +24,23 @@
 
 > module Simplify(simplify) where
 
-> import Control.Monad
+> import Control.Monad.Reader as R
+> import Control.Monad.State as S
+> import qualified Data.Map as Map
 
+> import Curry.Base.Position
+> import Curry.Base.Ident
+> import Curry.Syntax
+> import Curry.Syntax.Utils
+
+> import Types
 > import Base
-> import Combined
-> import Env
 > import SCC
 > import Typing
 
 
-> type SimplifyState a = StateT ValueEnv (ReaderT EvalEnv (St Int)) a
-> type InlineEnv = Env Ident Expression
+> type SimplifyState a = S.StateT ValueEnv (ReaderT EvalEnv (S.State Int)) a
+> type InlineEnv = Map.Map Ident Expression
 > type SimplifyFlags = Bool
  
 > flatFlag :: SimplifyFlags -> Bool
@@ -42,13 +48,13 @@
 
 > simplify :: SimplifyFlags -> ValueEnv -> EvalEnv -> Module -> (Module,ValueEnv)
 > simplify flags tyEnv evEnv m 
->   = runSt (callRt (callSt (simplifyModule flags m) tyEnv) evEnv) 1
+>   = S.evalState (R.runReaderT (S.evalStateT (simplifyModule flags m) tyEnv) evEnv) 1
 
 > simplifyModule :: SimplifyFlags -> Module -> SimplifyState (Module,ValueEnv)
 > simplifyModule flat (Module m es ds) =
 >   do
->     ds' <- mapM (simplifyDecl flat m emptyEnv) ds
->     tyEnv <- fetchSt
+>     ds' <- mapM (simplifyDecl flat m Map.empty) ds
+>     tyEnv <- S.get
 >     return (Module m es ds',tyEnv)
 
 > simplifyDecl :: SimplifyFlags -> ModuleIdent -> InlineEnv -> Decl -> SimplifyState Decl
@@ -135,22 +141,23 @@
 > simplifyEquation flat m env (Equation p lhs rhs) =
 >   do
 >     rhs' <- simplifyRhs flat m env rhs
->     tyEnv <- fetchSt
->     evEnv <- liftSt envRt
+>     tyEnv <- S.get
+>     evEnv <- S.lift R.ask
 >     return (inlineFun flat m tyEnv evEnv p lhs rhs')
 
 > inlineFun :: SimplifyFlags -> ModuleIdent -> ValueEnv -> EvalEnv -> Position -> Lhs -> Rhs
 >           -> [Equation]
 > inlineFun flags m tyEnv evEnv p (FunLhs f ts)
 >           (SimpleRhs _ (Let [FunctionDecl _ f' eqs'] e) _)
->   | f' `notElem` qfv m eqs' && e' == Variable (qualify f') &&
+>   | True -- False -- inlining of functions is deactivated (hsi)
+>    && f' `notElem` qfv m eqs' && e' == Variable (qualify f') &&
 >     n == arrowArity (funType m tyEnv (qualify f')) &&
 >     (evMode evEnv f == evMode evEnv f' ||
 >      and [all isVarPattern ts | Equation _ (FunLhs _ ts) _ <- eqs']) =
->     map (merge p f ts' vs') eqs'
+>     map (mergeEqns p f ts' vs') eqs'
 >   where n :: Int                      -- type signature necessary for nhc
 >         (n,vs',ts',e') = etaReduce 0 [] (reverse ts) e
->         merge p f ts vs (Equation _ (FunLhs _ ts') rhs) =
+>         mergeEqns p f ts vs (Equation _ (FunLhs _ ts') rhs) =
 >           Equation p (FunLhs f (ts ++ zipWith AsPattern vs ts')) rhs
 >         etaReduce n vs (VariablePattern v : ts) (Apply e (Variable v'))
 >           | qualify v == v' = etaReduce (n+1) (v:vs) ts e
@@ -188,7 +195,7 @@
 > simplifyExpr flat m env (Variable v)
 >   | isQualified v = return (Variable v)
 >   | otherwise = maybe (return (Variable v)) (simplifyExpr flat m env)
->                       (lookupEnv (unqualify v) env)
+>                       (Map.lookup (unqualify v) env)
 > simplifyExpr _ _ _ (Constructor c) = return (Constructor c)
 > simplifyExpr flags m env (Apply (Let ds e1) e2) 
 >   = simplifyExpr flags m env (Let ds (Apply e1 e2))
@@ -203,7 +210,7 @@
 >     return (Apply e1' e2')
 > simplifyExpr flags m env (Let ds e) =
 >   do
->     tyEnv <- fetchSt
+>     tyEnv <- S.get
 >     dss' <- mapM (sharePatternRhs m tyEnv) ds
 >     simplifyLet flags m env
 >       (scc bv (qfv m) (foldr (hoistDecls flags) [] (concat dss'))) e
@@ -251,7 +258,7 @@
 > simplifyLet flags m env (ds:dss) e =
 >   do
 >     ds' <- mapM (simplifyDecl flags m env) ds
->     tyEnv <- fetchSt
+>     tyEnv <- S.get
 >     e' <- simplifyLet flags m (inlineVars flags m tyEnv ds' env) dss e
 >     dss'' <-
 >       mapM (expandPatternBindings flags m tyEnv (qfv m ds' ++ qfv m e')) ds'
@@ -260,13 +267,15 @@
 
 > inlineVars :: SimplifyFlags -> ModuleIdent -> ValueEnv -> [Decl] -> InlineEnv -> InlineEnv
 > inlineVars flags m tyEnv [PatternDecl _ (VariablePattern v) (SimpleRhs _ e _)] env
->   | canInline e = bindEnv v e env
->   where canInline (Literal _) = True
->         canInline (Constructor _) = True
->         canInline (Variable v')
->           | isQualified v' = arrowArity (funType m tyEnv v') > 0
->           | otherwise = v /= unqualify v'
->         canInline _ = False
+>   | canInline e = Map.insert v e env
+>   where
+>   canInline (Literal _) = True
+>   canInline (Constructor _) = True
+>   canInline _ = False -- inlining of variables is deactivated (hsi)
+>   canInline (Variable v')
+>       | isQualified v' = arrowArity (funType m tyEnv v') > 0
+>       | otherwise = v /= unqualify v'
+>   canInline _ = False
 > inlineVars _ _ _ _ env = env
 
 > mkLet :: SimplifyFlags -> ModuleIdent -> [Decl] -> Expression -> Expression
@@ -431,14 +440,14 @@
 >             _ -> internalError ("funType " ++ show f)
 
 > evMode :: EvalEnv -> Ident -> Maybe EvalAnnotation
-> evMode evEnv f = lookupEnv f evEnv
+> evMode evEnv f = Map.lookup f evEnv
 
 > freshIdent :: ModuleIdent -> (Int -> Ident) -> TypeScheme
 >            -> SimplifyState Ident
 > freshIdent m f ty =
 >   do
->     x <- liftM f (liftSt (liftRt (updateSt (1 +))))
->     updateSt_ (bindFun m x ty)
+>     x <- liftM f (S.lift (R.lift ( S.modify succ >> S.get)))
+>     S.modify (bindFun m x ty)
 >     return x
 
 > shuffle :: [a] -> [[a]]
diff --git a/src/SyntaxCheck.lhs b/src/SyntaxCheck.lhs
--- a/src/SyntaxCheck.lhs
+++ b/src/SyntaxCheck.lhs
@@ -24,12 +24,16 @@
 
 > import Data.Maybe
 > import Data.List
-> import Control.Monad
+> import qualified Data.Map as Map
+> import Control.Monad.State as S
 
+> import Curry.Syntax
+> import Curry.Syntax.Utils
+> import Types
+> import Curry.Base.Position
+> import Curry.Base.Ident
 > import Base
-> import Env
 > import NestEnv
-> import Combined
 > import Utils
 
 \end{verbatim}
@@ -44,8 +48,7 @@
 addition, this process will also rename the local variables.
 \begin{verbatim}
 
-> syntaxCheck :: Bool -> ModuleIdent -> ImportEnv -> ArityEnv -> ValueEnv 
->                -> TCEnv -> [Decl] -> [Decl]
+> syntaxCheck :: Bool -> ModuleIdent -> ImportEnv -> ArityEnv -> ValueEnv -> TCEnv -> [Decl] -> [Decl]
 > syntaxCheck withExt m iEnv aEnv tyEnv tcEnv ds =
 >   case linear (concatMap constrs tds) of
 >     --Linear -> tds ++ run (checkModule withExt m env vds)
@@ -59,22 +62,18 @@
 >	               tds'
 >	  env2 = foldr (bindTypes m) env1 rs
 
-> --syntaxCheckGoal :: Bool -> ValueEnv -> Goal -> Goal
-> --syntaxCheckGoal withExt tyEnv g =
-> --  run (checkGoal withExt (mkMIdent []) (globalEnv (fmap renameInfo tyEnv)) g)
-
 \end{verbatim}
 A global state transformer is used for generating fresh integer keys
 by which the variables get renamed.
 \begin{verbatim}
 
-> type RenameState a = St Int a
+> type RenameState a = S.State Int a
 
 > run :: RenameState a -> a
-> run m = runSt m (globalKey + 1)
+> run m = S.evalState m (globalKey + 1)
 
 > newId :: RenameState Int
-> newId = updateSt (1 +)
+> newId = S.modify succ >> S.get
 
 \end{verbatim}
 \ToDo{Probably the state transformer should use an \texttt{Integer} 
@@ -113,7 +112,7 @@
 > renameInfo tcEnv iEnv aEnv (NewtypeConstructor _ _) 
 >    = Constr 1
 > renameInfo tcEnv iEnv aEnv (Value qid _)
->    = let (mmid, id) = splitQualIdent qid
+>    = let (mmid, id) = (qualidMod qid, qualidId qid)
 >          qid' = maybe qid 
 >	                (\mid -> maybe qid 
 >		                       (\mid' -> qualifyWith mid' id)
@@ -234,7 +233,7 @@
 >    | (isJust mmid) && ((fromJust mmid) == preludeMIdent) && (ident == consId)
 >       = qualLookupNestEnv (qualify ident) env
 >    | otherwise = []
->  where (mmid, ident) = splitQualIdent v
+>  where (mmid, ident) = (qualidMod v, qualidId v)
 
 > lookupTupleConstr :: Ident -> [RenameInfo]
 > lookupTupleConstr v
@@ -256,13 +255,6 @@
 > checkTopDecls withExt m env ds = 
 >   checkDeclGroup (bindFuncDecl m) withExt m globalKey env ds
 
-> --checkGoal :: Bool -> ModuleIdent -> RenameEnv -> Goal -> RenameState Goal
-> --checkGoal withExt m env (Goal p e ds) =
-> --  do
-> --    (env',ds') <- checkLocalDecls withExt m env ds
-> --    e' <- checkExpr withExt p m env' e
-> --    return (Goal p e' ds')
-
 > checkTypeDecl :: Bool -> ModuleIdent -> Decl -> Decl
 > checkTypeDecl withExt m d@(TypeDecl p r tvs (RecordType fs rty))
 >   | not withExt = errorAt (positionOfIdent r) noRecordExt
@@ -370,7 +362,7 @@
 >   | isJust m || isDataConstr op' env =
 >       checkOpLhs k env (f . InfixPattern t1 op) t2
 >   | otherwise = Left (op'',OpLhs (f t1) op'' t2)
->   where (m,op') = splitQualIdent op
+>   where (m,op') = (qualidMod op, qualidId op)
 >         op'' = renameIdent op' k
 > checkOpLhs _ _ f t = Right (f t)
 
@@ -591,8 +583,7 @@
 > checkConstrTerm withExt k p m env (RecordPattern fs t)
 >   | not withExt = errorAt p noRecordExt
 >   | not (null fs) =
->     let (Field _ label patt) = head fs
->         p' = positionOfIdent label
+>     let (Field _ label _) = head fs
 >     in  case (lookupVar label env) of
 >           [] -> errorAt' (undefinedLabel label)
 >           [RecordLabel r ls]
@@ -741,7 +732,7 @@
 > checkExpr withExt p m env (RecordConstr fs)
 >   | not withExt = errorAt p noRecordExt
 >   | not (null fs) = 
->     let (Field _ label expr) = head fs
+>     let (Field _ label _) = head fs
 >     in  case (lookupVar label env) of
 >           [] -> errorAt' (undefinedLabel label)
 >	    [RecordLabel r ls]
@@ -772,7 +763,7 @@
 > checkExpr withExt p m env (RecordUpdate fs e)
 >   | not withExt = errorAt p noRecordExt
 >   | not (null fs) =
->     let (Field _ label expr) = head fs
+>     let (Field _ label _) = head fs
 >     in  case (lookupVar label env) of
 >           [] -> errorAt' (undefinedLabel label)
 >	    [RecordLabel r ls]
@@ -868,16 +859,16 @@
 it is necessary to sort the list of declarations.
 
 > sortFuncDecls :: [Decl] -> [Decl]
-> sortFuncDecls decls = sortFD emptyEnv [] decls
+> sortFuncDecls decls = sortFD Map.empty [] decls
 >  where
 >  sortFD env res [] = reverse res
 >  sortFD env res (decl:decls)
 >     = case decl of
 >	  FunctionDecl _ ident _
->	     | isJust (lookupEnv ident env)
+>	     | isJust (Map.lookup ident env)
 >	       -> sortFD env (insertBy cmpFuncDecl decl res) decls
 >	     | otherwise
->              -> sortFD (bindEnv ident () env) (decl:res) decls
+>              -> sortFD (Map.insert ident () env) (decl:res) decls
 >	  _    -> sortFD env (decl:res) decls
 
 > cmpFuncDecl :: Decl -> Decl -> Ordering
@@ -886,26 +877,13 @@
 >    | otherwise  = GT
 > cmpFuncDecl decl1 decl2 = GT
 
-> cmpPos :: Position -> Position -> Ordering
-> cmpPos p1 p2 | lp1 < lp2  = LT
->              | lp1 == lp2 = EQ
->              | otherwise  = GT
->  where lp1 = line p1
->        lp2 = line p2
+cmpPos :: Position -> Position -> Ordering
+cmpPos p1 p2 | lp1 < lp2  = LT
+             | lp1 == lp2 = EQ
+             | otherwise  = GT
+ where lp1 = line p1
+       lp2 = line p2
 
-> getDeclPos :: Decl -> Position
-> getDeclPos (ImportDecl pos _ _ _ _) = pos
-> getDeclPos (InfixDecl pos _ _ _) = pos
-> getDeclPos (DataDecl pos _ _ _) = pos
-> getDeclPos (NewtypeDecl pos _ _ _) = pos
-> getDeclPos (TypeDecl pos _ _ _) = pos
-> getDeclPos (TypeSig pos _ _) = pos
-> getDeclPos (EvalAnnot pos _ _) = pos
-> getDeclPos (FunctionDecl pos _ _) = pos
-> getDeclPos (ExternalDecl pos _ _ _ _) = pos
-> getDeclPos (FlatExternalDecl pos _) = pos
-> getDeclPos (PatternDecl pos _ _) = pos
-> getDeclPos (ExtraVariables pos _) = pos
 
 \end{verbatim}
 Due to the lack of a capitalization convention in Curry, it is
@@ -1106,18 +1084,6 @@
 >   where arguments 0 = "no arguments"
 >         arguments 1 = "1 argument"
 >         arguments n = show n ++ " arguments"
-
-> --partialFuncPatt :: QualIdent -> Int -> Int -> String
-> --partialFuncPatt f arity argc =
-> --   "Function pattern " ++ qualName f ++ " expects at least " 
-> --   ++ arguments arity ++ " but is applied to " ++ show argc
-> -- where arguments 0 = "no arguments"
-> --       arguments 1 = "1 argument"
-> --       arguments n = show n ++ " arguments"
-
-> noExpressionStatement :: String
-> noExpressionStatement =
->   "Last statement in a do expression must be an expression"
 
 > illegalRecordPatt :: String
 > illegalRecordPatt = "Expexting `_` after `|` in the record pattern"
diff --git a/src/SyntaxColoring.hs b/src/SyntaxColoring.hs
--- a/src/SyntaxColoring.hs
+++ b/src/SyntaxColoring.hs
@@ -1,24 +1,24 @@
 module SyntaxColoring (Program,Code(..),TypeKind(..),ConstructorKind(..),
-                       IdentifierKind(..),FunctionKind(..),filename2program,
+                       IdentifierKind(..),FunctionKind(..), genProgram,
                        code2string,getQualIdent, position2code,
                        area2codes) where
 
 import Debug.Trace
+import Data.Function(on)
 
 import Data.Maybe
+import Data.Either
 import Data.List
-
-import CurryLexer
-import Position
-import Frontend
-import Ident
-import CurrySyntax 
 import Data.Char hiding(Space)
-import Message
-import Control.Exception
-import PathUtils (readModule)
 
+import Curry.Base.Position
+import Curry.Base.Ident
+import Curry.Base.MessageMonad
+import Curry.Syntax 
+import Curry.Syntax.Lexer
 
+
+
 debug = False -- mergen von Token und Codes
 
 trace' s x = if debug then trace s x else x
@@ -28,10 +28,6 @@
 
 trace'' s x = if debug' then trace s x else x
 
-debug'' = False -- parseResults und codes
-
-trace''' s x = if debug'' then trace s x else x
-
 type Program = [(Int,Int,Code)] 
 
 data Code =  Keyword String
@@ -47,9 +43,9 @@
            | CharCode String
            | Symbol String
            | Identifier IdentifierKind QualIdent
-           | CodeWarning [Message] Code
-           | CodeError [Message] Code
-           | NotParsed String deriving Show
+           | CodeWarning [WarnMsg] Code
+           | NotParsed String
+             deriving Show
            
 data TypeKind = TypeDecla
               | TypeUse
@@ -71,50 +67,21 @@
                   | OtherFunctionKind deriving Show      
                   
                   
-                  
---- @param importpaths
---- @param filename                  
---- @return program
-filename2program :: [String] -> String -> IO Program
-filename2program paths filename=
-     readModule filename >>= \ cont ->
-     (catchError show (typingParse paths filename  cont)) >>= \ typingParseResult ->
-     (catchError show (fullParse paths filename  cont)) >>= \ fullParseResult ->             
-     (catchError show (return (parse filename cont))) >>= \ parseResult ->
-     (catchError show (return (Frontend.lex filename cont))) >>= \ lexResult ->    
-     return (genProgram cont (typingParseResult : fullParseResult : [parseResult]) lexResult)    
-                        
-
      
         
 --- @param plaintext
 --- @param list with parse-Results with descending quality  e.g. [typingParse,fullParse,parse]                                        
 --- @param lex-Result
 --- @return program
-genProgram :: String -> [Result Module] -> Result [(Position,Token)] -> Program       
-genProgram _ parseResults (Result mess posNtokList) = 
-    let messages = (prepareMessages 
-                      (concatMap getMessages parseResults ++                         
-                       mess))
-        mergedMessages = (mergeMessages' (trace' ("Messages: " ++ show messages) messages) 
-                                      posNtokList)
-        (nameList,codes) = catIdentifiers parseResults in
-    trace''' ("parseResults : " ++ show parseResults ++ "\n\nCodes: " ++ show codes ++ "\n\nToken: " ++ show mergedMessages)
-             (tokenNcodes2codes
-                      nameList
-                      1 
-                      1
-                      mergedMessages 
-                      codes)            
-
-    
-genProgram plainText parseResults (Failure messages) =
-     trace' (unlines (map (\(Message _ _ str) -> str) allMessages)) 
-            (buildMessagesIntoPlainText allMessages plainText)    
-  where
-      allMessages = prepareMessages (concatMap getMessages parseResults ++ 
-                                     messages)   
-     
+genProgram :: String -> [MsgMonad Module] -> MsgMonad [(Position,Token)] -> Program       
+genProgram plainText parseResults m
+    = case runMsg m of
+        (Left e, msgs) -> buildMessagesIntoPlainText (e : msgs) plainText
+        (Right posNtokList, mess) 
+            -> let messages = (prepareMessages (concatMap getMessages parseResults ++ mess))
+                   mergedMessages = (mergeMessages' (trace' ("Messages: " ++ show messages) messages) posNtokList)
+                   (nameList,codes) = catIdentifiers parseResults
+               in tokenNcodes2codes nameList 1 1 mergedMessages codes
 
     
 --- @param Program
@@ -138,25 +105,9 @@
      | otherwise = area2codes xs p1 p2
    where
       posBegin = Position file l c noRef
-      posEnd   = Position file l (c + (length (code2string code))) noRef
-                  
-
---- this function intercepts errors and converts it to Messages      
---- @param a show-function for (Result a)                    
---- @param a function that generates a (Result a)
---- @return (Result a) without runtimeerrors   
-catchError :: (Result a -> String) -> IO (Result a) -> IO (Result a)
-catchError toString toDo = Control.Exception.catch (toDo >>= returnComplete toString) handler 
-  where     
-      handler (ErrorCall str) = return (Failure [setMessagePosition (Message Error Nothing str)])
-      handler  e = return (Failure [Message Error Nothing (show e)])       
-             
-      returnComplete :: (a -> String) -> a -> IO a
-      returnComplete toString a = f (toString a) (return a)
-          where
-             f [] r = r
-             f (_:xs) r = f xs r                      
+      posEnd   = Position file l (c + length (code2string code)) noRef
                   
+  
 --- @param code
 --- @return qualIdent if available                   
 getQualIdent :: Code -> Maybe QualIdent
@@ -167,18 +118,12 @@
 getQualIdent  _ = Nothing                  
                   
                     
--- privates-----------------------------------------------------------------------------------
-
-                  
-codeWithoutPos :: (Int,Int,Code) -> Code
-codeWithoutPos (_,_,c) = c                  
-                  
 -- DEBUGGING----------- wird bald nicht mehr gebraucht
 
-setMessagePosition :: Message -> Message
-setMessagePosition m@(Message _ (Just p) _) = trace'' ("pos:" ++ show p ++ ":" ++ show m) m
-setMessagePosition (Message typ _ m) = 
-        let mes@(Message _ pos _) =  (Message typ (getPositionFromString m) m) in
+setMessagePosition :: WarnMsg -> WarnMsg
+setMessagePosition m@(WarnMsg (Just p) _) = trace'' ("pos:" ++ show p ++ ":" ++ show m) m
+setMessagePosition (WarnMsg _ m) = 
+        let mes@(WarnMsg pos _) =  (WarnMsg (getPositionFromString m) m) in
         trace'' ("pos:" ++ show pos ++ ":" ++ show mes) mes
 
 getPositionFromString :: String -> Maybe Position
@@ -208,7 +153,6 @@
 
 flatCode :: Code -> Code
 flatCode (CodeWarning _ code) = code
-flatCode (CodeError _ code) = code
 flatCode code = code
              
 
@@ -216,31 +160,28 @@
 -- ----------Message---------------------------------------                  
                   
 
-getMessages :: Result a -> [Message]
-getMessages (Result mess _) = mess
-getMessages (Failure mess) = mess
+getMessages :: MsgMonad a -> [WarnMsg]
+getMessages = snd . runMsg --(Result mess _) = mess
+-- getMessages (Failure mess) = mess
 
-lessMessage :: Message -> Message -> Bool
-lessMessage (Message _ mPos1 _) (Message _ mPos2 _) = mPos1 < mPos2
+lessMessage :: WarnMsg -> WarnMsg -> Bool
+lessMessage (WarnMsg mPos1 _) (WarnMsg mPos2 _) = mPos1 < mPos2
 
-nubMessages :: [Message] -> [Message] 
+nubMessages :: [WarnMsg] -> [WarnMsg] 
 nubMessages = nubBy eqMessage
 
-eqMessage :: Message -> Message -> Bool
-eqMessage (Message f1 p1 s1) (Message f2 p2 s2) = (f1 == f2) && (p1 == p2) && (s1 == s2)
+eqMessage :: WarnMsg -> WarnMsg -> Bool
+eqMessage (WarnMsg p1 s1) (WarnMsg p2 s2) = (p1 == p2) && (s1 == s2)
 
-prepareMessages :: [Message] -> [Message]   
+prepareMessages :: [WarnMsg] -> [WarnMsg]   
 prepareMessages = qsort lessMessage . map setMessagePosition . nubMessages
 
-hasError [] = False
-hasError ((Message Error _ _):ms) = True
-hasError (_:ms) = hasError ms
 
-buildMessagesIntoPlainText :: [Message] -> String -> Program
+buildMessagesIntoPlainText :: [WarnMsg] -> String -> Program
 buildMessagesIntoPlainText messages text = 
     buildMessagesIntoPlainText' messages (lines text) [] 1
  where
-    buildMessagesIntoPlainText' :: [Message] -> [String] -> [String] -> Int -> Program
+    buildMessagesIntoPlainText' :: [WarnMsg] -> [String] -> [String] -> Int -> Program
     buildMessagesIntoPlainText' _ [] [] _ = 
           []
     buildMessagesIntoPlainText' _ [] postStrs line = 
@@ -253,11 +194,11 @@
           if null pre 
              then buildMessagesIntoPlainText' post preStrs (postStrs ++ [str]) (ln + 1)
              else (ln,1,NotParsed (unlines postStrs)) : 
-                  (if hasError pre then (ln,1,CodeError pre (NotParsed str)) : [(ln,1,NewLine)] 
-                                   else (ln,1,CodeWarning pre (NotParsed str)) : [(ln,1,NewLine)]) ++
-                  (buildMessagesIntoPlainText' post preStrs [] (ln + 1)) 
+                  (ln,1,CodeWarning pre (NotParsed str)) :
+                  (ln,1,NewLine) :
+                  buildMessagesIntoPlainText' post preStrs [] (ln + 1)
       where 
-         isLeq (Message _ (Just p) _) = line p <= ln 
+         isLeq (WarnMsg (Just p) _) = line p <= ln 
          isLeq _ = True
                 
         
@@ -265,19 +206,19 @@
 
      
 --- @param parse-Modules  [typingParse,fullParse,parse] 
-catIdentifiers :: [Result Module] -> ([(ModuleIdent,ModuleIdent)],[Code])
-catIdentifiers [] = ([],[])
-catIdentifiers [(Failure _)] = ([],[])
-catIdentifiers [(Result _ m@(Module moduleIdent maybeExportSpec decls))] =
-    catIdentifiers' m Nothing
-catIdentifiers ((Failure _):y:ys) = 
-    catIdentifiers (y:ys)     
-catIdentifiers rs@((Result _ m@(Module _ _ _)):y:ys) =  
-    catIdentifiers' (getLastModule (reverse rs)) (Just m)
-  where
-    getLastModule ((Failure _):xs) = getLastModule xs
-    getLastModule ((Result _ m@(Module _ _ _)):_) = m
+catIdentifiers :: [MsgMonad Module] -> ([(ModuleIdent,ModuleIdent)],[Code])
+catIdentifiers = catIds . rights . map (fst . runMsg)
+    where 
+      catIds [] = ([],[])
+      catIds [m] =
+          catIdentifiers' m Nothing
+      catIds rs@(m:y:ys) =  
+          catIdentifiers' (last rs) (Just m)
     
+-- not in base befoer base4
+
+rights  xs = [ x | Right x <- xs]
+
 --- @param parse-Module
 --- @param Maybe betterParse-Module    
 catIdentifiers' :: Module -> Maybe Module -> ([(ModuleIdent,ModuleIdent)],[Code])
@@ -285,19 +226,18 @@
                 Nothing =
       let codes = (concatMap decl2codes (qsort lessDecl decls)) in
       (concatMap renamedImports decls,      
-      ([ModuleName moduleIdent] ++
-       (maybe [] exportSpec2codes  maybeExportSpec)  ++
-       codes))     
+      ModuleName moduleIdent :
+       maybe [] exportSpec2codes maybeExportSpec ++ codes)
 catIdentifiers' (Module moduleIdent maybeExportSpec1 _)
                 (Just (Module _ maybeExportSpec2 decls)) =
       let codes = (concatMap decl2codes (qsort lessDecl decls)) in
       (concatMap renamedImports decls,
       replaceFunctionCalls $ 
-        map (addModuleIdent moduleIdent) $
+        map (addModuleIdent moduleIdent)
           ([ModuleName moduleIdent] ++
-           (mergeExports2codes  
+           mergeExports2codes  
               (maybe [] (\(Exporting _ i) -> i)  maybeExportSpec1)
-              (maybe [] (\(Exporting _ i) -> i)  maybeExportSpec2))  ++
+              (maybe [] (\(Exporting _ i) -> i)  maybeExportSpec2) ++
            codes))     
   
      
@@ -325,55 +265,46 @@
 
 idOccur2functionCall :: [QualIdent] -> Code -> Code
 idOccur2functionCall qualIdents ide@(Identifier IdOccur qualIdent)  
-   | isQualified qualIdent = (Function FunctionCall qualIdent)
-   | elem qualIdent qualIdents = (Function FunctionCall qualIdent)
+   | isQualified qualIdent = Function FunctionCall qualIdent
+   | elem qualIdent qualIdents = Function FunctionCall qualIdent
    | otherwise = ide
 idOccur2functionCall qualIdents (CodeWarning mess code) =
-       (CodeWarning mess (idOccur2functionCall qualIdents code))
-idOccur2functionCall qualIdents (CodeError mess code) =
-       (CodeError mess (idOccur2functionCall qualIdents code))       
+       CodeWarning mess (idOccur2functionCall qualIdents code)
 idOccur2functionCall _ code = code
   
 
 addModuleIdent :: ModuleIdent -> Code -> Code
-addModuleIdent moduleIdent (Function x qualIdent) 
+addModuleIdent moduleIdent c@(Function x qualIdent) 
     | uniqueId (unqualify qualIdent) == 0 =
-        (Function x (qualQualify moduleIdent qualIdent))
-    | otherwise = (Function x qualIdent)   
+        Function x (qualQualify moduleIdent qualIdent)
+    | otherwise = c
 addModuleIdent moduleIdent cn@(ConstructorName x qualIdent) 
     | not $ isQualified qualIdent =
-        (ConstructorName x (qualQualify moduleIdent qualIdent)) 
+        ConstructorName x (qualQualify moduleIdent qualIdent)
     | otherwise = cn       
 addModuleIdent moduleIdent tc@(TypeConstructor TypeDecla qualIdent) 
     | not $ isQualified qualIdent =
-        (TypeConstructor TypeDecla (qualQualify moduleIdent qualIdent)) 
+        TypeConstructor TypeDecla (qualQualify moduleIdent qualIdent)
     | otherwise = tc         
 addModuleIdent moduleIdent (CodeWarning mess code) =
-      (CodeWarning mess (addModuleIdent moduleIdent code))   
-addModuleIdent moduleIdent (CodeError mess code) =
-      (CodeError mess (addModuleIdent moduleIdent code))       
+    CodeWarning mess (addModuleIdent moduleIdent code)
 addModuleIdent _ c = c
                         
 -- ----------------------------------------
 
-mergeMessages :: [Message] -> [(Position,Token)] -> [([Message],Position,Token)]
-mergeMessages mess pos = mergeMessages' (prepareMessages mess) pos
-
-
-
-mergeMessages' :: [Message] -> [(Position,Token)] -> [([Message],Position,Token)]
+mergeMessages' :: [WarnMsg] -> [(Position,Token)] -> [([WarnMsg],Position,Token)]
 mergeMessages' _ [] = []
 mergeMessages' [] ((p,t):ps) = ([],p,t) : mergeMessages' [] ps
-mergeMessages' mss@(m@(Message _ mPos x):ms) ((p,t):ps)  
-    | mPos <= Just p = (trace' (show mPos ++ " <= " ++ show (Just p) ++ " Message: " ++ x) ([m],p,t)) : mergeMessages' ms ps 
+mergeMessages' mss@(m@(WarnMsg mPos x):ms) ((p,t):ps)  
+    | mPos <= Just p = trace' (show mPos ++ " <= " ++ show (Just p) ++ " Message: " ++ x) ([m],p,t) : mergeMessages' ms ps 
     | otherwise = ([],p,t) : mergeMessages' mss ps
 
 
-tokenNcodes2codes :: [(ModuleIdent,ModuleIdent)] -> Int -> Int -> [([Message],Position,Token)] -> [Code] -> [(Int,Int,Code)]
+tokenNcodes2codes :: [(ModuleIdent,ModuleIdent)] -> Int -> Int -> [([WarnMsg],Position,Token)] -> [Code] -> [(Int,Int,Code)]
 tokenNcodes2codes _ _ _ [] _ = []          
 tokenNcodes2codes nameList currLine currCol toks@((messages,pos@Position{line=line,column=col},token):ts) codes 
     | currLine < line = 
-           trace' (" NewLine: ")
+           trace' " NewLine: "
            ((currLine,currCol,NewLine) :
            tokenNcodes2codes nameList (currLine + 1) 1 toks codes)
     | currCol < col =  
@@ -419,14 +350,11 @@
       newLine  = (currLine + length (lines tokenStr)) - 1 
       newCol   = currCol + length tokenStr   
 
-      rename mid = Just $ maybe mid id (lookup mid nameList)
+      rename mid = Just $ fromMaybe mid (lookup mid nameList)
 
       addMessage [] = []
       addMessage ((l,c,code):cs)
-         | null messages = ((l,c,code):cs)
-         | hasError messages = 
-               trace' ("Error bei code: " ++ show codes ++ ":" ++ show messages) 
-                      ((l,c,CodeError messages code): addMessage cs)
+         | null messages = (l,c,code):cs
          | otherwise = trace' ("Warning bei code: " ++ show codes ++ ":" ++ show messages) 
                               ((l,c,CodeWarning messages code): addMessage cs)
       
@@ -434,12 +362,12 @@
 renameModuleIdents :: [(ModuleIdent,ModuleIdent)] -> Code -> Code
 renameModuleIdents nameList c =
     case c of
-        Function x qualIdent -> Function x (rename qualIdent (splitQualIdent qualIdent))
-        Identifier x qualIdent -> Identifier x (rename qualIdent (splitQualIdent qualIdent))
+        Function x qualIdent -> Function x (rename qualIdent (qualidMod qualIdent))
+        Identifier x qualIdent -> Identifier x (rename qualIdent (qualidMod qualIdent))
         _ -> c
   where
-    rename x (Nothing,_) = x
-    rename x (Just m,i) = maybe x (\ m' -> qualifyWith m' i) (lookup m nameList)
+    rename x (Nothing) = x
+    rename x (Just m) = maybe x (\ m' -> qualifyWith m' (qualidId x)) (lookup m nameList)
            
 {-
 codeWithoutUniqueID ::  Code -> String
@@ -454,11 +382,11 @@
 codeQualifiers = maybe [] moduleQualifiers . getModuleIdent
 
 getModuleIdent :: Code -> Maybe ModuleIdent
-getModuleIdent (ConstructorName _ qualIdent) = fst $ splitQualIdent qualIdent
-getModuleIdent (Function _ qualIdent) = fst $ splitQualIdent qualIdent
+getModuleIdent (ConstructorName _ qualIdent) = qualidMod qualIdent
+getModuleIdent (Function _ qualIdent) = qualidMod qualIdent
 getModuleIdent (ModuleName moduleIdent) = Just moduleIdent
-getModuleIdent (Identifier _ qualIdent) = fst $ splitQualIdent qualIdent                     
-getModuleIdent (TypeConstructor _ qualIdent) = fst $ splitQualIdent qualIdent
+getModuleIdent (Identifier _ qualIdent) = qualidMod qualIdent                     
+getModuleIdent (TypeConstructor _ qualIdent) = qualidMod qualIdent
 getModuleIdent _ = Nothing
 
 
@@ -551,7 +479,7 @@
              
 
 lessDecl :: Decl -> Decl -> Bool
-lessDecl decl1 decl2 = getPosition decl1 < getPosition decl2
+lessDecl = (<) `on` getPosition
 
 qsort _ []     = []
 qsort less (x:xs) = qsort less [y | y <- xs, less y x] ++ [x] ++ qsort less [y | y <- xs, not $ less y x]
@@ -598,7 +526,7 @@
     
        
 export2codes _ (ExportTypeWith qualIdent idents) = 
-     [TypeConstructor TypeExport qualIdent] ++ map (Function OtherFunctionKind . qualify) idents
+     TypeConstructor TypeExport qualIdent : map (Function OtherFunctionKind . qualify) idents
 export2codes _ (ExportTypeAll  qualIdent) = 
      [TypeConstructor TypeExport qualIdent]  
 export2codes _ (ExportModule moduleIdent) = 
@@ -610,9 +538,9 @@
      maybe [] ((:[]) . ModuleName) mModuleIdent ++
      maybe [] (importSpec2codes moduleIdent)  importSpec
 decl2codes (InfixDecl _ _ _ idents) =
-     (map (Function InfixFunction . qualify) idents) 
+     map (Function InfixFunction . qualify) idents
 decl2codes (DataDecl _ ident idents constrDecls) =
-     [TypeConstructor TypeDecla (qualify ident)] ++ 
+     TypeConstructor TypeDecla (qualify ident) : 
      map (Identifier UnknownId . qualify) idents ++
      concatMap constrDecl2codes constrDecls
 decl2codes (NewtypeDecl xPosition xIdent yIdents xNewConstrDecl) =
@@ -642,7 +570,7 @@
      
 lhs2codes :: Lhs -> [Code]
 lhs2codes (FunLhs ident constrTerms) =
-    (Function FunDecl $ qualify ident) : concatMap constrTerm2codes constrTerms
+    Function FunDecl (qualify ident) : concatMap constrTerm2codes constrTerms
 lhs2codes (OpLhs constrTerm1 ident constrTerm2) =
     constrTerm2codes constrTerm1 ++ [Function FunDecl $ qualify ident] ++ constrTerm2codes constrTerm2
 lhs2codes (ApLhs lhs constrTerms) =
@@ -663,17 +591,17 @@
 constrTerm2codes (NegativePattern ident literal) = []
 constrTerm2codes (VariablePattern ident) = [Identifier IdDecl (qualify ident)]
 constrTerm2codes (ConstructorPattern qualIdent constrTerms) =
-    (ConstructorName ConstrPattern qualIdent) : concatMap constrTerm2codes constrTerms
+    ConstructorName ConstrPattern qualIdent : concatMap constrTerm2codes constrTerms
 constrTerm2codes (InfixPattern constrTerm1 qualIdent constrTerm2) =
     constrTerm2codes constrTerm1 ++ [ConstructorName ConstrPattern qualIdent] ++ constrTerm2codes constrTerm2
 constrTerm2codes (ParenPattern constrTerm) = constrTerm2codes constrTerm
 constrTerm2codes (TuplePattern _ constrTerms) = concatMap constrTerm2codes constrTerms
 constrTerm2codes (ListPattern _ constrTerms) = concatMap constrTerm2codes constrTerms
 constrTerm2codes (AsPattern ident constrTerm) =
-    (Function OtherFunctionKind $ qualify ident) : constrTerm2codes constrTerm
+    Function OtherFunctionKind (qualify ident) : constrTerm2codes constrTerm
 constrTerm2codes (LazyPattern _ constrTerm) = constrTerm2codes constrTerm
 constrTerm2codes (FunctionPattern qualIdent constrTerms) = 
-    (Function OtherFunctionKind qualIdent) : concatMap constrTerm2codes constrTerms
+    Function OtherFunctionKind qualIdent : concatMap constrTerm2codes constrTerms
 constrTerm2codes (InfixFuncPattern constrTerm1 qualIdent constrTerm2) =
     constrTerm2codes constrTerm1 ++ [Function InfixFunction qualIdent] ++ constrTerm2codes constrTerm2
    
@@ -704,7 +632,7 @@
     expression2codes expression2 ++ 
     expression2codes expression3
 expression2codes (UnaryMinus ident expression) = 
-    [Symbol (name ident)] ++ expression2codes expression 
+    Symbol (name ident) : expression2codes expression 
 expression2codes (Apply expression1 expression2) = 
     expression2codes expression1 ++ expression2codes expression2
 expression2codes (InfixApply expression1 infixOp expression2) = 
@@ -744,7 +672,7 @@
          
 constrDecl2codes :: ConstrDecl -> [Code]
 constrDecl2codes (ConstrDecl _ idents ident typeExprs) =
-    (ConstructorName ConstrDecla $ qualify ident) : concatMap typeExpr2codes typeExprs
+    ConstructorName ConstrDecla (qualify ident) : concatMap typeExpr2codes typeExprs
 constrDecl2codes (ConOpDecl _ idents typeExpr1 ident typeExpr2) =   
     typeExpr2codes typeExpr1 ++ [ConstructorName ConstrDecla $ qualify ident] ++ typeExpr2codes typeExpr2
 
@@ -757,14 +685,14 @@
 import2codes moduleIdent (Import ident) =
      [Function OtherFunctionKind $ qualifyWith moduleIdent ident]  
 import2codes moduleIdent (ImportTypeWith ident idents) = 
-     [ConstructorName OtherConstrKind $ qualifyWith moduleIdent ident] ++ 
+     ConstructorName OtherConstrKind (qualifyWith moduleIdent ident) :
      map (Function OtherFunctionKind . qualifyWith moduleIdent) idents
 import2codes moduleIdent (ImportTypeAll  ident) = 
      [ConstructorName OtherConstrKind $ qualifyWith moduleIdent ident]  
      
 typeExpr2codes :: TypeExpr -> [Code]     
 typeExpr2codes (ConstructorType qualIdent typeExprs) = 
-    (TypeConstructor TypeUse qualIdent) : concatMap typeExpr2codes typeExprs
+    TypeConstructor TypeUse qualIdent : concatMap typeExpr2codes typeExprs
 typeExpr2codes (VariableType ident) = 
     [Identifier IdOccur (qualify ident)]
 typeExpr2codes (TupleType typeExprs) = 
@@ -851,14 +779,13 @@
 attributes2string (StringAttributes sval _) = showSt sval 
 attributes2string (IdentAttributes mIdent ident) =concat (intersperse "." (mIdent ++ [ident])) 
 
-basename = reverse .  takeWhile (/='/')    . reverse
 
 showCh c    
    | c == '\\' = "'\\\\'"
    | elem c ('\127' : ['\001' .. '\031']) = show c
    | otherwise = toString c
   where
-    toString c = "'" ++ c : "'"
+    toString c = '\'' : c : "'"
 
 showSt = addQuotes . concatMap toGoodChar 
    where
@@ -870,4 +797,4 @@
    | c == '"' = "\\\""
    | otherwise = c : "" 
  where
-     justShow = reverse . tail . reverse . tail . show
+     justShow = init . tail . show
diff --git a/src/TopEnv.lhs b/src/TopEnv.lhs
--- a/src/TopEnv.lhs
+++ b/src/TopEnv.lhs
@@ -41,10 +41,10 @@
 >               allImports,moduleImports,localBindings) where
 
 > import Data.Maybe
+> import qualified Data.Map as Map
+> import Control.Arrow(second)
+> import Curry.Base.Ident
 
-> import Env
-> import Ident
-> import Utils
 
 > data Source = Local | Import [ModuleIdent] deriving (Eq,Show)
 
@@ -55,32 +55,32 @@
 >    | origName x == origName y = Just x
 >    | otherwise = Nothing
 
-> newtype TopEnv a = TopEnv (Env QualIdent [(Source,a)]) deriving Show
+> newtype TopEnv a = TopEnv (Map.Map QualIdent [(Source,a)]) deriving Show
 
 > instance Functor TopEnv where
->   fmap f (TopEnv env) = TopEnv (fmap (map (apSnd f)) env)
+>   fmap f (TopEnv env) = TopEnv (fmap (map (second f)) env)
 
-> entities :: QualIdent -> Env QualIdent [(Source,a)] -> [(Source,a)]
-> entities x env = fromMaybe [] (lookupEnv x env)
+> entities :: QualIdent -> Map.Map QualIdent [(Source,a)] -> [(Source,a)]
+> entities x env = fromMaybe [] (Map.lookup x env)
 
 > emptyTopEnv :: TopEnv a
-> emptyTopEnv = TopEnv emptyEnv
+> emptyTopEnv = TopEnv Map.empty
 
 > predefTopEnv :: Entity a => QualIdent -> a -> TopEnv a -> TopEnv a
 > predefTopEnv x y (TopEnv env) =
->   case lookupEnv x env of
+>   case Map.lookup x env of
 >     Just _ -> error "internal error: predefTopEnv"
->     Nothing -> TopEnv (bindEnv x [(Import [],y)] env)
+>     Nothing -> TopEnv (Map.insert x [(Import [],y)] env)
 
 > importTopEnv :: Entity a => ModuleIdent -> Ident -> a -> TopEnv a -> TopEnv a
 > importTopEnv m x y (TopEnv env) =
->   TopEnv (bindEnv x' (mergeImport m y (entities x' env)) env)
+>   TopEnv (Map.insert x' (mergeImport m y (entities x' env)) env)
 >   where x' = qualify x
 
 > qualImportTopEnv :: Entity a => ModuleIdent -> Ident -> a -> TopEnv a
 >                  -> TopEnv a
 > qualImportTopEnv m x y (TopEnv env) =
->   TopEnv (bindEnv x' (mergeImport m y (entities x' env)) env)
+>   TopEnv (Map.insert x' (mergeImport m y (entities x' env)) env)
 >   where x' = qualifyWith m x
 
 > mergeImport :: Entity a => ModuleIdent -> a -> [(Source,a)] -> [(Source,a)]
@@ -96,7 +96,7 @@
 
 > qualBindTopEnv :: String -> QualIdent -> a -> TopEnv a -> TopEnv a
 > qualBindTopEnv fun x y (TopEnv env) =
->   TopEnv (bindEnv x (bindLocal y (entities x env)) env)
+>   TopEnv (Map.insert x (bindLocal y (entities x env)) env)
 >   where bindLocal y ys
 >           | null [y' | (Local,y') <- ys] = (Local,y) : ys
 >           | otherwise = error ("internal error: \"qualBindTopEnv " 
@@ -108,14 +108,14 @@
 
 > qualRebindTopEnv :: QualIdent -> a -> TopEnv a -> TopEnv a
 > qualRebindTopEnv x y (TopEnv env) =
->   TopEnv (bindEnv x (rebindLocal (entities x env)) env)
+>   TopEnv (Map.insert x (rebindLocal (entities x env)) env)
 >   where rebindLocal [] = error "internal error: qualRebindTopEnv"
 >         rebindLocal ((Local,_) : ys) = (Local,y) : ys
 >         rebindLocal ((Import ms,y) : ys) = (Import ms,y) : rebindLocal ys
 
 > unbindTopEnv :: Ident -> TopEnv a -> TopEnv a
 > unbindTopEnv x (TopEnv env) =
->   TopEnv (bindEnv x' (unbindLocal (entities x' env)) env)
+>   TopEnv (Map.insert x' (unbindLocal (entities x' env)) env)
 >   where x' = qualify x
 >         unbindLocal [] = error "internal error: unbindTopEnv"
 >         unbindLocal ((Local,_) : ys) = ys
@@ -129,11 +129,11 @@
 
 > allImports :: TopEnv a -> [(QualIdent,a)]
 > allImports (TopEnv env) =
->   [(x,y) | (x,ys) <- envToList env, (Import _,y) <- ys]
+>   [(x,y) | (x,ys) <- Map.toList env, (Import _,y) <- ys]
 
 > unqualBindings :: TopEnv a -> [(Ident,(Source,a))]
 > unqualBindings (TopEnv env) =
->   [(x',y) | (x,ys) <- takeWhile (not . isQualified . fst) (envToList env),
+>   [(x',y) | (x,ys) <- takeWhile (not . isQualified . fst) (Map.toList env),
 >             let x' = unqualify x, y <- ys]
 
 > moduleImports :: ModuleIdent -> TopEnv a -> [(Ident,a)]
diff --git a/src/TypeCheck.lhs b/src/TypeCheck.lhs
--- a/src/TypeCheck.lhs
+++ b/src/TypeCheck.lhs
@@ -21,21 +21,25 @@
 type annotation is present.
 \begin{verbatim}
 
-> module TypeCheck(typeCheck,typeCheckGoal) where
+> module TypeCheck(typeCheck) where
 
-> import Control.Monad
+> import Control.Monad.State as S
 > import Data.List
 > import Data.Maybe
+> import qualified Data.Map as Map
 > import qualified Data.Set as Set
 
+> import Curry.Base.Position
+> import Curry.Base.Ident
+> import Curry.Syntax
+> import Curry.Syntax.Pretty
+> import Curry.Syntax.Utils
+
+
 > import Base
-> import Pretty
-> import Ident
-> import CurryPP
-> import Env
+> import Types
+> import PrettyCombinators
 > import TopEnv
-
-> import Combined
 > import SCC
 > import TypeSubst
 > import Utils
@@ -57,36 +61,24 @@
 
 > typeCheck :: ModuleIdent -> TCEnv -> ValueEnv -> [Decl] -> (TCEnv,ValueEnv)
 > typeCheck m tcEnv tyEnv ds =
->   run (tcDecls m tcEnv' emptyEnv vds >>
->        liftSt fetchSt >>= \theta -> fetchSt >>= \tyEnv' ->
+>   run (tcDecls m tcEnv' Map.empty vds >>
+>        S.lift S.get >>= \theta -> S.get >>= \tyEnv' ->
 >        return (tcEnv',subst theta tyEnv'))
 >       (bindLabels m tcEnv' (bindConstrs m tcEnv' tyEnv))
 >   where (tds,vds) = partition isTypeDecl ds
 >         tcEnv' = bindTypes m tds tcEnv
 
 \end{verbatim}
-Type checking of a goal expression is simpler because the type
-constructor environment is fixed already and there are no
-type declarations in a goal.
-\begin{verbatim}
 
-> typeCheckGoal :: TCEnv -> ValueEnv -> Goal -> ValueEnv
-> typeCheckGoal tcEnv tyEnv (Goal p e ds) =
->    run (tcRhs m0 tcEnv tyEnv emptyEnv (SimpleRhs p e ds) >>
->         liftSt fetchSt >>= \theta -> fetchSt >>= \tyEnv' ->
->         return (subst theta tyEnv')) tyEnv
->   where m0 = mkMIdent []
-
-\end{verbatim}
 The type checker makes use of nested state monads in order to
 maintain the type environment, the current substitution, and a counter
 which is used for generating fresh type variables.
 \begin{verbatim}
 
-> type TcState a = StateT ValueEnv (StateT TypeSubst (St Int)) a
+> type TcState a = S.StateT ValueEnv (S.StateT TypeSubst (S.State Int)) a
 
 > run :: TcState a -> ValueEnv -> a
-> run m tyEnv = runSt (callSt (callSt m tyEnv) idSubst) 0
+> run m tyEnv = S.evalState (S.evalStateT (S.evalStateT m tyEnv) idSubst) 0
 
 \end{verbatim}
 \paragraph{Defining Types}
@@ -218,10 +210,10 @@
 inferred type is less general than the signature.
 \begin{verbatim}
 
-> type SigEnv = Env Ident TypeExpr
+> type SigEnv = Map.Map Ident TypeExpr
 
 > bindTypeSig :: Ident -> TypeExpr -> SigEnv -> SigEnv
-> bindTypeSig = bindEnv
+> bindTypeSig = Map.insert
 
 > bindTypeSigs :: Decl -> SigEnv -> SigEnv
 > bindTypeSigs (TypeSig _ vs ty) env =
@@ -229,7 +221,7 @@
 > bindTypeSigs _ env = env
 
 > lookupTypeSig :: Ident -> SigEnv -> Maybe TypeExpr
-> lookupTypeSig = lookupEnv
+> lookupTypeSig = Map.lookup
 
 > qualLookupTypeSig :: ModuleIdent -> QualIdent -> SigEnv -> Maybe TypeExpr
 > qualLookupTypeSig m f sigs = localIdent m f >>= flip lookupTypeSig sigs
@@ -259,8 +251,8 @@
 > nameType (RecordType fs rty) tvs = 
 >   (RecordType (zip ls tys') (listToMaybe rty'), tvs)
 >   where (ls, tys) = unzip fs
->         (tys', tvs') = nameTypes tys tvs
->         (rty', tvs'') = nameTypes (maybeToList rty) tvs
+>         (tys', _) = nameTypes tys tvs
+>         (rty', _) = nameTypes (maybeToList rty) tvs
         
 \end{verbatim}
 \paragraph{Type Inference}
@@ -302,17 +294,17 @@
 >   mapM_ (tcExtraVar m tcEnv sigs ) vs
 > tcDeclGroup m tcEnv sigs ds =
 >   do
->     tyEnv0 <- fetchSt
+>     tyEnv0 <- S.get
 >     tysLhs <- mapM (tcDeclLhs m tcEnv sigs) ds
 >     tysRhs <- mapM (tcDeclRhs m tcEnv tyEnv0 sigs) ds
 >     sequence_ (zipWith3 (unifyDecl m) ds tysLhs tysRhs)
->     theta <- liftSt fetchSt
+>     theta <- S.lift S.get
 >     mapM_ (genDecl m tcEnv sigs (fvEnv (subst theta tyEnv0)) theta) ds
 
 > --tcForeignFunct :: ModuleIdent -> TCEnv -> Position -> CallConv -> Ident
 > --               -> TypeExpr -> TcState ()
 > --tcForeignFunct m tcEnv p cc f ty =
-> --  updateSt_ (bindFun m f (checkForeignType cc (expandPolyType tcEnv ty)))
+> --  S.modify (bindFun m f (checkForeignType cc (expandPolyType tcEnv ty)))
 > --  where checkForeignType CallConvPrimitive ty = ty
 > --        checkForeignType CallConvCCall (ForAll n ty) =
 > --          ForAll n (checkCCallType ty)
@@ -332,11 +324,11 @@
 
 > tcExternalFunct :: ModuleIdent -> TCEnv -> Ident -> TypeExpr -> TcState ()
 > tcExternalFunct m tcEnv  f ty =
->   updateSt_ (bindFun m f (expandPolyType m tcEnv ty))
+>   S.modify (bindFun m f (expandPolyType m tcEnv ty))
 
 > tcFlatExternalFunct :: ModuleIdent -> TCEnv -> SigEnv -> Ident -> TcState ()
 > tcFlatExternalFunct m tcEnv sigs f =
->   typeOf f tcEnv sigs >>= updateSt_ . bindFun m f
+>   typeOf f tcEnv sigs >>= S.modify . bindFun m f
 >   where typeOf f tcEnv sigs =
 >           case lookupTypeSig f sigs of
 >             Just ty -> return (expandPolyType m tcEnv ty)
@@ -345,7 +337,7 @@
 > tcExtraVar :: ModuleIdent -> TCEnv -> SigEnv -> Ident
 >            -> TcState ()
 > tcExtraVar m tcEnv sigs v =
->   typeOf v tcEnv sigs >>= updateSt_ . bindFun m v . monoType
+>   typeOf v tcEnv sigs >>= S.modify . bindFun m v . monoType
 >   where typeOf v tcEnv sigs =
 >           case lookupTypeSig v sigs of
 >             Just ty
@@ -404,9 +396,9 @@
 > genDecl :: ModuleIdent -> TCEnv -> SigEnv -> Set.Set Int -> TypeSubst -> Decl
 >         -> TcState ()
 > genDecl m tcEnv sigs lvs theta (FunctionDecl _ f _) =
->   updateSt_ (genVar True m tcEnv sigs lvs theta f)
+>   S.modify (genVar True m tcEnv sigs lvs theta f)
 > genDecl m tcEnv sigs lvs theta (PatternDecl p t _) =
->   mapM_ (updateSt_ . genVar False m tcEnv sigs lvs theta ) (bv t)
+>   mapM_ (S.modify . genVar False m tcEnv sigs lvs theta ) (bv t)
 
 > genVar :: Bool -> ModuleIdent -> TCEnv -> SigEnv -> Set.Set Int -> TypeSubst
 >        -> Ident -> ValueEnv -> ValueEnv
@@ -442,7 +434,7 @@
 > tcLiteral m (Int v _)  = --return intType
 >   do
 >     ty <- freshConstrained [intType,floatType]
->     updateSt_ (bindFun m v (monoType ty))
+>     S.modify (bindFun m v (monoType ty))
 >     return ty
 > tcLiteral _ (Float _ _) = return floatType
 > tcLiteral _ (String _ _) = return stringType
@@ -456,12 +448,12 @@
 >     ty <- case lookupTypeSig v sigs of
 >             Just t -> inst (expandPolyType m tcEnv t)
 >             Nothing -> freshTypeVar
->     updateSt_ (bindFun m v (monoType ty))
+>     S.modify (bindFun m v (monoType ty))
 >     return ty
 >   
 > tcConstrTerm m tcEnv sigs p t@(ConstructorPattern c ts) =
 >   do
->     tyEnv <- fetchSt
+>     tyEnv <- S.get
 >     ty <- skol (constrType m c tyEnv)
 >     unifyArgs (ppConstrTerm 0 t) ts ty
 >   where unifyArgs _ [] ty = return ty
@@ -473,7 +465,7 @@
 >         unifyArgs _ _ _ = internalError "tcConstrTerm"
 > tcConstrTerm m tcEnv sigs p t@(InfixPattern t1 op t2) =
 >   do
->     tyEnv <- fetchSt
+>     tyEnv <- S.get
 >     ty <- skol (constrType m op tyEnv)
 >     unifyArgs (ppConstrTerm 0 t) [t1,t2] ty
 >   where unifyArgs _ [] ty = return ty
@@ -504,7 +496,7 @@
 > tcConstrTerm m tcEnv sigs p (LazyPattern _ t) = tcConstrTerm m tcEnv sigs p t
 > tcConstrTerm m tcEnv sigs p t@(FunctionPattern f ts) =
 >   do
->     tyEnv <- fetchSt
+>     tyEnv <- S.get
 >     ty <- inst (funType m f tyEnv) --skol (constrType m c tyEnv)
 >     unifyArgs (ppConstrTerm 0 t) ts ty
 >   where unifyArgs _ [] ty = return ty
@@ -553,14 +545,14 @@
 >     ty <- maybe freshTypeVar 
 >                 (inst . expandPolyType m tcEnv) 
 >                 (lookupTypeSig v sigs)
->     tyEnv <- fetchSt
->     ty' <- maybe (updateSt_ (bindFun m v (monoType ty)) >> return ty)
+>     tyEnv <- S.get
+>     ty' <- maybe (S.modify (bindFun m v (monoType ty)) >> return ty)
 >                  (\ (ForAll _ t) -> return t)
 >	           (sureVarType v tyEnv)
 >     return ty' 
 > tcConstrTermFP m tcEnv sigs p t@(ConstructorPattern c ts) =
 >   do
->     tyEnv <- fetchSt
+>     tyEnv <- S.get
 >     ty <- skol (constrType m c tyEnv)
 >     unifyArgs (ppConstrTerm 0 t) ts ty
 >   where unifyArgs _ [] ty = return ty
@@ -572,7 +564,7 @@
 >         unifyArgs _ _ _ = internalError "tcConstrTermFP"
 > tcConstrTermFP m tcEnv sigs p t@(InfixPattern t1 op t2) =
 >   do
->     tyEnv <- fetchSt
+>     tyEnv <- S.get
 >     ty <- skol (constrType m op tyEnv)
 >     unifyArgs (ppConstrTerm 0 t) [t1,t2] ty
 >   where unifyArgs _ [] ty = return ty
@@ -603,7 +595,7 @@
 > tcConstrTermFP m tcEnv sigs p (LazyPattern _ t) = tcConstrTermFP m tcEnv sigs p t
 > tcConstrTermFP m tcEnv sigs p t@(FunctionPattern f ts) =
 >   do
->     tyEnv <- fetchSt
+>     tyEnv <- S.get
 >     ty <- inst (funType m f tyEnv) --skol (constrType m c tyEnv)
 >     unifyArgs (ppConstrTerm 0 t) ts ty
 >   where unifyArgs _ [] ty = return ty
@@ -640,11 +632,11 @@
 >             -> Field ConstrTerm -> TcState (Ident,Type)
 > tcFieldPatt tcPatt m f@(Field _ l t) =
 >   do
->     tyEnv <- fetchSt
+>     tyEnv <- S.get
 >     let p = positionOfIdent l
 >     lty <- maybe (freshTypeVar
 >	             >>= (\lty' ->
->		           updateSt_
+>		           S.modify
 >		             (bindLabel l (qualifyWith m (mkIdent "#Rec"))
 >		                        (polyType lty'))
 >		           >> return lty'))
@@ -689,15 +681,15 @@
 > tcExpr m tcEnv sigs p (Variable v) =
 >   case qualLookupTypeSig m v sigs of
 >     Just ty -> inst (expandPolyType m tcEnv ty)
->     Nothing -> fetchSt >>= inst . funType m v
-> tcExpr m tcEnv sigs p (Constructor c) = fetchSt >>= instExist . constrType m c
+>     Nothing -> S.get >>= inst . funType m v
+> tcExpr m tcEnv sigs p (Constructor c) = S.get >>= instExist . constrType m c
 > tcExpr m tcEnv sigs p (Typed e sig) =
 >   do
->     tyEnv0 <- fetchSt
+>     tyEnv0 <- S.get
 >     ty <- tcExpr m tcEnv sigs p e
 >     inst sigma' >>=
 >       flip (unify p "explicitly typed expression" (ppExpr 0 e) m) ty
->     theta <- liftSt fetchSt
+>     theta <- S.lift S.get
 >     let sigma = gen (fvEnv (subst theta tyEnv0)) (subst theta ty)
 >     unless (sigma == sigma')
 >       (errorAt p (typeSigTooGeneral m (text "Expression:" <+> ppExpr 0 e)
@@ -718,7 +710,7 @@
 >           tcElems doc es ty
 > tcExpr m tcEnv sigs p (ListCompr _ e qs) =
 >   do
->     tyEnv0 <- fetchSt
+>     tyEnv0 <- S.get
 >     mapM_ (tcQual m tcEnv sigs p) qs
 >     ty <- tcExpr m tcEnv sigs p e
 >     checkSkolems p m (text "Expression:" <+> ppExpr 0 e) tyEnv0 (listType ty)
@@ -814,21 +806,21 @@
 >     return (TypeArrow alpha gamma)
 > tcExpr m tcEnv sigs p exp@(Lambda r ts e) =
 >   do
->     tyEnv0 <- fetchSt
+>     tyEnv0 <- S.get
 >     tys <- mapM (tcConstrTerm m tcEnv sigs p) ts
 >     ty <- tcExpr m tcEnv sigs p e
 >     checkSkolems p m (text "Expression:" <+> ppExpr 0 exp) tyEnv0
 >                  (foldr TypeArrow ty tys)
 > tcExpr m tcEnv sigs p (Let ds e) =
 >   do
->     tyEnv0 <- fetchSt
->     theta <- liftSt fetchSt
+>     tyEnv0 <- S.get
+>     theta <- S.lift S.get
 >     tcDecls m tcEnv sigs ds
 >     ty <- tcExpr m tcEnv sigs p e
 >     checkSkolems p m (text "Expression:" <+> ppExpr 0 e) tyEnv0 ty
 > tcExpr m tcEnv sigs p (Do sts e) =
 >   do
->     tyEnv0 <- fetchSt
+>     tyEnv0 <- S.get
 >     mapM_ (tcStmt m tcEnv sigs p) sts
 >     alpha <- freshTypeVar
 >     ty <- tcExpr m tcEnv sigs p e
@@ -846,7 +838,7 @@
 >     return ty3
 > tcExpr m tcEnv sigs p (Case _ e alts) =
 >   do
->     tyEnv0 <- fetchSt
+>     tyEnv0 <- S.get
 >     ty <- tcExpr m tcEnv sigs p e
 >     alpha <- freshTypeVar
 >     tcAlts tyEnv0 ty alpha alts
@@ -868,10 +860,10 @@
 > tcExpr m tcEnv sigs p r@(RecordSelection e l) =
 >   do
 >     ty <- tcExpr m tcEnv sigs p e
->     tyEnv <- fetchSt
+>     tyEnv <- S.get
 >     lty <- maybe (freshTypeVar 
 >	             >>= (\lty' -> 
->		           updateSt_ 
+>		           S.modify 
 >		             (bindLabel l (qualifyWith m (mkIdent "#Rec"))
 >		                        (monoType lty'))
 >	                   >> return lty'))
@@ -923,11 +915,11 @@
 >	      -> TcState (Ident,Type)
 > tcFieldExpr m tcEnv sigs comb f@(Field _ l e) =
 >   do
->     tyEnv <- fetchSt
+>     tyEnv <- S.get
 >     let p = positionOfIdent l
 >     lty <- maybe (freshTypeVar 
 >	             >>= (\lty' -> 
->		           updateSt_ 
+>		           S.modify 
 >		             (bindLabel l (qualifyWith m (mkIdent "#Rec"))
 >		                          (monoType lty'))
 >	                   >> return lty'))
@@ -950,14 +942,14 @@
 >         -> TcState (Type,Type)
 > tcArrow p what doc m ty =
 >   do
->     theta <- liftSt fetchSt
+>     theta <- S.lift S.get
 >     unaryArrow (subst theta ty)
 >   where unaryArrow (TypeArrow ty1 ty2) = return (ty1,ty2)
 >         unaryArrow (TypeVariable tv) =
 >           do
 >             alpha <- freshTypeVar
 >             beta <- freshTypeVar
->             liftSt (updateSt_ (bindVar tv (TypeArrow alpha beta)))
+>             S.lift (S.modify (bindVar tv (TypeArrow alpha beta)))
 >             return (alpha,beta)
 >         unaryArrow ty = errorAt p (nonFunctionType what doc m ty)
 
@@ -969,7 +961,7 @@
 >           do
 >             beta <- freshTypeVar
 >             gamma <- freshTypeVar
->             liftSt (updateSt_ (bindVar tv (TypeArrow beta gamma)))
+>             S.lift (S.modify (bindVar tv (TypeArrow beta gamma)))
 >             return (ty1,beta,gamma)
 >         binaryArrow ty1 ty2 =
 >           errorAt p (nonBinaryOp what doc m (TypeArrow ty1 ty2))
@@ -983,13 +975,13 @@
 > unify :: Position -> String -> Doc -> ModuleIdent -> Type -> Type
 >       -> TcState ()
 > unify p what doc m ty1 ty2 =
->   liftSt $ {-$-}
+>   S.lift $ {-$-}
 >   do
->     theta <- fetchSt
+>     theta <- S.get
 >     let ty1' = subst theta ty1
 >     let ty2' = subst theta ty2
 >     either (errorAt p . typeMismatch what doc m ty1' ty2')
->            (updateSt_ . compose)
+>            (S.modify . compose)
 >            (unifyTypes m ty1' ty2')
 
 > unifyTypes :: ModuleIdent -> Type -> Type -> Either Doc TypeSubst
@@ -1086,7 +1078,7 @@
 >              -> TcState Type
 > checkSkolems p m what tyEnv ty =
 >   do
->     theta <- liftSt fetchSt
+>     theta <- S.lift S.get
 >     let ty' = subst theta ty
 >         fs = fsEnv (subst theta tyEnv)
 >     unless (all (`Set.member` fs) (typeSkolems ty'))
@@ -1100,7 +1092,7 @@
 \begin{verbatim}
 
 > fresh :: (Int -> a) -> TcState a
-> fresh f = liftM f (liftSt (liftSt (updateSt (1 +))))
+> fresh f = liftM f (S.lift (S.lift (S.modify succ >> S.get)))
 
 > freshVar :: (Int -> a) -> TcState a
 > freshVar f = fresh (\n -> f (- n - 1))
@@ -1184,20 +1176,6 @@
 >             [Value _ sigma] -> sigma
 >             _ -> internalError ("funType " ++ show f)
 
-> sureFunType :: ModuleIdent -> QualIdent -> ValueEnv -> Maybe TypeScheme
-> sureFunType m f tyEnv =
->   case (qualLookupValue f tyEnv) of
->     [Value _ sigma] -> Just sigma
->     vs -> case (qualLookupValue (qualQualify m f) tyEnv) of
->             [Value _ sigma] -> Just sigma
->             _ -> Nothing
-
-> labelType :: Ident -> ValueEnv -> TypeScheme
-> labelType l tyEnv =
->   case lookupValue l tyEnv of
->     Label _ _ sigma : _ -> sigma
->     _ -> internalError ("labelType " ++ show l)
-
 > sureLabelType :: Ident -> ValueEnv -> Maybe TypeScheme
 > sureLabelType l tyEnv =
 >   case lookupValue l tyEnv of
@@ -1319,11 +1297,6 @@
 >   vcat [text "Existential type escapes out of its scope", what,
 >         text "Type:" <+> ppType m ty]
 
-> invalidCType :: String -> ModuleIdent -> Type -> String
-> invalidCType what m ty = show $
->   vcat [text ("Invalid " ++ what ++ " type in foreign declaration"),
->         ppType m ty]
-
 > recursiveType :: ModuleIdent -> Int -> Type -> Doc
 > recursiveType m tv ty = incompatibleTypes m (TypeVariable tv) ty
 
@@ -1345,3 +1318,14 @@
 >        text "are incompatible"]
 
 \end{verbatim}
+
+
+\end{verbatim}
+The following functions implement pretty-printing for types.
+\begin{verbatim}
+
+> ppType :: ModuleIdent -> Type -> Doc
+> ppType m = ppTypeExpr 0 . fromQualType m
+
+> ppTypeScheme :: ModuleIdent -> TypeScheme -> Doc
+> ppTypeScheme m (ForAll _ ty) = ppType m ty
diff --git a/src/TypeSubst.lhs b/src/TypeSubst.lhs
--- a/src/TypeSubst.lhs
+++ b/src/TypeSubst.lhs
@@ -15,6 +15,8 @@
 > import Data.Maybe
 > import Data.List
 
+> import Types
+
 > import Subst
 > import Base
 > import TopEnv
diff --git a/src/Types.lhs b/src/Types.lhs
--- a/src/Types.lhs
+++ b/src/Types.lhs
@@ -16,7 +16,7 @@
 > import Data.List
 > import Data.Maybe
 
-> import Ident
+> import Curry.Base.Ident
 
 \end{verbatim}
 A type is either a type variable, an application of a type constructor
@@ -47,7 +47,7 @@
 >   | TypeArrow Type Type
 >   | TypeSkolem Int
 >   | TypeRecord [(Ident,Type)] (Maybe Int)
->   deriving (Eq,Show)
+>   deriving (Show, Eq)
 
 \end{verbatim}
 The function \texttt{isArrowType} checks whether a type is a function
@@ -172,8 +172,8 @@
 quantified variables.
 \begin{verbatim}
 
-> data TypeScheme = ForAll Int Type deriving (Eq,Show)
-> data ExistTypeScheme = ForAllExist Int Int Type deriving (Eq,Show)
+> data TypeScheme = ForAll Int Type deriving (Show, Eq)
+> data ExistTypeScheme = ForAllExist Int Int Type deriving (Show, Eq)
 
 \end{verbatim}
 The functions \texttt{monoType} and \texttt{polyType} translate a type
@@ -215,3 +215,37 @@
 > typeVar = TypeVariable
 
 \end{verbatim}
+
+
+
+> qualifyType :: ModuleIdent -> Type -> Type
+> qualifyType m (TypeConstructor tc tys)
+>   | isTupleId tc' = tupleType tys'
+>   | tc' == unitId && n == 0 = unitType
+>   | tc' == listId && n == 1 = listType (head tys')
+>   | otherwise = TypeConstructor (qualQualify m tc) tys'
+>   where n = length tys'
+>         tc' = unqualify tc
+>         tys' = map (qualifyType m) tys
+> qualifyType _ (TypeVariable tv) = TypeVariable tv
+> qualifyType m (TypeConstrained tys tv) =
+>   TypeConstrained (map (qualifyType m) tys) tv
+> qualifyType m (TypeArrow ty1 ty2) =
+>   TypeArrow (qualifyType m ty1) (qualifyType m ty2)
+> qualifyType _ (TypeSkolem k) = TypeSkolem k
+> qualifyType m (TypeRecord fs rty) =
+>   TypeRecord (map (\ (l,ty) -> (l, qualifyType m ty)) fs) rty
+
+
+> unqualifyType :: ModuleIdent -> Type -> Type
+> unqualifyType m (TypeConstructor tc tys) =
+>   TypeConstructor (qualUnqualify m tc) (map (unqualifyType m) tys)
+> unqualifyType _ (TypeVariable tv) = TypeVariable tv
+> unqualifyType m (TypeConstrained tys tv) =
+>   TypeConstrained (map (unqualifyType m) tys) tv
+> unqualifyType m (TypeArrow ty1 ty2) =
+>   TypeArrow (unqualifyType m ty1) (unqualifyType m ty2)
+> unqualifyType m (TypeSkolem k) = TypeSkolem k
+> unqualifyType m (TypeRecord fs rty) =
+>   TypeRecord (map (\ (l,ty) -> (l, unqualifyType m ty)) fs) rty
+
diff --git a/src/Typing.lhs b/src/Typing.lhs
--- a/src/Typing.lhs
+++ b/src/Typing.lhs
@@ -12,10 +12,14 @@
 
 > import Data.Maybe
 > import Control.Monad
+> import Control.Monad.State as S
 
+> import Curry.Base.Ident
+> import Curry.Syntax
+
+> import Types
 > import Base
 > import TypeSubst
-> import Combined
 > import TopEnv
 > import Utils
 
@@ -84,10 +88,10 @@
 environment.}
 \begin{verbatim}
 
-> type TyState a = StateT TypeSubst (St Int) a
+> type TyState a = S.StateT TypeSubst (S.State Int) a
 
 > run :: TyState a -> ValueEnv -> a
-> run m tyEnv = runSt (callSt m idSubst) 0
+> run m tyEnv = S.evalState (S.evalStateT m idSubst) 0
 
 > class Typeable a where
 >   typeOf :: ValueEnv -> a -> Type
@@ -108,7 +112,7 @@
 >   where doComputeType =
 >           do
 >             ty <- f tyEnv x
->             theta <- fetchSt
+>             theta <- S.get
 >             return (fixTypeVars tyEnv (subst theta ty))
 
 > fixTypeVars :: ValueEnv -> Type -> Type
@@ -281,7 +285,7 @@
 \begin{verbatim}
 
 > freshTypeVar :: TyState Type
-> freshTypeVar = liftM TypeVariable $ liftSt $ updateSt (1 +)
+> freshTypeVar = liftM TypeVariable $ S.lift (S.modify succ >> S.get)
 
 > instType :: Int -> Type -> TyState Type
 > instType n ty =
@@ -304,7 +308,7 @@
 
 > unify :: Type -> Type -> TyState ()
 > unify ty1 ty2 =
->   updateSt_ (\theta -> unifyTypes (subst theta ty1) (subst theta ty2) theta)
+>   S.modify (\theta -> unifyTypes (subst theta ty1) (subst theta ty2) theta)
 
 > unifyList :: [Type] -> [Type] -> TyState ()
 > unifyList tys1 tys2 = sequence_ (zipWith unify tys1 tys2)
@@ -312,14 +316,14 @@
 > unifyArrow :: Type -> TyState (Type,Type)
 > unifyArrow ty =
 >   do
->     theta <- fetchSt
+>     theta <- S.get
 >     case subst theta ty of
 >       TypeVariable tv
 >         | tv >= 0 ->
 >             do
 >               ty1 <- freshTypeVar
 >               ty2 <- freshTypeVar
->               updateSt_ (bindVar tv (TypeArrow ty1 ty2))
+>               S.modify (bindVar tv (TypeArrow ty1 ty2))
 >               return (ty1,ty2)
 >       TypeArrow ty1 ty2 -> return (ty1,ty2)
 >       ty' -> internalError ("unifyArrow (" ++ show ty' ++ ")")
diff --git a/src/Unlit.lhs b/src/Unlit.lhs
deleted file mode 100644
--- a/src/Unlit.lhs
+++ /dev/null
@@ -1,110 +0,0 @@
-% -*- LaTeX -*-
-% $Id: Unlit.lhs,v 1.2 2002/10/01 06:55:50 lux Exp $
-%
-% $Log: Unlit.lhs,v $
-% Revision 1.2  2002/10/01 06:55:50  lux
-% unlit returns an error message to the caller instead of calling error.
-%
-% Revision 1.1  2000/02/07 14:05:55  lux
-% The compiler now supports literate source files. Literate source files
-% must end with the suffix ".lcurry".
-%
-%
-\nwfilename{Unlit.lhs}
-\section{Literate comments}
-Since version 0.7 of the language report, Curry accepts literate
-source programs. In a literate source all program lines must begin
-with a greater sign in the first column. All other lines are assumed
-to be documentation. In order to avoid some common errors with
-literate programs, Curry requires at least one program line to be
-present in the file. In addition, every block of program code must be
-preceded by a blank line and followed by a blank line.
-
-The module \texttt{Unlit} acts as a preprocessor which converts
-literate source programs into the ``un-literate'' format accepted by
-the lexer. The implementation, together with the comments below, was
-derived from appendix D in the Haskell 1.2 report.
-\begin{verbatim}
-
-> module Unlit(unlit) where
-> import Data.Char
-> import Position
-
-\end{verbatim}
-Each of the lines in a literate script is a program line, a blank
-line, or a comment line. In the first case the text is kept with the
-line.
-\begin{verbatim}
-
-> data Classified = Program String | Blank | Comment
-
-\end{verbatim}
-In a literate program, program lines begin with a \verb|>| character,
-blank lines contain only whitespace, and all other lines are comment
-lines.
-\begin{verbatim}
-
-> classify :: String -> Classified
-> classify ""            = Blank
-> classify (c:cs)
->   | c == '>'           = Program cs
->   | all isSpace (c:cs) = Blank
->   | otherwise          = Comment
-
-\end{verbatim}
-In the corresponding program, program lines have the leading \verb|>|
-replaced by a leading space, to preserve tab alignments.
-\begin{verbatim}
-
-> unclassify :: Classified -> String
-> unclassify (Program cs) = ' ' : cs
-> unclassify Blank        = ""
-> unclassify Comment      = ""
-
-\end{verbatim}
-Process a literate program into error messages (if any) and the
-corresponding non-literate program.
-\begin{verbatim}
-
-> unlit :: FilePath -> String -> (String,String)
-> unlit fn lcy = (es,cy)
->   where cs = map classify (lines lcy)
->         es = unlines (errors fn cs)
->         cy = unlines (map unclassify cs)
-
-\end{verbatim}
-Check that each program line is not adjacent to a comment line and
-there is at least one program line.
-\begin{verbatim}
-
-> errors :: FilePath -> [Classified] -> [String]
-> errors fn cs =
->   concat (zipWith3 adjacent (iterate nl (first fn)) cs (tail cs)) ++
->   empty fn (filter isProgram cs)
-
-\end{verbatim}
-Given a line number and a pair of adjacent lines, generate a list of
-error messages, which will contain either one entry or none.
-\begin{verbatim}
-
-> adjacent :: Position -> Classified -> Classified -> [String]
-> adjacent p (Program _) Comment     = [message (nl p) "after"]
-> adjacent p Comment     (Program _) = [message p "before"]
-> adjacent p _           _           = []
-
-> message p w = show p ++ ": comment line " ++ w ++ " program line."
-
-\end{verbatim}
-Given the list of program lines generate an error if this list is
-empty.
-\begin{verbatim}
-
-> empty :: FilePath -> [Classified] -> [String]
-> empty fn [] = [show (first fn) ++ ": no code in literate script"]
-> empty fn _ = []
-
-> isProgram :: Classified -> Bool
-> isProgram (Program _) = True
-> isProgram _ = False
-
-\end{verbatim}
diff --git a/src/Utils.lhs b/src/Utils.lhs
--- a/src/Utils.lhs
+++ b/src/Utils.lhs
@@ -12,16 +12,10 @@
 \begin{verbatim}
 
 > module Utils where
-> infixr 5 ++!
 
-\end{verbatim}
-\paragraph{Pairs}
-The functions \texttt{apFst} and \texttt{apSnd} apply a function to
-the first and second components of a pair, resp.
-\begin{verbatim}
+> import Data.List(foldl')
 
-> apFst f (x,y) = (f x,y)
-> apSnd f (x,y) = (x,f y)
+> infixr 5 ++!
 
 \end{verbatim}
 \paragraph{Triples}
@@ -62,9 +56,9 @@
 case of the recursion.
 \begin{verbatim}
 
-> foldl_strict :: (a -> b -> a) -> a -> [b] -> a
-> foldl_strict f z []     = z
-> foldl_strict f z (x:xs) = let z' = f z x in  z' `seq` foldl_strict f z' xs
+foldl_strict :: (a -> b -> a) -> a -> [b] -> a
+foldl_strict = foldl'
+
 
 \end{verbatim}
 \paragraph{Folding with two lists}
diff --git a/src/WarnCheck.hs b/src/WarnCheck.hs
--- a/src/WarnCheck.hs
+++ b/src/WarnCheck.hs
@@ -8,22 +8,47 @@
 --
 module WarnCheck (warnCheck) where
 
-import Control.Monad
+import Control.Monad.State
+import qualified Data.Map as Map
 import Data.List
 
-import CurrySyntax
-import Ident
-import Position
-import Base (ValueEnv, ValueInfo(..), qualLookupValue, lookupValue)
+import Curry.Base.Ident
+import Curry.Base.Position
+import Curry.Base.MessageMonad
+import Curry.Syntax
+
+import Base (ValueEnv, ValueInfo(..), qualLookupValue)
 import TopEnv
 import qualified ScopeEnv
 import ScopeEnv (ScopeEnv)
-import Message
-import Env
 
 
+-------------------------------------------------------------------------------
 
+-- Data type for representing the current state of generating warnings.
+-- The monadic representation of the state allows the usage of monadic 
+-- syntax (do expression) for dealing easier and safer with its
+-- contents.
 
+type CheckState = State CState
+
+data CState = CState {messages  :: [WarnMsg],
+		      scope     :: ScopeEnv QualIdent IdInfo,
+		      values    :: ValueEnv,
+		      moduleId  :: ModuleIdent }
+
+-- Runs a 'CheckState' action and returns the list of messages
+run ::  CheckState a -> [WarnMsg]
+run f
+   = reverse (messages (execState f emptyState))
+
+emptyState :: CState
+emptyState = CState {messages  = [],
+		     scope     = ScopeEnv.new,
+		     values    = emptyTopEnv,
+		     moduleId  = mkMIdent []
+		    }
+
 -------------------------------------------------------------------------------
 
 -- Find potentially incorrect code in a Curry program and generate
@@ -33,7 +58,7 @@
 --    - idle case alternatives
 --    - overlapping case alternatives
 --    - function rules which are not together
-warnCheck :: ModuleIdent -> ValueEnv -> [Decl] -> [Decl] -> [Message]
+warnCheck :: ModuleIdent -> ValueEnv -> [Decl] -> [Decl] -> [WarnMsg]
 warnCheck mid vals imports decls
    = run (do addImportedValues vals
 	     addModuleId mid
@@ -164,6 +189,7 @@
 	     (foldM' genWarning' (map unrefVar idents'))
 	endScope
 
+
 --
 checkCondExpr :: ModuleIdent -> CondExpr -> CheckState ()
 checkCondExpr mid (CondExpr _ cond expr)
@@ -325,6 +351,7 @@
 	checkOverlappingAlts mid alts
 
 --
+-- FIXME this looks buggy: is alts' required to be non-null or not? (hsi)
 checkIdleAlts :: ModuleIdent -> [Alt] -> CheckState ()
 checkIdleAlts mid alts
    = do alts' <- dropUnless' isVarAlt alts
@@ -382,16 +409,16 @@
 
 -- Find function rules which are not together
 checkDeclOccurrences :: [Decl] -> CheckState ()
-checkDeclOccurrences decls = checkDO (mkIdent "") emptyEnv decls
+checkDeclOccurrences decls = checkDO (mkIdent "") Map.empty decls
  where
  checkDO prevId env [] = return ()
  checkDO prevId env ((FunctionDecl pos ident _):decls)
     = do c <- isConsId ident
 	 if not (c || prevId == ident)
-          then (maybe (checkDO ident (bindEnv ident pos env) decls)
+          then (maybe (checkDO ident (Map.insert ident pos env) decls)
 	              (\pos' -> genWarning' (rulesNotTogether ident pos')
 		                >> checkDO ident env decls)
-	              (lookupEnv ident env))
+	              (Map.lookup ident env))
 	  else checkDO ident env decls
  checkDO _ env (_:decls) 
     = checkDO (mkIdent "") env decls
@@ -399,15 +426,15 @@
 
 -- check import declarations for multiply imported modules
 checkImports :: [Decl] -> CheckState ()
-checkImports imps = checkImps emptyEnv imps
+checkImports imps = checkImps Map.empty imps
  where
  checkImps env [] = return ()
  checkImps env ((ImportDecl pos mid _ _ spec):imps)
     | mid /= preludeMIdent
-      = maybe (checkImps (bindEnv mid (fromImpSpec spec) env) imps)
+      = maybe (checkImps (Map.insert mid (fromImpSpec spec) env) imps)
               (\ishs -> checkImpSpec env pos mid ishs spec
 	                >>= (\env' -> checkImps env' imps))
-	      (lookupEnv mid env)
+	      (Map.lookup mid env)
     | otherwise
       = checkImps env imps
  checkImps env (_:imps) = checkImps env imps
@@ -417,21 +444,21 @@
  checkImpSpec env pos mid (is,hs) (Just (Importing _ is'))
     | null is && any (\i' -> notElem i' hs) is'
       = do genWarning' (multiplyImportedModule mid)
-	   return (bindEnv mid (is',hs) env)
+	   return (Map.insert mid (is',hs) env)
     | null iis
-      = return (bindEnv mid (is' ++ is,hs) env)
+      = return (Map.insert mid (is' ++ is,hs) env)
     | otherwise
       = do foldM' genWarning'
 		  (map ((multiplyImportedSymbol mid) . impName) iis)
-	   return (bindEnv mid (unionBy cmpImport is' is,hs) env)
+	   return (Map.insert mid (unionBy cmpImport is' is,hs) env)
   where iis = intersectBy cmpImport is' is
  checkImpSpec env pos mid (is,hs) (Just (Hiding _ hs'))
     | null ihs
-      = return (bindEnv mid (is,hs' ++ hs) env)
+      = return (Map.insert mid (is,hs' ++ hs) env)
     | otherwise
       = do foldM' genWarning' 
 		  (map ((multiplyHiddenSymbol mid) . impName) ihs)
-	   return (bindEnv mid (is,unionBy cmpImport hs' hs) env)
+	   return (Map.insert mid (is,unionBy cmpImport hs' hs) env)
   where ihs = intersectBy cmpImport hs' hs
 
  cmpImport (ImportTypeWith id1 cs1) (ImportTypeWith id2 cs2)
@@ -572,68 +599,29 @@
 		       _         -> info
 
 
--- Data type for representing the current state of generating warnings.
--- The monadic representation of the state allows the usage of monadic 
--- syntax (do expression) for dealing easier and safer with its
--- contents.
-data CheckState a = CheckState (CState () -> CState a)
-
-data CState a = CState {messages  :: [Message],
-			scope     :: ScopeEnv QualIdent IdInfo,
-			values    :: ValueEnv,
-			moduleId  :: ModuleIdent,
-			result    :: a
-		       }
-
 --
-emptyState :: CState ()
-emptyState = CState {messages  = [],
-		     scope     = ScopeEnv.new,
-		     values    = emptyTopEnv,
-		     moduleId  = mkMIdent [],
-		     result    = ()
-		    }
-
---
 modifyScope :: (ScopeEnv QualIdent IdInfo -> ScopeEnv QualIdent IdInfo)
-	       -> CState a -> CState a
+	       -> CState -> CState
 modifyScope f state = state{ scope = f (scope state) }
 
 
--- 'CheckState' is declared as an instance of 'Monad' to use its actions
--- in 'do' expressions
-instance Monad CheckState where
-
- -- (>>=) :: CheckState a -> (a -> CheckState b) -> CheckState b
- (CheckState f) >>= g 
-    = CheckState (\state -> let state'       = f state
-		                CheckState h = g (result state')
-		            in  h (state'{ result = () }))
-
- -- (>>) :: CheckState a -> CheckState b -> CheckState b
- a >> b = a >>= (\_ -> b)
-
- -- return :: a -> CheckState a
- return val = CheckState (\state -> state{ result = val })
-
-
 --
-genWarning :: Position -> (WarningType,String) -> CheckState ()
-genWarning pos (warnType,msg)
-   = CheckState (\state -> state{ messages = warnMsg:(messages state) })
- where warnMsg = message (Warning warnType) pos msg
+genWarning :: Position -> String -> CheckState ()
+genWarning pos msg
+   = modify (\state -> state{ messages = warnMsg:(messages state) })
+ where warnMsg = WarnMsg (Just pos) msg
  
-genWarning' :: (Position,WarningType,String) -> CheckState ()
-genWarning' (pos,warnType,msg)
-   = CheckState (\state -> state{ messages = warnMsg:(messages state) })
- where warnMsg = message (Warning warnType) pos msg 
+genWarning' :: (Position, String) -> CheckState ()
+genWarning' (pos, msg)
+   = modify (\state -> state{ messages = warnMsg:(messages state) })
+    where warnMsg = WarnMsg (Just pos) msg 
 
 --
 insertVar :: Ident -> CheckState ()
 insertVar id 
    | isAnnonId id = return ()
    | otherwise
-     = CheckState 
+     = modify 
          (\state -> modifyScope 
 	              (ScopeEnv.insert (commonId id) (VarInfo False)) state)
 
@@ -642,101 +630,90 @@
 insertTypeVar id
    | isAnnonId id = return ()
    | otherwise    
-     = CheckState 
+     = modify 
          (\state -> modifyScope 
 	              (ScopeEnv.insert (typeId id) (VarInfo False)) state)
 
 --
 insertConsId :: Ident -> CheckState ()
 insertConsId id
-   = CheckState 
+   = modify 
        (\state -> modifyScope (ScopeEnv.insert (commonId id) ConsInfo) state)
 
 --
 insertTypeConsId :: Ident -> CheckState ()
 insertTypeConsId id
-   = CheckState 
+   = modify 
        (\state -> modifyScope (ScopeEnv.insert (typeId id) ConsInfo) state)
 
 --
 isVarId :: Ident -> CheckState Bool
 isVarId id
-   = CheckState (\state -> state{ result = isVar state (commonId id) })
+   = gets (\state -> isVar state (commonId id))
 
 --
 isConsId :: Ident -> CheckState Bool
 isConsId id 
-   = CheckState (\state -> state{ result = isCons state (qualify id) })
+   = gets (\state -> isCons state (qualify id))
 
 --
 isQualConsId :: QualIdent -> CheckState Bool
 isQualConsId qid
-   = CheckState (\state -> state{ result = isCons state qid })
+   = gets (\state -> isCons state qid)
 
 --
 isShadowingVar :: Ident -> CheckState Bool
 isShadowingVar id 
-   = CheckState 
-       (\state -> state{ result = isShadowing state (commonId id) })
-
---
-isShadowingTypeVar :: Ident -> CheckState Bool
-isShadowingTypeVar id
-   = CheckState 
-       (\state -> state{ result = isShadowing state (typeId id) })
+   = gets (\state -> isShadowing state (commonId id))
 
 --
 visitId :: Ident -> CheckState ()
 visitId id 
-   = CheckState 
+   = modify 
        (\state -> modifyScope 
 	            (ScopeEnv.modify visitVariable (commonId id)) state)
 
 --
 visitTypeId :: Ident -> CheckState ()
 visitTypeId id 
-   = CheckState 
+   = modify 
        (\state -> modifyScope 
 	            (ScopeEnv.modify visitVariable (typeId id)) state)
 
 --
-isUnrefVar :: Ident -> CheckState Bool
-isUnrefVar id 
-   = CheckState (\state -> state{ result = isUnref state (commonId id) })
-
---
 isUnrefTypeVar :: Ident -> CheckState Bool
 isUnrefTypeVar id
-   = CheckState (\state -> state{ result = isUnref state (typeId id) })
+   = gets (\state -> isUnref state (typeId id))
 
 --
 returnUnrefVars :: CheckState [Ident]
 returnUnrefVars 
-   = CheckState (\state -> 
+   = gets (\state -> 
 	   	    let ids    = map fst (ScopeEnv.toLevelList (scope state))
                         unrefs = filter (isUnref state) ids
-	            in  state{ result = map unqualify unrefs })
+	            in  map unqualify unrefs )
 
 --
 addModuleId :: ModuleIdent -> CheckState ()
-addModuleId mid = CheckState (\state -> state{ moduleId = mid })
+addModuleId mid = modify (\state -> state{ moduleId = mid })
 
 --
-returnModuleId :: CheckState ModuleIdent
-returnModuleId = CheckState (\state -> state{ result = moduleId state })
 
+withScope :: CheckState a -> CheckState ()
+withScope m = beginScope >> m >> endScope
+
 --
 beginScope :: CheckState ()
-beginScope = CheckState (\state -> modifyScope ScopeEnv.beginScope state)
+beginScope = modify (\state -> modifyScope ScopeEnv.beginScope state)
 
 --
 endScope :: CheckState ()
-endScope = CheckState (\state -> modifyScope ScopeEnv.endScopeUp state)
+endScope = modify (\state -> modifyScope ScopeEnv.endScopeUp state)
 
 
 -- Adds the content of a value environment to the state
 addImportedValues :: ValueEnv -> CheckState ()
-addImportedValues vals = CheckState (\state -> state{ values = vals })
+addImportedValues vals = modify (\state -> state{ values = vals })
 
 --
 foldM' :: (a -> CheckState ()) -> [a] -> CheckState ()
@@ -768,36 +745,31 @@
 	if p then all' mpred xs else return False
 
 
--- Runs a 'CheckState' action and returns the list of messages
-run ::  CheckState a -> [Message]
-run (CheckState f)
-   = reverse (messages (f emptyState))
 
-
 -------------------------------------------------------------------------------
 
 --
-isShadowing :: CState a -> QualIdent -> Bool
+isShadowing :: CState -> QualIdent -> Bool
 isShadowing state qid
    = let sc = scope state
      in  maybe False isVariable (ScopeEnv.lookup qid sc)
 	 && ScopeEnv.level qid sc < ScopeEnv.currentLevel sc
 
 --
-isUnref :: CState a -> QualIdent -> Bool
+isUnref :: CState -> QualIdent -> Bool
 isUnref state qid 
    = let sc = scope state
      in  maybe False (not . variableVisited) (ScopeEnv.lookup qid sc)
          && ScopeEnv.level qid sc == ScopeEnv.currentLevel sc
 
 --
-isVar :: CState a -> QualIdent -> Bool
+isVar :: CState -> QualIdent -> Bool
 isVar state qid = maybe (isAnnonId (unqualify qid)) 
 	           isVariable 
 		   (ScopeEnv.lookup qid (scope state))
 
 --
-isCons :: CState a -> QualIdent -> Bool
+isCons :: CState -> QualIdent -> Bool
 isCons state qid = maybe (isImportedCons state qid)
 		         isConstructor
 			 (ScopeEnv.lookup qid (scope state))
@@ -831,56 +803,49 @@
 -------------------------------------------------------------------------------
 -- Warnings...
 
-unrefTypeVar :: Ident -> (Position,WarningType,String)
+unrefTypeVar :: Ident -> (Position, String)
 unrefTypeVar id = 
   (positionOfIdent id,
-   UnrefTypeVar,
    "unreferenced type variable \"" ++ show id ++ "\"")
 
-unrefVar :: Ident -> (Position,WarningType,String)
+unrefVar :: Ident -> (Position, String)
 unrefVar id = 
   (positionOfIdent id,
-   UnrefVar,
-   "unreferenced variable \"" ++ show id ++ "\"")
+   "unused declaration of variable \"" ++ show id ++ "\"")
 
-shadowingVar :: Ident -> (Position,WarningType,String)
+shadowingVar :: Ident -> (Position, String)
 shadowingVar id = 
   (positionOfIdent id,
-   ShadowingVar,
    "shadowing symbol \"" ++ show id ++ "\"")
 
-idleCaseAlts :: (WarningType,String)
-idleCaseAlts = (IdleCaseAlt,"idle case alternative(s)")
+idleCaseAlts :: String
+idleCaseAlts = "idle case alternative(s)"
 
-overlappingCaseAlt :: (WarningType,String)
-overlappingCaseAlt = (OverlapCase,"redundant overlapping case alternative")
+overlappingCaseAlt :: String
+overlappingCaseAlt = "redundant overlapping case alternative"
 
-rulesNotTogether :: Ident -> Position -> (Position,WarningType,String)
+rulesNotTogether :: Ident -> Position -> (Position, String)
 rulesNotTogether id pos
   = (positionOfIdent id,
-     RulesNotTogether,
      "rules for function \"" ++ show id ++ "\" "    
      ++ "are not together "
      ++ "(first occurrence at " 
      ++ show (line pos) ++ "." ++ show (column pos) ++ ")")
 
-multiplyImportedModule :: ModuleIdent -> (Position,WarningType,String)
+multiplyImportedModule :: ModuleIdent -> (Position, String)
 multiplyImportedModule mid 
   = (positionOfModuleIdent mid,
-     MultipleImportModule,
      "module \"" ++ show mid ++ "\" was imported more than once")
 
-multiplyImportedSymbol :: ModuleIdent -> Ident -> (Position,WarningType,String)
+multiplyImportedSymbol :: ModuleIdent -> Ident -> (Position, String)
 multiplyImportedSymbol mid ident
   = (positionOfIdent ident,
-     MultipleImportSymbol,
      "symbol \"" ++ show ident ++ "\" was imported from module \""
      ++ show mid ++ "\" more than once")
 
-multiplyHiddenSymbol :: ModuleIdent -> Ident -> (Position,WarningType,String)
+multiplyHiddenSymbol :: ModuleIdent -> Ident -> (Position, String)
 multiplyHiddenSymbol mid ident
   = (positionOfIdent ident,
-     MultipleHiding,
      "symbol \"" ++ show ident ++ "\" from module \"" ++ show mid
      ++ "\" was hidden more than once")
 
@@ -893,9 +858,6 @@
 tail_ alt []     = alt
 tail_ _   (_:xs) = xs
 
-head_ :: a -> [a] -> a
-head_ alt []    = alt
-head_ _   (x:_) = x
 
 --
 cmpListM :: Monad m => (a -> a -> m Bool) -> [a] -> [a] -> m Bool
diff --git a/src/cymake.hs b/src/cymake.hs
--- a/src/cymake.hs
+++ b/src/cymake.hs
@@ -16,13 +16,13 @@
 import Data.List
 import Data.Maybe
 import System.IO
-import System.Environment
-import System.Exit
+import System.Environment(getArgs, getProgName)
+import System.Exit(ExitCode(..), exitWith)
 import Control.Monad (unless)
 import Data.Char (isDigit)
 
 import GetOpt
-import CurryBuilder
+import CurryBuilder(buildCurry)
 import CurryCompilerOpts
 import CurryHtml
 
@@ -45,7 +45,7 @@
    | null errs' && not (elem Html opts)    = do
        unless (noVerb options') 
               (putStrLn  $ "This is cymake, version 0.1." 
-                         ++ filter isDigit "$Revision: 3624 $")
+                         ++ filter isDigit "$Revision: 3630 $")
        mapM_ (buildCurry options') files
    | null errs' = do
       let importFiles = nub $ importPaths opts'
