<> <> DIRECTORY Basics, Convert, IntStuff, Rope, RuntimeError; IntStuffImpl: CEDAR PROGRAM IMPORTS Convert, IntStuff, Rope, RuntimeError EXPORTS IntStuff = BEGIN OPEN IntStuff; ToRope: PUBLIC PROC [t: EINT, base: [2..36] _ 10] RETURNS [rope: ROPE] ~ TRUSTED { neg: BOOL ~ t.Negative; tweak: BOOL _ neg; IF neg THEN t _ negOne.Sub[t]; rope _ NIL; WHILE t#zero DO {quot: EINT; rem: CARDINAL; [quot, rem] _ TDivMod[t, base]; IF tweak THEN { rem _ rem+1; IF rem=base THEN rem _ 0 ELSE tweak _ FALSE}; rope _ Rope.FromChar[IF rem<10 THEN '0 + rem ELSE 'A + (rem-10)].Concat[rope]; t _ quot; }ENDLOOP; IF tweak THEN rope _ Rope.Concat["1", rope] ELSE IF rope=NIL THEN rope _ "0"; IF neg THEN rope _ Rope.Concat["-", rope]; RETURN}; TDivMod: PROC [num: EINT, den: CARDINAL] RETURNS [quot: EINT, rem: CARDINAL] ~ TRUSTED { h: DM ~ DivMod[num.hi, den]; n2: INT ~ INT[num.lo] + INT[b1]*h.rem; l: DM ~ DivMod[n2, den]; quot _ IE[l.quot].Add[[loShort[lo: 0, hi: h.quot]]]; rem _ l.rem; RETURN}; DM: TYPE ~ RECORD [quot: INT, rem: CARDINAL]; DivMod: PROC [num: INT, den: CARDINAL] RETURNS [dm: DM] ~ { dm.quot _ num/den; num _ num - dm.quot*den; IF num<0 THEN {num _ num + den; dm.quot _ dm.quot-1}; IF num NOT IN [0 .. den) THEN ERROR; dm.rem _ num; RETURN}; FromRope: PUBLIC PROC [r: ROPE, base: [2..36] _ 10] RETURNS [t: EINT] ~ TRUSTED { rlen: INT ~ r.Length; pos: BOOL ~ r.Fetch[0] # '-; lim: EINT ~ TDivMod[firstEINT, base].quot; i: INT _ IF pos THEN 0 ELSE 1; t _ zero; FOR i _ i, i+1 WHILE i < rlen DO c: CHAR ~ r.Fetch[i]; d: CARDINAL; IF c IN ['0 .. '9] THEN d _ c - '0 ELSE IF c IN ['A .. 'Z] THEN d _ (c-'A) + 10 ELSE IF c IN ['a .. 'z] THEN d _ (c-'a) + 10 ELSE d _ 37; IF d >= base THEN Convert.Error[syntax, i]; IF t.Compare[lim] = less THEN Convert.Error[overflow, i]; t _ MulSC[t, base].SubI[d]; IF t.Positive THEN Convert.Error[overflow, i]; ENDLOOP; IF pos THEN {IF t#firstEINT THEN t _ t.Neg ELSE Convert.Error[overflow, i-1]}; RETURN}; MulI: PUBLIC PROC [a: EINT, b: INT] RETURNS [EINT] ~ { l: EINT ~ MulSC[a, Basics.LowHalf[b]]; h: EINT ~ MulSI[a, LOOPHOLE[Basics.HighHalf[b]]]; hi: INT ~ h.EI; RETURN l.Add[[loShort[lo: 0, hi: hi]]]}; MulSI: PROC [a: EINT, b: INTEGER] RETURNS [c: EINT] ~ { m: INT ~ INT[a.lo]*INT[b]; RETURN [[loShort[lo: Basics.LowHalf[m], hi: HighInt[m] + a.hi*b]]]}; MulSC: PROC [a: EINT, b: CARDINAL] RETURNS [c: EINT] ~ { m: CARD ~ a.lo.LONG*b; RETURN [[loShort[lo: Basics.LowHalf[m], hi: INT[Basics.HighHalf[m]] + a.hi*b]]]}; ShiftInterval: PUBLIC PROC [i: Interval, o.min _ o.max _ }; ClipShiftInterval: PUBLIC PROC [i: Interval, o.min _ o.max _ }; NClipI: PROC [t: EINT] RETURNS [INT] ~ {RETURN t.ClipI}; NAddI: PROC [a: EINT, b: INT] RETURNS [EINT] ~ {RETURN a.AddI[b]}; NISub: PROC [a, b: INT] RETURNS [EINT] ~ {RETURN ISub[a, b]}; NSucc: PROC [t: EINT] RETURNS [EINT] ~ {RETURN t.Succ}; END.