File: word.sml

package info (click to toggle)
mlton 20061107-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 27,828 kB
  • ctags: 61,118
  • sloc: ansic: 11,446; makefile: 1,339; sh: 1,160; lisp: 900; pascal: 256; asm: 97
file content (159 lines) | stat: -rw-r--r-- 5,479 bytes parent folder | download
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
(* Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
 *    Jagannathan, and Stephen Weeks.
 * Copyright (C) 1997-2000 NEC Research Institute.
 *
 * MLton is released under a BSD-style license.
 * See the file MLton-LICENSE for details.
 *)

functor Word (W: PRE_WORD_EXTRA): WORD_EXTRA =
struct

open W
structure PW = Primitive.Word

val detectOverflow = Primitive.detectOverflow

(* These are overriden in patch.sml after int-inf.sml has been defined. *)
val toLargeInt: word -> LargeInt.int = fn _ => raise Fail "toLargeInt"
val toLargeIntX: word -> LargeInt.int = fn _ => raise Fail "toLargeIntX"
val fromLargeInt: LargeInt.int -> word = fn _ => raise Fail "fromLargeInt"

val wordSizeWord: Word.word = PW.fromInt wordSize
val wordSizeMinusOneWord: Word.word = PW.fromInt (Int.-? (wordSize, 1))
val zero: word = fromInt 0

val toLargeWord = toLarge
val toLargeWordX = toLargeX
val fromLargeWord = fromLarge

fun toInt w =
   if detectOverflow
      andalso Int.>= (wordSize, Int.precision')
      andalso w > fromInt Int.maxInt'
      then raise Overflow
   else W.toInt w
                      
fun toIntX w =
  if detectOverflow
     andalso Int.> (wordSize, Int.precision')
     andalso fromInt Int.maxInt' < w
     andalso w < fromInt Int.minInt'
     then raise Overflow
  else W.toIntX w

local
   fun make f (w, w') =
      if Primitive.safe andalso w' = zero
         then raise Div
      else f (w, w')
in
   val op div = make (op div)
   val op mod = make (op mod)
end

fun << (i, n) 
  = if PW.>=(n ,wordSizeWord)
      then zero
      else W.<<(i, n)

fun >> (i, n) 
  = if PW.>=(n, wordSizeWord)
      then zero
      else W.>>(i, n)

fun ~>> (i, n) 
  = if PW.<(n, wordSizeWord)
      then W.~>>(i, n)
      else W.~>>(i, wordSizeMinusOneWord)

val {compare, min, max} = Util.makeCompare(op <)

fun fmt radix (w: word): string =
   let val radix = fromInt (StringCvt.radixToInt radix)
      fun loop (q, chars) =
         let val chars = StringCvt.digitToChar (toInt (q mod radix)) :: chars
            val q = q div radix
         in if q = zero
               then String0.implode chars
            else loop (q, chars)
         end
   in loop (w, [])
   end

val toString = fmt StringCvt.HEX

fun scan radix reader state =
   let
      val state = StringCvt.skipWS reader state
      val charToDigit = StringCvt.charToDigit radix
      val radixWord = fromInt (StringCvt.radixToInt radix)
      fun finishNum (state, n) =
         case reader state of
            NONE => SOME (n, state)
          | SOME (c, state') =>
               case charToDigit c of
                  NONE => SOME (n, state)
                | SOME n' =>
                     let val n'' = n * radixWord
                     in if n'' div radixWord = n
                           then let val n' = fromInt n'
                                   val n''' = n'' + n'
                                in if n''' >= n''
                                      then finishNum (state', n''')
                                   else raise Overflow
                                end
                        else raise Overflow
                     end
      fun num state = finishNum (state, zero)
   in
      case reader state of
         NONE => NONE
       | SOME (c, state) =>
            case c of
               #"0" =>
               (case reader state of
                   NONE => SOME (zero, state)
                 | SOME (c, state') =>
                      case c of
                         #"w" => (case radix of
                                     StringCvt.HEX =>
                                        (case reader state' of
                                            NONE =>
                                               (* the #"w" was not followed by
                                                * an #"X" or #"x", therefore we
                                                * return 0 *)
                                               SOME (zero, state)
                                          | SOME (c, state) =>
                                               (case c of
                                                   #"x" => num state
                                                 | #"X" => num state
                                                 | _ =>
                                                 (* the #"w" was not followed by
                                                  * an #"X" or #"x", therefore we
                                                  * return 0 *)
                                                      SOME (zero, state)))
                                   | _ => num state')
                       | #"x" => (case radix of
                                     StringCvt.HEX => num state'
                                   | _ => NONE)
                       | #"X" => (case radix of
                                     StringCvt.HEX => num state'
                                   | _ => NONE)
                       | _ => num state)
             | _ => (case charToDigit c of
                        NONE => NONE
                      | SOME n => finishNum (state, fromInt n))
   end

val fromString = StringCvt.scanString (scan StringCvt.HEX)

end

structure Word8 = Word (Primitive.Word8)
structure Word16 = Word (Primitive.Word16)
structure Word32 = Word (Primitive.Word32)
structure Word64 = Word (Primitive.Word64)
structure Word = Word32
structure WordGlobal: WORD_GLOBAL = Word
open WordGlobal