home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Language / Compiler / Builtins / Array.m < prev    next >
Encoding:
Text File  |  1990-08-16  |  10.6 KB  |  366 lines

  1. % @(#)real_Array.m    1.3  7/13/87
  2. %
  3. export _ArrayObject to "Builtins"
  4.  
  5. const _ArrayObject == 
  6.   immutable object _ArrayObject
  7.     export of
  8.     function of [ElementType : AbstractType] -> [result : NAT]
  9.       where
  10.     NAT ==    immutable type NAT
  11.           operation empty -> [NA]
  12.           operation literal [RIS] -> [NA]
  13.           operation create[Integer] -> [NA]
  14.           function getSignature -> [Signature]
  15.         end NAT
  16.     RIS ==  type i_RIS
  17.           function getElement [Integer] -> [ElementType]
  18.           function upperbound -> [Integer]
  19.           function lowerbound -> [Integer]
  20.         end i_RIS
  21.     NA ==    type NA
  22.           function  getElement [Integer] -> [ElementType]
  23.             % get the element indexed by index, failing if index 
  24.             % out of range.
  25.           operation setElement [Integer, ElementType]
  26.             % set the element, failing if index out of range
  27.           function  upperbound -> [Integer]
  28.             % return the highest valid index, ub.
  29.           function  lowerbound -> [Integer]
  30.             % return the lowest valid index, lb.
  31.           function  getSlice [Integer, Integer] -> [NA]
  32.             % return a new array, a, with lower bound lb, and 
  33.             % upper bound ub, such that for lb <= i <= ub:
  34.             %     self.getElement[i] == a.getElement[i]
  35.             % fail if lb or ub is out of range.
  36.           operation setSlice [Integer, Integer, RIS]
  37.             % set the elements indexed by i for lb <= i <= ub, so 
  38.             % that for each such i:
  39.             %     self.getElement[i] == a.getElement[i]
  40.             % fail if lb or ub is out of range.
  41.           operation slideTo [Integer]
  42.             % change the valid indicies for self.  Assuming 
  43.             % the old indicies ranged from lb to ub, the new 
  44.             % indicies will range from i to i + ub - lb
  45.           operation addUpper [ElementType]
  46.             % extend the set of valid indicies, changing ub to 
  47.             % ub + 1, and setting the element indexed by the new
  48.             % ub to be e.
  49.           operation removeUpper -> [ElementType]
  50.             % return the element indexed by ub, after contracting 
  51.             % the set of valid indicies to lb <= i <= ub - 1.
  52.           operation addLower [ElementType]
  53.             % extend the set of valid indicies, changing lb to 
  54.             % lb - 1, and setting
  55.             % the element indexed by the new lb to be e.
  56.           operation removeLower -> [ElementType]
  57.             % return the element indexed by lb, after contracting 
  58.             % the set of valid indicies to lb + 1 <= i <= ub.
  59.           function  empty -> [Boolean]
  60.             % -> true if lb == ub + 1, which is true initially,
  61.             % since initially lb = 1, and ub = 0.
  62.           operation catenate [a : RIS] -> [r : NA]
  63.             % extend the range of valid indicies from lb .. ub to 
  64.             % lb .. ub + a.length.  Set these new elements to refer
  65.             % to the elements of a so that for a.lb <= i <= a.ub, 
  66.             % where oub is the old value of self.ub:
  67.             %     a.getElement[i] == self.getElement[oub + i - 1]
  68.         end NA
  69.     ElementType *> type T end T
  70.       end where
  71.  
  72.       result <- 
  73.     immutable object aNAT
  74.       export empty, create, getSignature, literal
  75.  
  76.       const ve == Vector.of[ElementType]
  77.  
  78.       function getSignature -> [result : Signature]
  79.         result <- NA
  80.       end getSignature
  81.  
  82.       operation create[length : Integer] -> [result : NA]
  83.         result <-
  84.           object aNA
  85.         export getElement, setElement, upperbound, lowerbound, getSlice, setSlice,
  86.                slideTo, addUpper, removeUpper, addLower,
  87.                removeLower, empty, catenate
  88.  
  89.         monitor
  90.           var lwb, upb, firstIndex, lastIndex : Integer
  91.           var currentSize, maxSize : Integer
  92.           attached var vec: ve
  93.           
  94.           function  getElement [i : Integer] -> [r : ElementType]
  95.             var index : Integer
  96.             assert i >= lwb
  97.             assert i <= upb
  98.             index <- (i - lwb) + firstIndex
  99.             if index >= maxSize then
  100.               index <- index - maxSize
  101.             end if
  102.             r <- vec(index)
  103.           end getElement
  104.  
  105.           operation setElement [i : Integer, r : ElementType]
  106.             var index : Integer
  107.             assert i >= lwb
  108.             assert i <= upb
  109.             index <- (i - lwb) + firstIndex
  110.             if index >= maxSize then
  111.               index <- index - maxSize
  112.             end if
  113.             vec(index) := r
  114.           end setElement
  115.  
  116.           function  upperbound -> [r : Integer]
  117.             r <- upb
  118.           end upperbound
  119.  
  120.           function  lowerbound -> [r : Integer]
  121.             r <- lwb
  122.           end lowerbound
  123.  
  124.           % return a new Array, a, with lower bound lwb, and 
  125.           % upper bound upb, such that for lwb <= i <= upb:
  126.           %     self.getElement[i] == a.getElement[i]
  127.           % fail if lwb or upb is out of range.
  128.           function  getSlice [i1 : Integer, l : Integer] -> [r : NA]
  129.             var index : Integer
  130.             var i : Integer <- 0
  131.             assert l >= 0
  132.             assert i1 >= lwb
  133.             assert i1+l-1 <= upb
  134.             r <- aNAT.create[l]
  135.             r.slideTo[i1]
  136.             index <- (i1 - lwb) + firstIndex
  137.             if index >= maxSize then
  138.               index <- index - maxSize
  139.             end if
  140.             loop
  141.               exit when i >= l
  142.               r(i1 + i) := vec(index)
  143.               i <- i + 1
  144.               index <- index + 1
  145.               if index >= maxSize then
  146.             index <- index - maxSize
  147.               end if
  148.             end loop
  149.           end getSlice
  150.  
  151.           % set the elements indexed by i for lwb <= i <= upb, so 
  152.           % that for each such i:
  153.           %     self.getElement[i] == a.getElement[i]
  154.           % fail if lwb or upb is out of range.
  155.           operation setSlice [i1 : Integer, l : Integer, s : RIS]
  156.             var index : Integer
  157.             var i : Integer <- 0
  158.             assert l >= 0
  159.             assert i1 >= lwb
  160.             assert i1 + l <= upb
  161.             assert i1 >= s.lowerbound
  162.             assert i1 + l <= s.upperbound
  163.             index <- (i1 - lwb) + firstIndex
  164.             if index >= maxSize then
  165.               index <- index - maxSize
  166.             end if
  167.             loop
  168.               exit when i >= l
  169.               vec(index) := s(i1 + i)
  170.               i <- i + 1
  171.               index <- index + 1
  172.               if index >= maxSize then
  173.             index <- index - maxSize
  174.               end if
  175.             end loop
  176.           end setSlice
  177.  
  178.           % change the valid indicies for self.  Assuming 
  179.           % the old indicies ranged from lwb to upb, the new 
  180.           % indicies will range from i to i + upb - lwb
  181.           operation slideTo [i : Integer]
  182.             var difference : Integer <- lwb - i
  183.             lwb <- lwb - difference
  184.             upb <- upb - difference
  185.           end slideTo
  186.  
  187.           % extend the set of valid indicies, changing upb to 
  188.           % upb + 1, and setting the element indexed by the new
  189.           % upb to be e.
  190.           operation addUpper [e : ElementType]
  191.             var index : Integer
  192.             if currentSize = maxSize then
  193.               var nvec : ve
  194.               const nMaxSize : Integer == maxSize * 2
  195.               var oldIndex : Integer <- firstIndex
  196.               var newIndex : Integer <- 0
  197.               nvec <- ve.create[nMaxSize]
  198.               loop
  199.             exit when newIndex >= maxSize
  200.             nvec(newIndex) := vec(oldIndex)
  201.             newIndex <- newIndex + 1
  202.             oldIndex <- oldIndex + 1
  203.             if oldIndex >= maxSize then
  204.               oldIndex <- oldIndex - maxSize
  205.             end if
  206.               end loop
  207.               firstIndex <- 0
  208.               lastIndex <- maxSize - 1
  209.               maxSize <- nMaxSize
  210.               vec <- nvec
  211.             end if
  212.             index <- lastIndex + 1
  213.             if index >= maxSize then
  214.               index <- index - maxSize
  215.             end if
  216.             vec(index) := e
  217.             lastIndex <- index
  218.             currentSize <- currentSize + 1
  219.             upb <- upb + 1
  220.           end addUpper
  221.  
  222.           % return the element indexed by upb, after contracting 
  223.           % the set of valid indicies to lwb <= i <= upb - 1.
  224.           operation removeUpper -> [r : ElementType]
  225.             assert currentSize > 0
  226.             r <- vec(lastIndex)
  227.             currentSize <- currentSize - 1
  228.             upb <- upb - 1
  229.             if currentSize = 0 then
  230.               firstIndex <- 0
  231.               lastIndex <- ~1
  232.             else
  233.               lastIndex <- lastIndex - 1
  234.               if lastIndex < 0 then
  235.             lastIndex <- lastIndex + maxSize
  236.               end if
  237.             end if
  238.           end removeUpper
  239.  
  240.           % extend the set of valid indicies, changing lwb to 
  241.           % lwb - 1, and setting
  242.           % the element indexed by the new lwb to be e.
  243.           operation addLower [e : ElementType]
  244.             var index : Integer
  245.             if currentSize = maxSize then
  246.               var nvec : ve
  247.               const nMaxSize : Integer == maxSize * 2
  248.               var oldIndex : Integer <- firstIndex
  249.               var newIndex : Integer <- 0
  250.               nvec <- ve.create[nMaxSize]
  251.               loop
  252.             exit when newIndex >= maxSize
  253.             nvec(newIndex) := vec(oldIndex)
  254.             newIndex <- newIndex + 1
  255.             oldIndex <- oldIndex + 1
  256.             if oldIndex >= maxSize then
  257.               oldIndex <- oldIndex - maxSize
  258.             end if
  259.               end loop
  260.               firstIndex <- 0
  261.               lastIndex <- maxSize - 1
  262.               maxSize <- nMaxSize
  263.               vec <- nvec
  264.             end if
  265.             index <- firstIndex - 1
  266.             if index < 0 then
  267.               index <- index + maxSize
  268.             end if
  269.             vec(index) := e
  270.             firstIndex <- index
  271.             currentSize <- currentSize + 1
  272.             lwb <- lwb - 1
  273.           end addLower
  274.  
  275.           % return the element indexed by lwb, after contracting 
  276.           % the set of valid indicies to lwb + 1 <= i <= upb.
  277.           operation removeLower -> [r : ElementType]
  278.             assert currentSize > 0
  279.             r <- vec(firstIndex)
  280.             currentSize <- currentSize - 1
  281.             lwb <- lwb + 1
  282.             if currentSize = 0 then
  283.               firstIndex <- 0
  284.               lastIndex <- ~1
  285.             else 
  286.               firstIndex <- firstIndex + 1
  287.               if firstIndex >= maxSize then
  288.             firstIndex <- firstIndex - maxSize
  289.               end if
  290.             end if
  291.           end removeLower
  292.  
  293.           % -> true if the array is empty
  294.           function  empty -> [r : Boolean]
  295.             r <- currentSize = 0
  296.           end empty
  297.  
  298.           % return a new array the result of catenating the 
  299.           % elements of a to self
  300.           operation catenate [a : RIS] -> [catenateResult : NA]
  301.             var index, limit, newsize : Integer
  302.             var i : Integer <- 0
  303.             newsize <- currentSize+a.upperbound-a.lowerbound+1
  304.             catenateResult <- aNAT.create[newsize]
  305.             catenateResult.slideTo[lwb]
  306.             index <- firstIndex
  307.             loop
  308.               exit when i >= currentSize
  309.               catenateResult.addUpper[vec(index)]
  310.               i <- i + 1
  311.               index <- index + 1
  312.               if index >= maxSize then
  313.             index <- index - maxSize
  314.               end if
  315.             end loop
  316.             i <- a.lowerbound
  317.             limit <- a.upperbound
  318.             loop
  319.               exit when i > limit
  320.               catenateResult.addUpper[a(i)]
  321.               i <- i + 1
  322.             end loop
  323.           end catenate
  324.  
  325.           initially
  326.             lwb <- 0
  327.             firstIndex <- 0
  328.             if length < 0 then
  329.               upb <- ~1
  330.               lastIndex <- ~1
  331.               maxSize <- ~length
  332.               currentSize <- 0
  333.             elseif length = 0 then
  334.               upb <- ~1
  335.               lastIndex <- ~1
  336.               maxSize <- 10
  337.               currentSize <- 0
  338.             else
  339.               upb <- length - 1
  340.               lastIndex <- length - 1
  341.               maxSize <- length
  342.               currentSize <- length
  343.             end if
  344.             vec <- ve.create[maxSize]
  345.           end initially
  346.         end monitor
  347.           end aNA
  348.       end create
  349.       operation empty -> [result : NA]
  350.         result <- aNAT.create[0]
  351.       end empty
  352.       operation literal [v : RIS] -> [literalResult : NA]
  353.         var i : Integer <- v.lowerbound
  354.         const limit : Integer == v.upperbound
  355.         literalResult <- aNAT.create[~(limit - i + 1)]
  356.         loop
  357.           exit when i > limit
  358.           literalResult.addUpper[v(i)]
  359.           i <- i + 1
  360.         end loop
  361.       end literal
  362.     end aNAT
  363.     end of
  364.   end _ArrayObject
  365.