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