]>
Commit | Line | Data |
---|---|---|
12aa4087 JW |
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 | |
5c79bb68 | 17 | |
12aa4087 JW |
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 *) | |
5c79bb68 JW |
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 | |
12aa4087 JW |
31 | end |
32 | ||
33 | structure Word32Signed :> WORD32_SIGNED = | |
34 | struct | |
5c79bb68 | 35 | |
12aa4087 JW |
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 | |
5c79bb68 JW |
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 | ||
12aa4087 | 66 | end |