[project @ 1998-12-02 13:17:09 by simonm]
[ghc-hetmet.git] / ghc / compiler / reader / PrefixSyn.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
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 module PrefixSyn (
12         RdrBinding(..),
13         RdrMatch(..),
14         SigConverter,
15         SrcFile,
16         SrcFun,
17         SrcLine,
18
19         readInteger
20     ) where
21
22 #include "HsVersions.h"
23
24 import HsSyn
25 import RdrHsSyn
26 import Util             ( panic )
27 import Char             ( isDigit, ord )
28
29
30 --UNUSED: type RdrId   = RdrName
31 type SrcLine = Int
32 type SrcFile = FAST_STRING
33 type SrcFun  = RdrName
34 \end{code}
35
36 \begin{code}
37 data RdrBinding
38   = RdrNullBind
39   | RdrAndBindings      RdrBinding RdrBinding
40
41   | RdrTyDecl           RdrNameTyDecl
42   | RdrFunctionBinding  SrcLine [RdrMatch]
43   | RdrPatternBinding   SrcLine [RdrMatch]
44   | RdrClassDecl        RdrNameClassDecl
45   | RdrInstDecl         RdrNameInstDecl
46   | RdrDefaultDecl      RdrNameDefaultDecl
47   | RdrForeignDecl      RdrNameForeignDecl
48
49                         -- signatures are mysterious; we can't
50                         -- tell if its a Sig or a ClassOpSig,
51                         -- so we just save the pieces:
52   | RdrSig              RdrNameSig
53
54 type SigConverter = RdrNameSig -> RdrNameSig
55 \end{code}
56
57 \begin{code}
58 data RdrMatch
59   = RdrMatch_NoGuard
60              SrcLine SrcFun
61              RdrNamePat
62              RdrNameHsExpr
63              RdrBinding
64
65   | RdrMatch_Guards
66              SrcLine SrcFun
67              RdrNamePat
68              [([RdrNameStmt], RdrNameHsExpr)]
69              -- (guard,         expr)
70              RdrBinding
71 \end{code}
72
73 Unscramble strings representing oct/dec/hex integer literals:
74 \begin{code}
75 readInteger :: String -> Integer
76
77 readInteger ('-' : xs)       = - (readInteger xs)
78 readInteger ('0' : 'o' : xs) = chk (stoo 0 xs)
79 readInteger ('0' : 'x' : xs) = chk (stox 0 xs)
80 readInteger ['0']            = 0    -- efficiency shortcut?
81 readInteger ['1']            = 1    -- ditto?
82 readInteger xs               = chk (stoi 0 xs)
83
84 chk (i, "")   = i
85 chk (i, junk) = panic ("readInteger: junk after reading:"++junk)
86
87 stoo, stoi, stox :: Integer -> String -> (Integer, String)
88
89 stoo a (c:cs) | is_oct c  = stoo (a*8 + ord_ c - ord_0) cs
90 stoo a cs                 = (a, cs)
91
92 stoi a (c:cs) | isDigit c = stoi (a*10 + ord_ c - ord_0) cs
93 stoi a cs                 = (a, cs)
94
95 stox a (c:cs) | isDigit c = stox (a_16_ord_c - ord_0)      cs
96               | is_hex  c = stox (a_16_ord_c - ord_a + 10) cs
97               | is_Hex  c = stox (a_16_ord_c - ord_A + 10) cs
98               where a_16_ord_c = a*16 + ord_ c
99 stox a cs = (a, cs)
100
101 is_oct c = c >= '0' && c <= '7'
102 is_hex c = c >= 'a' && c <= 'f'
103 is_Hex c = c >= 'A' && c <= 'F'
104
105 ord_ c = toInteger (ord c)
106
107 ord_0, ord_a, ord_A :: Integer
108 ord_0 = ord_ '0'; ord_a = ord_ 'a'; ord_A = ord_ 'A'
109 \end{code}