]> Joshua Wise's Git repositories - snipe.git/blob - util/word32.sml
c25c2855c224dc37647bf0c7b64b666a910d876a
[snipe.git] / util / word32.sml
1 (* L1 Compiler
2  * Utilities for signed modular arithmetic
3  * Author: Frank Pfenning
4  *)
5
6 (*
7  * There are two useful structure in the SML Basis Library
8  * Int32, with 2's complement arithmetic,
9  *        but it raises Overflow instead of doing modular arithmetic
10  * Word32, with unsigned modular arithmetic
11  *
12  * This structure implements some signed operations on Word32
13  *)
14
15 signature WORD32_SIGNED =
16 sig
17
18   val TMAX : Word32.word        (* largest signed positive word, 2^31-1  *)
19   val TMIN : Word32.word        (* smallest signed negative word -2^31 *)
20   val ZERO : Word32.word        (* 0 *)
21   val fromString : string -> Word32.word option (* parse from string, no sign *)
22                                 (* raises Overflow if not 0 <= n < 2^32 *)
23   val toString : Word32.word -> string (* print to string, with sign *)
24   val abs : Word32.word -> Word32.word
25   val adiv : Word32.word * Word32.word -> Word32.word
26   val amod : Word32.word * Word32.word -> Word32.word
27   val lt : Word32.word * Word32.word -> bool
28   val gt : Word32.word * Word32.word -> bool
29   val le : Word32.word * Word32.word -> bool
30   val ge : Word32.word * Word32.word -> bool
31 end
32
33 structure Word32Signed :> WORD32_SIGNED =
34 struct
35
36   val TMIN = Word32.<<(Word32.fromInt(1), Word.fromInt(Word32.wordSize-1))
37   val TMAX = Word32.-(TMIN, Word32.fromInt(1))
38   val ZERO = Word32.fromInt(0)
39   fun neg w = Word32.>(w, TMAX)
40
41   (* fromString does not allow leading "-" *)
42   fun fromString (str) =
43          (* scanString might also raise Overflow *)
44          StringCvt.scanString (Word32.scan StringCvt.DEC) str
45
46   fun toString (w) =
47       if neg w
48          then "-0x" ^ Word32.fmt StringCvt.HEX (Word32.~(w))
49       else "0x" ^ Word32.fmt StringCvt.HEX w
50
51   fun toInt32 w = Int32.fromLarge (Word32.toLargeInt w)
52   fun fromInt32 i = Word32.fromLargeInt (Int32.toLarge i)
53
54   fun abs w = if neg w then Word32.~ (w) else w
55   fun adiv (a,b) = fromInt32 (Int32.div (toInt32 a, toInt32 b))
56   fun amod (a,b) = fromInt32 (Int32.mod (toInt32 a, if neg a andalso neg b then toInt32 b
57                                                     else if neg b then toInt32 (abs b)
58                                                     else if neg a then toInt32 (Word32.~ b)
59                                                     else toInt32 b))
60
61   fun lt (a,b) = Int32.compare (toInt32 a, toInt32 b) = LESS
62   fun gt (a,b) = Int32.compare (toInt32 a, toInt32 b) = GREATER
63   fun le (a,b) = case Int32.compare (toInt32 a, toInt32 b) of LESS => true | EQUAL => true | _ => false
64   fun ge (a,b) = case Int32.compare (toInt32 a, toInt32 b) of GREATER => true | EQUAL => true | _ => false
65
66 end
This page took 0.030824 seconds and 4 git commands to generate.