[project @ 1996-01-08 20:28:12 by partain]
[ghc-hetmet.git] / ghc / compiler / reader / PrefixSyn.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
3 %
4 \section[PrefixSyn]{``Prefix-form'' syntax}
5
6 This module contains an algebraic data type into which a prefix form
7 string from the current Haskell parser is converted.  Given in an
8 order that follows the \tr{Prefix_Form} document.
9
10 \begin{code}
11 #include "HsVersions.h"
12
13 module PrefixSyn (
14         RdrBinding(..),
15         RdrId(..),
16         RdrMatch(..),
17         RdrTySigPragmas(..),
18         SigConverter(..),
19         SrcFile(..),
20         SrcFun(..),
21         SrcLine(..),
22
23         readInteger
24     ) where
25
26 import AbsSyn
27 import ProtoName        ( ProtoName(..) ) -- .. is for pragmas only
28 import Outputable
29 import Util             -- pragmas only
30
31 type RdrId   = ProtoName
32 type SrcLine = Int
33 type SrcFile = FAST_STRING
34 type SrcFun  = FAST_STRING
35 \end{code}
36
37 \begin{code}
38 data RdrBinding
39   = RdrNullBind
40   | RdrAndBindings      RdrBinding RdrBinding
41
42   | RdrTyData           ProtoNameTyDecl
43   | RdrTySynonym        ProtoNameTyDecl
44   | RdrFunctionBinding  SrcLine [RdrMatch]
45   | RdrPatternBinding   SrcLine [RdrMatch]
46   | RdrClassDecl        ProtoNameClassDecl
47   | RdrInstDecl         ( FAST_STRING{-original  module's name-} ->
48                           FAST_STRING{-informant module's name-} ->
49                           Bool{-from here?-} ->
50                           ProtoNameInstDecl )
51   | RdrDefaultDecl      ProtoNameDefaultDecl
52   | RdrIfaceImportDecl  IfaceImportDecl
53
54                         -- signatures are mysterious; we can't
55                         -- tell if its a Sig or a ClassOpSig,
56                         -- so we just save the pieces:
57   | RdrTySig            [ProtoName]         -- vars getting sigs
58                         ProtoNamePolyType   -- the type
59                         RdrTySigPragmas     -- val/class-op pragmas
60                         SrcLoc
61
62   -- user pragmas come in in a Sig-ish way/form...
63   | RdrSpecValSig       [ProtoNameSig]
64   | RdrInlineValSig     ProtoNameSig
65   | RdrDeforestSig      ProtoNameSig
66   | RdrMagicUnfoldingSig ProtoNameSig
67   | RdrSpecInstSig      ProtoNameSpecialisedInstanceSig
68   | RdrAbstractTypeSig  ProtoNameDataTypeSig
69   | RdrSpecDataSig      ProtoNameDataTypeSig
70
71 data RdrTySigPragmas
72   = RdrNoPragma
73   | RdrGenPragmas       ProtoNameGenPragmas
74   | RdrClassOpPragmas   ProtoNameClassOpPragmas
75
76 type SigConverter = RdrBinding {- a RdrTySig... -} -> [ProtoNameSig]
77 \end{code}
78
79 \begin{code}
80 data RdrMatch
81   = RdrMatch SrcLine SrcFun ProtoNamePat [(ProtoNameExpr, ProtoNameExpr)] RdrBinding
82                                        -- (guard,         expr)
83 \end{code}
84
85 Unscramble strings representing oct/dec/hex integer literals:
86 \begin{code}
87 readInteger :: String -> Integer
88
89 readInteger ('-' : xs)       = - (readInteger xs)
90 readInteger ('0' : 'o' : xs) = chk (stoo 0 xs)
91 readInteger ('0' : 'x' : xs) = chk (stox 0 xs)
92 readInteger ['0']            = 0    -- efficiency shortcut?
93 readInteger ['1']            = 1    -- ditto?
94 readInteger xs               = chk (stoi 0 xs)
95
96 chk (i, "")   = i
97 chk (i, junk) = panic ("readInteger: junk after reading:"++junk)
98
99 stoo, stoi, stox :: Integer -> String -> (Integer, String)
100
101 stoo a (c:cs) | is_oct c  = stoo (a*8 + ord_ c - ord_0) cs
102 stoo a cs                 = (a, cs)
103
104 stoi a (c:cs) | isDigit c = stoi (a*10 + ord_ c - ord_0) cs
105 stoi a cs                 = (a, cs)
106
107 stox a (c:cs) | isDigit c = stox (a_16_ord_c - ord_0)      cs
108               | is_hex  c = stox (a_16_ord_c - ord_a + 10) cs
109               | is_Hex  c = stox (a_16_ord_c - ord_A + 10) cs
110               where a_16_ord_c = a*16 + ord_ c
111 stox a cs = (a, cs)
112
113 is_oct c = c >= '0' && c <= '7'
114 is_hex c = c >= 'a' && c <= 'f'
115 is_Hex c = c >= 'A' && c <= 'F'
116
117 ord_ c = toInteger (ord c)
118
119 ord_0, ord_a, ord_A :: Integer
120 ord_0 = ord_ '0'; ord_a = ord_ 'a'; ord_A = ord_ 'A'
121 \end{code}