1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
------------------------------------------------------------------------------
--- Library with some functions for reading special tokens.
---
--- This library is included for backward compatibility.
--- You should use the library ReadNumeric which provides a better interface
--- for these functions.
---
--- @author Michael Hanus
--- @version January 2000
--- @category general
------------------------------------------------------------------------------

module Read ( readNat, readInt, readHex ) where

import Char ( isDigit )

--- Read a natural number in a string.
--- The string might contain leadings blanks and the the number is read
--- up to the first non-digit.
readNat :: String -> Int   -- result >= 0
readNat l = readNatPrefix (dropWhile (\c->c==' ') l) 0
 where
  readNatPrefix []     n = n
  readNatPrefix (c:cs) n =
    let oc = ord c
    in if oc>=ord '0' && oc<=ord '9' then readNatPrefix cs (n*10+oc-(ord '0'))
                                     else n


--- Read a (possibly negative) integer in a string.
--- The string might contain leadings blanks and the the integer is read
--- up to the first non-digit.
readInt :: String -> Int   -- result >= 0
readInt l = readIntPrefix (dropWhile (\c->c==' ') l)
 where
  readIntPrefix []     = 0
  readIntPrefix (c:cs) = if c=='-' then - (readNat cs) else readNat (c:cs)


--- Read a hexadecimal number in a string.
--- The string might contain leadings blanks and the the integer is read
--- up to the first non-heaxdecimal digit.
readHex :: String -> Int   -- result >= 0
readHex l = readHexPrefix (dropWhile (\c->c==' ') l) 0
 where
  readHexPrefix []     n = n
  readHexPrefix (c:cs) n =
    let cv = hex2int c
    in if cv>=0 then readHexPrefix cs (n*16+cv)
                else n

  hex2int c = if isDigit c then ord c - ord '0'
                           else if ord c >= ord 'A' && ord c <= ord 'F'
                                  then ord c - ord 'A' + 10
                                  else -1

-- end of library Read