1(*
2    Title:      Standard Basis Library: Int32 Structure
3    Author:     Vesa Karvonen
4    Copyright   David Matthews 1999, 2016
5                Vesa Karvonen 2007
6
7        This library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Lesser General Public
9    License version 2.1 as published by the Free Software Foundation.
10
11    This library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with this library; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19*)
20
21(*
22  This is a hacked version of Int32 - a 32bit Int implementation for
23  PolyML 5. It's neither well tested nor efficiently implemented.
24*)
25
26structure Int32 :> INTEGER =
27struct
28   open LargeInt (* We need LargeInt on 32-bits. *)
29
30   val precision:Int.int = 32
31   val minInt = ~(IntInf.<< (1, Word.fromInt (Int.- (precision, 1))))
32   val maxInt = ~1-minInt
33
34   fun check i =
35       if i < minInt orelse maxInt < i
36       then raise Overflow
37       else i
38
39   val precision = SOME precision
40   val minInt = SOME minInt
41   val maxInt = SOME maxInt
42
43   val fromLarge = check o fromLarge
44   val fromInt = check o fromInt
45
46   val ~ = check o ~
47   val op * = check o op *
48   val op + = check o op +
49   val op - = check o op -
50   val op div = check o op div
51   val op mod = check o op mod
52   val quot = check o quot
53   val rem = check o rem
54
55   val abs = check o abs
56   fun scan' r g s =
57       case scan r g s
58        of NONE => NONE
59         | SOME (i, s) => SOME (check i, s)
60   val scan = scan'
61   val fromString = Option.map check o fromString
62end;
63
64local
65   fun convInt s = let
66      val radix =
67      if String.size s >= 3 andalso String.substring(s, 0, 2) = "0x"
68         orelse String.size s >= 4 andalso String.substring(s, 0, 3) = "~0x"
69      then StringCvt.HEX else StringCvt.DEC
70   in
71      case StringCvt.scanString (Int32.scan radix) s of
72     NONE => raise RunCall.Conversion "Invalid integer constant"
73       | SOME res => res
74   end
75   fun pretty _ _ x = PolyML.PrettyString (Int32.toString x)
76in
77   val () = RunCall.addOverload convInt "convInt"
78   val () = PolyML.addPrettyPrinter pretty
79end;
80
81val () = RunCall.addOverload Int32.~ "~";
82val () = RunCall.addOverload Int32.+ "+";
83val () = RunCall.addOverload Int32.- "-";
84val () = RunCall.addOverload Int32.* "*";
85val () = RunCall.addOverload Int32.div "div";
86val () = RunCall.addOverload Int32.mod "mod";
87val () = RunCall.addOverload Int32.< "<";
88val () = RunCall.addOverload Int32.> ">";
89val () = RunCall.addOverload Int32.<= "<=";
90val () = RunCall.addOverload Int32.>= ">=";
91val () = RunCall.addOverload Int32.abs "abs";
92