Patch title: Release 91 bulk changes
Abstract:
File: /language/type/set/array.pli
Key:
    Removed line
    Added line
# Copyright  Hubert Tonneau  hubert.tonneau@pliant.cx
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# version 2 along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

scope "/pliant/language/" "/pliant/install/"
module "/pliant/install/ring2.pli"
submodule "/pliant/language/basic/setfield.pli"
submodule "common.pli"


gvar Relation 'pliant array types'
export 'pliant array types'

function Array value -> t
  arg Type value ; arg_R Type t
  has_no_side_effect

  var Address adr := 'pliant array types' query addressof:value null
  if adr<>null
    return (adr map Type)

  runtime_compile  Value value  Array (cast "(Array "+value:name+")" Ident)
    type Array
      field Address items
      field Int nb

    function build  a
      arg_w Array a
      a items := null
      a nb := 0

    function destroy a
      arg_w Array a
      if (Value:flags .and. type_flag_scalar)=0
        for (var Int i) 0 a:nb-1
          Value destroy_instance (a:items translate Value i)
      memory_free a:items

    method a '' k -> v
      arg Array a ; arg Int k ; arg_C Value v
      check k>=0 and k<a:nb "out of range array index"
      # v :> (a:items translate Value k) map Value
      (addressof Pointer:Value v) map Address := a:items translate Value k

    method a size -> n
      arg Array a ; arg Int n
      n := a:nb
      n := a nb

    method a 'size :=' s
      arg_rw Array a ; arg Int s
      check s>=0 "negative array size"
      if s>a:nb
        a items := memory_resize a:items s*Value:size addressof:a
        if (Value:flags .and. type_flag_scalar)=0
          for (var Int i) a:nb s-1
            Value build_instance (a:items translate Value i)
      if s<a:nb
        if (Value:flags .and. type_flag_scalar)=0
          for (var Int i) s a:nb-1
            Value destroy_instance (a:items translate Value i)
        a items := memory_resize a:items s*Value:size addressof:a
      a:nb := s
      a nb := s

    function copy src dest
      arg Array src ; arg_w Array dest
      dest 'size :=' src:nb
      if (Value:flags .and. type_flag_scalar)=0
        for (var Int i) 0 src:nb-1
          # dest i := src i
          Value copy_instance (src:items translate Value i) (dest:items translate Value i)
      else
        memory_copy src:items dest:items src:nb*Value:size

    function '+=' a v
      arg_rw Array a ; arg Value v
      var Int i := a size
      a 'size :=' i+1
      # a i := v
      Value copy_instance (addressof Value v) (a:items translate Value i)

    method a exists k -> c
      arg Array a ; arg Int k ; arg CBool c
      c := k>=0 and k<a:size

    method a key v -> k
      arg Array a ; arg_r Value v ; arg Int k
      k := ( (cast (addressof Value v) Int) .-. (cast a:items Int) ) \ Value:size

    method a first -> v
      arg Array a ; arg_C Value v
      if a:size>0
        # v :> a 0
        (addressof Pointer:Value v) map Address := a items
      else
        # v :> null map Value
        (addressof Pointer:Value v) map Address := null

    method a next v1 -> v2
      arg Array a ; arg_r Value v1 ; arg_C Value v2
      var Int i := (a key v1)+1
      if a:size>i
        # v2 :> a i
        (addressof Pointer:Value v2) map Address := a:items translate Value i
      else
        # v2 :> null map Value
        (addressof Pointer:Value v2) map Address := null

    method a first k -> v
      arg Array a ; arg Int k ; arg_C Value v
      if k>=0 and k<a:size
        # v :> a k
        (addressof Pointer:Value v) map Address := a:items translate Value k
      else
        # v :> null map Value
        (addressof Pointer:Value v) map Address := null

    method a next k v1 -> v2
      arg Array a; arg Int k ; arg_r Value v1 ; arg_C Value v2
      # v2 :> null map Value
      (addressof Pointer:Value v2) map Address := null

    method a check
      arg Array a

    export Array '' '. size' '. size :=' '+=' '. exists' '. key' '. first' '. next' '. check'
    'pliant array types' define addressof:Value null addressof:Array
    'pliant set types' define addressof:Array addressof:Array addressof:(new Str "Array")
    'pliant set types' define addressof:Array null addressof:Int
    'pliant set types' define null addressof:Array addressof:Value

  var Address adr := 'pliant array types' query addressof:value null
  check adr<>null
  return (adr map Type)

export Array