22.3 ACPrimitiveArray

592dom: ACPrimitiveArray 592  (569a)
ACPrimitiveArray(S: Type): with {
        exports: ACPrimitiveArray 593
} == PrimitiveArray S add {
        Rep == PrimitiveArray S;
        import from Rep;
        implementation: ACPrimitiveArray 594
}

Defines:
ACPrimitiveArray, used in chunks 54 and 605.

Exports of ACPrimitiveArray

bracket: Tuple S -> %

apply: (%, I) -> S

set!: (%, I, S) -> S

empty: %

empty?: % -> Boolean

new: (I, S) -> %

new: I -> %

resize!: (%, I, I) -> %

593exports: ACPrimitiveArray 593  (592)  595a
bracket: Tuple S -> %;
ToDo 83
rhx 65 21-Dec-2006: The description of bracket explains some potentially dangerous code.
In the implementation of bracket we rely on two things.
  1. The implementation of Tuple in src/algebra/array1.spad.pamphlet of Axiom says

    Tuple(S:Type): CoercibleTo(PrimitiveArray S) with
      coerce: PrimitiveArray S -> %
      ...
     == add
      Rep := Record(len : NonNegativeInteger, elts : PrimitiveArray S)
      ...

  2. In the distribution of the files from Peter Broadbery that construct the libaxiom.al file one finds in as/axlit.as.pamphlet

    extend Tuple (T: Type) : with {
      length:         % -> SI;
      element:        (%, SI) -> T;

      export from T;
    }
    == add {
      Rep ==> Record(sz: SI, values: BArr);
      import from Rep;

      length (t: %) : SI == rep(t).sz;
      element(t: %, n: SI): T == (rep(t).values.(dec n)) pretend T;
    }

    and additionally that SI is a macro that expands to SingleInteger. SingleInteger uses Integer as representation.

The pretend below is safe as long as the above files are not changed.

594implementation: ACPrimitiveArray 594  (592)  595b
bracket(s: Tuple S): % == {
        macro TUPLE == Record(sz: SingleInteger, values: PrimitiveArray S);
        r: TUPLE := s pretend TUPLE;
        per r.values;
}
595aexports: ACPrimitiveArray 593+   (592)  593  595c
apply: (%, I) -> S;

Uses I 47.
595bimplementation: ACPrimitiveArray 594+   (592)  594  595d
apply(x: %, i: I): S == {
        import from ACInteger;
        rep(x).(i :: Integer);
}

Uses ACInteger 581a, I 47, and Integer 66.
595cexports: ACPrimitiveArray 593+   (592)  595a  596a
set!: (%, I, S) -> S;

Uses I 47.
595dimplementation: ACPrimitiveArray 594+   (592)  595b  596b
set!(x: %, i: I, s: S): S == {
        import from ACInteger;
        set!(rep x, i :: Integer, s);
}

Uses ACInteger 581a, I 47, and Integer 66.
596aexports: ACPrimitiveArray 593+   (592)  595c  596c
empty: %;
596bimplementation: ACPrimitiveArray 594+   (592)  595d  596d
empty: % == per empty();
596cexports: ACPrimitiveArray 593+   (592)  596a  596e
empty?: % -> Boolean;
596dimplementation: ACPrimitiveArray 594+   (592)  596b  597a
empty?(x: %): Boolean == {
        import from NonNegativeInteger;
        zero? # rep x;
}
596eexports: ACPrimitiveArray 593+   (592)  596c  597b
new: (I, S) -> %;

Uses I 47.
597aimplementation: ACPrimitiveArray 594+   (592)  596d  597c
new(sz: I, s: S): % == {
        import from NonNegativeInteger;
        per new(sz :: NNI, s);
}

Uses I 47.
597bexports: ACPrimitiveArray 593+   (592)  596e  598a
new: I -> %;

Uses I 47.
ToDo 84
rhx 66 21-Dec-2006: Potentially dangerous to rely on the right size of 0$Integer!
Unfortunately, we need a dummy element from the parameter domain S. Hopefully, that will have the right size.
597cimplementation: ACPrimitiveArray 594+   (592)  597a  598b
new(sz: I): % == {
        dummyElement: S == (0$Integer) pretend S;
        new(sz, dummyElement);
}

Uses I 47 and Integer 66.
598aexports: ACPrimitiveArray 593+   (592)  597b
resize!: (%, I, I) -> %;

Uses I 47.
598bimplementation: ACPrimitiveArray 594+   (592)  597c
resize!(x: %, oldSize: I, newSize: I): % == {
        assert(oldSize >= 0);
        assert(newSize >= 0);
        if newSize > oldSize then { -- double size
                lastIndex := prev oldSize;
        } else if 2*newSize < oldSize then { -- half size of array
                lastSize := prev newSize;
        } else {
                return x
        }
        z: % := new newSize;
        import from UniversalSegment I;
        for i:I in 0..lastIndex repeat z.i := x.i;
        z;
}

Uses I 47.