<> <> <<>> DIRECTORY Rope, IO, Basics, Atom, Convert, AlgebraClasses, MathConstructors, Bools, Ints; IntsImpl: CEDAR PROGRAM IMPORTS IO, Convert, Rope, AlgebraClasses, MathConstructors EXPORTS Ints = BEGIN OPEN Ints, Convert, AC: AlgebraClasses; <> IntsError: PUBLIC SIGNAL [reason: ATOM _ $Unspecified] = CODE; bitsPerWord: CARDINAL = Basics.bitsPerWord; CARD: TYPE = LONG CARDINAL; ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; Object: TYPE = AC.Object; Method: TYPE = AC.Method; TypeError: PUBLIC ERROR [message: ATOM _ $Unspecified] = CODE; <> PrintName: PUBLIC AC.ToRopeOp = { RETURN["Ints"]; }; ShortPrintName: PUBLIC AC.ToRopeOp = { RETURN["Z"]; }; Characteristic: PUBLIC AC.StructureRankOp = { RETURN[ 0 ] }; <> Recast: PUBLIC AC.BinaryOp = { IF NOT AC.StructureEqual[firstArg.class, Ints] THEN RETURN[NIL] ELSE RETURN[firstArg]; }; CanRecast: PUBLIC AC.BinaryPredicate = { firstArgStructure: Object _ IF firstArg.flavor = StructureElement THEN firstArg.class ELSE IF firstArg.flavor = Structure THEN firstArg ELSE ERROR; SELECT TRUE FROM AC.StructureEqual[firstArgStructure, Ints] => RETURN[TRUE]; ENDCASE; RETURN[FALSE]; }; ToExpr: PUBLIC AC.ToExprOp = { data: IntData _ NARROW[in.data]; RETURN[MathConstructors.MakeInt[Convert.RopeFromInt[data^] ] ]; }; LegalFirstChar: PUBLIC AC.LegalFirstCharOp = { SELECT char FROM IN ['0..'9] => RETURN[TRUE]; ENDCASE; RETURN[FALSE]; }; Read: PUBLIC AC.ReadOp ~ { RETURN[NEW[AC.ObjectRec _ [ flavor: StructureElement, class: Ints, data: NEW[INT _ IO.GetInt[in] ] ] ] ]; }; FromRope: PUBLIC AC.FromRopeOp = { stream: IO.STREAM _ IO.RIS[in]; RETURN[ Read[stream] ]; }; ToRope: PUBLIC AC.ToRopeOp = { data: IntData _ NARROW[in.data]; RETURN[ Convert.RopeFromInt[data^] ]; }; Write: PUBLIC AC.WriteOp = { IO.PutRope[ stream, ToRope[in] ] }; FromINT: PUBLIC AC.FromINTOp = { RETURN[NEW[AC.ObjectRec _ [ flavor: StructureElement, class: Ints, data: NEW[INT _ in] ] ] ]; }; ToINT: PUBLIC PROC [int: Int] RETURNS [INT] = { data: IntData _ NARROW[int.data]; RETURN[data^]; }; <> Zero: PUBLIC AC.NullaryOp = { RETURN[ IntZero ] }; One: PUBLIC AC.NullaryOp = { RETURN[ IntOne ] }; Add: PUBLIC AC.BinaryOp ~ { firstData: IntData _ NARROW[firstArg.data]; secondData: IntData _ NARROW[secondArg.data]; RETURN[NEW[AC.ObjectRec _ [ flavor: StructureElement, class: Ints, data: NEW[INT _ firstData^ + secondData^ ] ] ] ]; }; Negate: PUBLIC AC.UnaryOp ~ { data: IntData _ NARROW[arg.data]; RETURN[NEW[AC.ObjectRec _ [ flavor: StructureElement, class: Ints, data: NEW[INT _ - data^ ] ] ] ]; }; Subtract: PUBLIC AC.BinaryOp ~ { firstData: IntData _ NARROW[firstArg.data]; secondData: IntData _ NARROW[secondArg.data]; RETURN[NEW[AC.ObjectRec _ [ flavor: StructureElement, class: Ints, data: NEW[INT _ firstData^ - secondData^ ] ] ] ]; }; Multiply: PUBLIC AC.BinaryOp ~ { firstData: IntData _ NARROW[firstArg.data]; secondData: IntData _ NARROW[secondArg.data]; RETURN[NEW[AC.ObjectRec _ [ flavor: StructureElement, class: Ints, data: NEW[INT _ firstData^ * secondData^ ] ] ] ]; }; ObjectAndIntDesired: PUBLIC AC.UnaryToListOp ~ { RETURN[ LIST[arg, Ints] ]; -- arg assumed to be a Structure }; Power: PUBLIC AC.BinaryOp ~ { -- this simple algorithm is Structure independent power: INT _ ToINT[secondArg]; structure: Object _ firstArg.class; one: Object _ AC.ApplyLkpNoRecastObject[$one, structure, LIST[structure] ]; productMethod: Method _ AC.LookupMethodInStructure[$product, structure]; IF power < 0 THEN { invertMethod: Method _ AC.LookupMethodInStructure[$invert, structure]; temp: Object; IF invertMethod = NIL THEN ERROR; temp _ Power[firstArg, FromINT[ABS[power] ] ]; RETURN[AC.ApplyNoLkpNoRecastObject[invertMethod, LIST[temp] ] ]; }; IF power = 0 THEN RETURN[one]; result _ firstArg; FOR i:INT IN [2..power] DO result _ AC.ApplyNoLkpNoRecastObject[productMethod, LIST[firstArg, result] ]; ENDLOOP; }; Remainder: PUBLIC AC.BinaryOp ~ { firstData: IntData _ NARROW[firstArg.data]; secondData: IntData _ NARROW[secondArg.data]; RETURN[NEW[AC.ObjectRec _ [ flavor: StructureElement, class: Ints, data: NEW[INT _ firstData^ MOD secondData^ ] ] ] ]; }; Gcd: PUBLIC AC.BinaryOp ~ { gcd: Int; IF Equal[firstArg, IntZero] AND Equal[secondArg, IntZero] THEN gcd _ IntZero ELSE { r: Int; UNTIL Equal[secondArg, IntZero] DO r _ Remainder[firstArg, secondArg]; firstArg _ secondArg; secondArg _ r; ENDLOOP; gcd _ Abs[firstArg]; }; RETURN[gcd ]; }; Totient: PUBLIC AC.UnaryOp ~ { totient: INT _ 0; IF Equal[arg, IntZero] THEN RETURN[IntZero]; FOR i:INT IN [1.. ToINT[arg] ] DO IF ToINT[Gcd[FromINT[i], arg] ] = 1 THEN totient _ totient + 1; ENDLOOP; RETURN[FromINT[totient] ]; }; Divides: PUBLIC AC.BinaryOp ~ { <> first: INT _ ToINT[firstArg]; second: INT _ ToINT[secondArg]; IF first MOD second = 0 THEN RETURN[FromINT[1] ] ELSE RETURN[FromINT[0] ]; }; Paren: PUBLIC AC.UnaryOp ~ { RETURN[NEW[AC.ObjectRec _ [ flavor: StructureElement, class: Ints, data: arg.data ] ] ]; }; <> Sign: PUBLIC AC.CompareToZeroOp = { data: IntData _ NARROW[arg.data]; SELECT data^ FROM < 0 => RETURN[less]; = 0 => RETURN[equal]; ENDCASE => RETURN[greater]; }; <<>> Abs: PUBLIC AC.UnaryOp ~ { data: IntData _ NARROW[arg.data]; RETURN[NEW[AC.ObjectRec _ [ flavor: StructureElement, class: Ints, data: NEW[INT _ ABS[data^] ] ] ] ]; }; Compare: PUBLIC AC.BinaryCompareOp ~ { firstData: IntData _ NARROW[firstArg.data]; secondData: IntData _ NARROW[secondArg.data]; SELECT firstData^ FROM < secondData^ => RETURN[less]; = secondData^ => RETURN[equal]; ENDCASE => RETURN[greater]; }; Equal: PUBLIC AC.BinaryPredicate ~ { firstData: IntData _ NARROW[firstArg.data]; secondData: IntData _ NARROW[secondArg.data]; RETURN[ firstData^ = secondData^ ] }; TestLoop: PUBLIC AC.UnaryOp ~ { firstData: IntData _ NARROW[arg.data]; num: INT _ firstData^; string: ROPE _ "298749823749823749"; c: CHAR; FOR i:INT IN [1..num] DO c _ Rope.Fetch[string, 3]; ENDLOOP; RETURN[ FromRope[ Rope.FromChar[c]] ] }; <> IntsDesired: PUBLIC AC.UnaryToListOp ~ { <> RETURN[ LIST[Ints] ]; }; <> <> <> <> <> <> <> <> <<>> <> <<>> <> <> <> <> <> <> <> <<>> <> <> <> <> <<>> <> <> <> <<>> <> <<>> <> <> <> <> <<>> <> <> <> <> <> <<>> <<] ];>> <<>> intsClass: Object _ AC.MakeClass["intsClass", NIL, NIL]; Ints: PUBLIC Object _ AC.MakeStructure["Ints", intsClass, NIL]; IntOne: Int _ FromINT[1]; -- Do after Ints set, so structure field gets nonNIL value IntZero: Int _ FromINT[0]; categoryMethod: Method _ AC.MakeMethod[Value, FALSE, NEW[AC.Category _ ring], NIL, "category"]; groundStructureMethod: Method _ AC.MakeMethod[Value, FALSE, NIL, NIL, "groundStructure"]; shortPrintNameMethod: Method _ AC.MakeMethod[ToRopeOp, FALSE, NEW[AC.ToRopeOp _ ShortPrintName], NIL, "shortPrintName"]; recastMethod: Method _ AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp _ Recast], NIL, "recast"]; canRecastMethod: Method _ AC.MakeMethod[BinaryPredicate, TRUE, NEW[AC.BinaryPredicate _ CanRecast], NIL, "canRecast"]; toExprMethod: Method _ AC.MakeMethod[ToExprOp, FALSE, NEW[AC.ToExprOp _ ToExpr], NEW[AC.UnaryToListOp _ IntsDesired], "toExpr"]; legalFirstCharMethod: Method _ AC.MakeMethod[LegalFirstCharOp, FALSE, NEW[AC.LegalFirstCharOp _ LegalFirstChar], NIL, "legalFirstChar"]; readMethod: Method _ AC.MakeMethod[ReadOp, FALSE, NEW[AC.ReadOp _ Read], NIL, "read"]; fromRopeMethod: Method _ AC.MakeMethod[FromRopeOp, TRUE, NEW[AC.FromRopeOp _ FromRope], NIL, "fromRope"]; toRopeMethod: Method _ AC.MakeMethod[ToRopeOp, FALSE, NEW[AC.ToRopeOp _ ToRope], NIL, "toRope"]; fromINTMethod: Method _ AC.MakeMethod[FromINTOp, FALSE, NEW[AC.FromINTOp _ FromINT], NIL, "fromINT"]; integerMethod: Method _ AC.MakeMethod[FromRopeOp, FALSE, NEW[AC.FromRopeOp _ FromRope], NIL, "integer"]; zeroMethod: Method _ AC.MakeMethod[NullaryOp, FALSE, NEW[AC.NullaryOp _ Zero], NIL, "zero"]; oneMethod: Method _ AC.MakeMethod[NullaryOp, FALSE, NEW[AC.NullaryOp _ One], NIL, "one"]; parenMethod: Method _ AC.MakeMethod[UnaryOp, FALSE, NEW[AC.UnaryOp _ Paren], NIL, "paren"]; sumMethod: Method _ AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp _ Add], NEW[AC.UnaryToListOp _ IntsDesired], "sum"]; negationMethod: Method _ AC.MakeMethod[UnaryOp, TRUE, NEW[AC.UnaryOp _ Negate], NEW[AC.UnaryToListOp _ IntsDesired], "negation"]; differenceMethod: Method _ AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp _ Subtract], NEW[AC.UnaryToListOp _ IntsDesired], "difference"]; productMethod: Method _ AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp _ Multiply], NEW[AC.UnaryToListOp _ IntsDesired], "product"]; commutativeMethod: Method _ AC.MakeMethod[Value, FALSE, NIL, NIL, "commutative"]; powerMethod: Method _ AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp _ Power], NEW[AC.UnaryToListOp _ ObjectAndIntDesired], "power"]; euclideanDomainMethod: Method _ AC.MakeMethod[Value, FALSE, NIL, NIL, "euclideanDomain"]; remainderMethod: Method _ AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp _ Remainder], NEW[AC.UnaryToListOp _ IntsDesired], "remainder"]; gcdMethod: Method _ AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp _ Gcd], NEW[AC.UnaryToListOp _ IntsDesired], "gcd"]; totientMethod: Method _ AC.MakeMethod[UnaryOp, TRUE, NEW[AC.UnaryOp _ Totient], NEW[AC.UnaryToListOp _ IntsDesired], "totient"]; dividesMethod: Method _ AC.MakeMethod[BinaryOp, TRUE, NEW[AC.BinaryOp _ Divides], NEW[AC.UnaryToListOp _ IntsDesired], "divides"]; equalMethod: Method _ AC.MakeMethod[BinaryPredicate, TRUE, NEW[AC.BinaryPredicate _ Equal], NEW[AC.UnaryToListOp _ IntsDesired], "equals"]; orderedMethod: Method _ AC.MakeMethod[Value, FALSE, NIL, NIL, "ordered"]; signMethod: Method _ AC.MakeMethod[CompareToZeroOp, TRUE, NEW[AC.CompareToZeroOp _ Sign], NEW[AC.UnaryToListOp _ IntsDesired], "sign"]; absMethod: Method _ AC.MakeMethod[UnaryOp, TRUE, NEW[AC.UnaryOp _ Abs], NEW[AC.UnaryToListOp _ IntsDesired], "abs"]; compareMethod: Method _ AC.MakeMethod[BinaryCompareOp, TRUE, NEW[AC.BinaryCompareOp _ Compare], NEW[AC.UnaryToListOp _ IntsDesired], "compare"]; testLoop: Method _ AC.MakeMethod[UnaryOp, TRUE, NEW[AC.UnaryOp _ TestLoop], NEW[AC.UnaryToListOp _ IntsDesired], "testLoop"]; AC.AddMethodToClass[$category, categoryMethod, intsClass]; AC.AddMethodToClass[$groundStructure, categoryMethod, intsClass]; AC.AddMethodToClass[$shortPrintName, shortPrintNameMethod, intsClass]; AC.AddMethodToClass[$recast, recastMethod, intsClass]; AC.AddMethodToClass[$canRecast, canRecastMethod, intsClass]; AC.AddMethodToClass[$toExpr, toExprMethod, intsClass]; AC.AddMethodToClass[$legalFirstChar, legalFirstCharMethod, intsClass]; AC.AddMethodToClass[$read, readMethod, intsClass]; AC.AddMethodToClass[$fromRope, fromRopeMethod, intsClass]; AC.AddMethodToClass[$toRope, toRopeMethod, intsClass]; AC.AddMethodToClass[$integer, integerMethod, intsClass]; AC.AddMethodToClass[$fromINT, fromINTMethod, intsClass]; AC.AddMethodToClass[$zero, zeroMethod, intsClass]; AC.AddMethodToClass[$one, oneMethod, intsClass]; AC.AddMethodToClass[$paren, parenMethod, intsClass]; AC.AddMethodToClass[$sum, sumMethod, intsClass]; AC.AddMethodToClass[$negation, negationMethod, intsClass]; AC.AddMethodToClass[$difference, differenceMethod, intsClass]; AC.AddMethodToClass[$product, productMethod, intsClass]; AC.AddMethodToClass[$commutative, commutativeMethod, intsClass]; AC.AddMethodToClass[$pow, powerMethod, intsClass]; AC.AddMethodToClass[$euclideanDomain, euclideanDomainMethod, intsClass]; AC.AddMethodToClass[$remainder, remainderMethod, intsClass]; AC.AddMethodToClass[$gcd, gcdMethod, intsClass]; AC.AddMethodToClass[$totient, totientMethod, intsClass]; AC.AddMethodToClass[$divides, dividesMethod, intsClass]; AC.AddMethodToClass[$eqFormula, equalMethod, intsClass]; AC.AddMethodToClass[$ordered, orderedMethod, intsClass]; AC.AddMethodToClass[$sign, signMethod, intsClass]; AC.AddMethodToClass[$abs, absMethod, intsClass]; AC.AddMethodToClass[$compare, compareMethod, intsClass]; AC.AddMethodToClass[$testLoop, testLoop, intsClass]; AC.InstallStructure[Ints]; END.