Changeset 2155

Show
Ignore:
Timestamp:
07/01/08 09:24:04 (3 months ago)
Author:
jmaessen
Message:

Fixed bug / oversight in bounds checking and narrowing of partial
ranges wrt full ranges. A partial range may now start just past the
end of the corresponding range, or end just before the beginning, and
this will yield an empty range as we expect. This gets rid of a bunch
of fencepost checking in code that creates array views (especially for
stuff like substrings, which previously contained a watered-down hack
that accomplished the same goal).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Library/FortressLibrary.fss

    r2150 r2155  
    28872887    getter indices(): FullRange[\T\] = bounds() 
    28882888 
     2889    (** The following two methods are used in bounds checking code to 
     2890        permit ranges that are just outside the edge of the given 
     2891        range. **) 
     2892    widenUpper(): FullRange[\T\] 
     2893    widenLower(): FullRange[\T\] 
     2894 
    28892895    opr[r:Range[\T\]]: FullRange[\T\] = fail("Unrecognized Range " r) 
    28902896    opr[_:OpenRange[\T\]]: FullRange[\T\] = self 
     
    29012907            (* Important, also handles empty range case. *) 
    29022908            self 
    2903         elif r.lower() IN self then 
     2909        elif r.lower() IN widenUpper() then 
    29042910            r.lower():upper() 
    29052911        else 
     
    29102916            (* Important, also handles empty range case. *) 
    29112917            self 
    2912         elif r.upper() IN self then 
     2918        elif r.upper() IN widenLower() then 
    29132919            lower():r.upper() 
    29142920        else 
     
    29642970    getter upper():N = lower() + extent() - 1 
    29652971    getter size():ZZ32 = |self| 
     2972    widenUpper(): ScalarRange[\N\] = lower()#(extent()+1) 
     2973    widenLower(): ScalarRange[\N\] = (lower()-1)#(extent()+1) 
    29662974    opr |self| : ZZ32 = narrow(extent()) 
    29672975    opr[i:N]: N = 
     
    30933101        Tuple2Range[\N\](0,0,x1,x2).map[\((N,M),(N,M))\]( 
    30943102            fn (n:N,m:M):((N,M),(N,M)) => ((n,m),(n+l1,m+l2))) 
     3103    widenUpper(): Tuple2Range[\N,M\] = (l1,l2)#(x1+1,x2+1) 
     3104    widenLower(): Tuple2Range[\N,M\] = (l1-1,l2-1)#(x1+1,x2+1) 
    30953105    opr |self| : ZZ32 = |l1#x1| |l2#x2| 
    30963106    opr[i:(N,M)]: (N,M) = do 
     
    31283138            fn (t:(N1,N2),n3:N3):((N1,N2,N3),(N1,N2,N3)) => 
    31293139                do (n1,n2)=t; ((n1,n2,n3),(n1+l1,n2+l2,n3+l3)) end) 
     3140    widenUpper(): Tuple3Range[\N1,N2,N3\] = (l1,l2,l3)#(x1+1,x2+1,x3+1) 
     3141    widenLower(): Tuple3Range[\N1,N2,N3\] = (l1-1,l2-1,l3-1)#(x1+1,x2+1,x3+1) 
    31303142    opr |self| : (N1,N2,N3) = |l1#x1| |l2#x2| |l3#x3| 
    31313143    opr[i:(N1,N2,N3)]: (N1,N2,N3) = do 
     
    32103222match(regex:String,some:String):Boolean = builtinPrimitive("com.sun.fortress.interpreter.glue.prim.StringPrim$Match") 
    32113223 
    3212 (** opr // appends a single newline separator. **) 
     3224(** postfix %//% appends a single newline separator.  The postfix version 
     3225    performs implicit conversion to String, which is why it's a 
     3226    standalone top-level function.  Infix and prefix versions are defined by String. **) 
    32133227opr (x:Any)// : String = x||"\n" 
    32143228 
    3215 (** opr /// appends a double newline separator **) 
     3229(** postfix %///% appends a double newline separator.  The postfix version 
     3230    performs implicit conversion to String, which is why it's a 
     3231    standalone top-level function.  Infix and prefix versions are defined by String. **) 
    32163232opr (x:Any)/// : String = x||"\n\n" 
    32173233 
  • trunk/Library/List.fss

    r2106 r2155  
    8888trait SomeList excludes { Number, HasRank } 
    8989        (* comprises List[\E\] where [\E\] *) 
    90     append(f:SomeList): SomeList = app(self,f) 
     90    opr ||(self, f:SomeList): SomeList = app(self,f) 
    9191    addLeft(e:Any): SomeList = addL(e,self) 
    9292    addRight(e:Any): SomeList = addR(self,e) 
     
    9595private app[\T,E extends T,F extends T\](a:List[\E\], b:List[\F\]): List[\T\] = 
    9696    typecase (a,b) of 
    97         (List[\T\],List[\T\]) => a.append(b) 
     97        (List[\T\],List[\T\]) => a || b 
    9898        (List[\T\],List[\F\]) => a.appendRC[\F\](b) 
    9999        (List[\E\],List[\T\]) => b.appendLC[\E\](a) 
     
    123123    getter extractLeft(): Maybe[\(E,List[\E\])\] 
    124124    getter extractRight(): Maybe[\(List[\E\],E)\] 
    125     (** %append% returns a list containing the elements of %self% followed 
     125    (** the operator %||% returns a list containing the elements of %self% followed 
    126126        by the elements of %f% *) 
    127     append(f:List[\E\]): List[\E\] 
    128     (** the operator %||% performs the %append% operation *) 
    129     opr ||(self, other:List[\E\]): List[\E\] = append(other) 
     127    opr ||(self, other:List[\E\]): List[\E\] 
    130128    (** Helper methods for %append% *) 
    131129    private appendRC[\T\](other:List[\T\]): List[\E\] 
     
    183181covariantComprehension[\T,R\](unwrap:SomeList->R): Comprehension[\T,R,SomeList,SomeList\] = 
    184182    Comprehension[\T,R,SomeList,SomeList\]( 
    185         fn xs => unwrap(xs.append(emptyList[\T\]())), CVConcat[\T\], cvSingleton) 
     183        fn xs => unwrap(xs || emptyList[\T\]()), CVConcat[\T\], cvSingleton) 
    186184 
    187185(** Convert generator into list; can be used to desugar list 
     
    232230  getter toString():String = "List concatenation" 
    233231  empty(): List[\E\] = emptyList[\E\]() 
    234   join(a:List[\E\], b:List[\E\]): List[\E\] = a.append(b) 
     232  join(a:List[\E\], b:List[\E\]): List[\E\] = a || b 
    235233end 
    236234 
     
    239237  getter toString():String = "Covariant list concatenation" 
    240238  empty(): SomeList = emptyList[\T\]() 
    241   join(a:SomeList, b:SomeList): SomeList = a.append(b) 
     239  join(a:SomeList, b:SomeList): SomeList = a || b 
    242240end 
    243241 
     
    246244  getter toString():String = "List reversal concatenation" 
    247245  empty(): List[\E\] = emptyList[\E\]() 
    248   join(a:List[\E\], b:List[\E\]): List[\E\] = b.append(a) 
     246  join(a:List[\E\], b:List[\E\]): List[\E\] = b || a 
    249247end 
    250248 
     
    353351      end 
    354352 
    355     (** %append%.  Can either append %other% to the right of %self% 
     353    (** %||% cab either append %other% to the right of %self% 
    356354        or %self% to the left of %other%.  Choose based on available 
    357355        space, preferring right append and if necessary right extension. **) 
    358     append(other:List[\E\]): List[\E\] = 
     356    opr ||(self, other:List[\E\]): List[\E\] = 
    359357        if rightSpace() >= |other| AND: canExtendRight.tryOnce() then 
    360358            appendR[\E\](other) 
  • trunk/Library/PureList.fss

    r2140 r2155  
    4747trait List[\E\] extends { LexicographicOrder[\List[\E\],E\] } 
    4848        excludes { Number, HasRank } 
    49   getter left():Maybe[\E\] = extractLeft().map[\E\](fn (v:E,_):E => v) 
    50   getter right():Maybe[\E\] = extractRight().map[\E\](fn (_,v:E):E => v) 
    51   getter extractLeft(): Maybe[\(E,List[\E\])\] 
    52   getter extractRight(): Maybe[\(List[\E\],E)\] 
    53   append(f:List[\E\]): List[\E\] 
    54   opr ||(self, other:List[\E\]): List[\E\]      
    55   addLeft(e:E):List[\E\] 
    56   addRight(e:E):List[\E\] 
    57   take(n:ZZ32): List[\E\] 
    58   drop(n:ZZ32): List[\E\] 
    59   opr [n:ZZ32]: E 
    60   opr [n:Range[\ZZ32\]]: List[\E\] = 
    61       drop(n.lower()).take(n.extent()) 
    62   split(n:ZZ32): (List[\E\], List[\E\]) 
    63   split(): (List[\E\], List[\E\]) 
    64   reverse(): List[\E\] = generate[\List[\E\]\](RevConcat[\E\],singleton[\E\]) 
    65   filter(p: E -> Boolean): List[\E\] = 
    66       concatMap[\E\](fn (x:ZZ32):List[\E\] => if p(x) then singleton[\E\](x) 
    67                                               else emptyList[\E\]() end) 
    68   toString():String = 
     49    (** %left% and %extractLeft% return the leftmost element in the list 
     50        (and in the latter case, the remainder of the list without its 
     51        leftmost element).  They return %Nothing% if the list is empty. 
     52        %right% and %extractRight% do the same with the rightmost 
     53        element. *) 
     54    getter left():Maybe[\E\] = extractLeft().map[\E\](fn (v:E,_):E => v) 
     55    getter right():Maybe[\E\] = extractRight().map[\E\](fn (_,v:E):E => v) 
     56    getter extractLeft(): Maybe[\(E,List[\E\])\] 
     57    getter extractRight(): Maybe[\(List[\E\],E)\] 
     58    opr ||(self, other:List[\E\]): List[\E\] 
     59    (** %addLeft% and %addRight% add an element to the left or right of 
     60        the list, respectively *) 
     61    addLeft(e:E):List[\E\] 
     62    addRight(e:E):List[\E\] 
     63    (** %take% returns the leftmost %n% elements of the list; if the 
     64        list is shorter than this, the entire list is returned. *) 
     65    take(n:ZZ32): List[\E\] 
     66    (** %drop% drops the leftmost %n% elements of the list; if the list 
     67        is shorter than this, an empty list is returned. *) 
     68    drop(n:ZZ32): List[\E\] 
     69    opr [n:ZZ32]: E 
     70    opr [n:Range[\ZZ32\]]: List[\E\] = do 
     71        r = (0 # |self|)[n] 
     72        drop(r.lower()).take(r.extent()) 
     73      end 
     74    (** %l.split(n)% is equivalent to %(l.take(n),l.drop(n))%.  Note in 
     75        particular that appending its results yields the original 
     76        list. *) 
     77    split(n:ZZ32): (List[\E\], List[\E\]) 
     78    (** %split% splits the list into two smaller lists.  If %|l| > 1% 
     79        both lists will be non-empty. *) 
     80    split(): (List[\E\], List[\E\]) 
     81    reverse(): List[\E\] = 
     82        generate[\List[\E\]\](RevConcat[\E\],singleton[\E\]) 
     83    filter(p: E -> Boolean): List[\E\] = 
     84        concatMap[\E\](fn (x:E):List[\E\] => if p(x) then singleton[\E\](x) 
     85                                             else emptyList[\E\]() end) 
     86    toString():String = 
    6987      "<|" (if (h,t) <- extractLeft() then 
    7088                h (BIG ||[e<-t] ", " e) 
    7189            else " " end) "|>" 
    72   concatMap[\G\](f: E->List[\G\]): List[\G\] = 
    73       generate[\List[\G\]\](Concat[\G\],f) 
    74   map[\G\](f: E->G): List[\G\] = 
    75       concatMap[\G\](fn (e:E):List[\G\] => singleton[\G\](f(e))) 
    76   ivmap[\G\](f: (ZZ32,E)->G): List[\G\] = 
    77       indexValuePairs().generate[\List[\G\]\](Concat[\G\], 
    78                 fn (t:(ZZ32,E)):List[\G\] => singleton[\G\](f(t))) 
     90    (** %concatMap% is an in-place version of the %nest% method from 
     91        %Generator%; it flattens the result into an actual list, rather than 
     92        returning an abstract %Generator%. *) 
     93    concatMap[\G\](f: E->List[\G\]): List[\G\] = 
     94        generate[\List[\G\]\](Concat[\G\],f) 
     95    map[\G\](f: E->G): List[\G\] = 
     96        concatMap[\G\](fn (e:E):List[\G\] => singleton[\G\](f(e))) 
     97    ivmap[\G\](f: (ZZ32,E)->G): List[\G\] = 
     98        indexValuePairs().generate[\List[\G\]\](Concat[\G\], 
     99                  fn (t:(ZZ32,E)):List[\G\] => singleton[\G\](f(t))) 
    79100end 
    80101 
     
    96117  getter toString(): String = "List concatenation reduction" 
    97118  empty(): List[\E\] = emptyList[\E\]() 
    98   join(a:List[\E\], b:List[\E\]): List[\E\] = a.append(b) 
     119  join(a:List[\E\], b:List[\E\]): List[\E\] = a || b 
    99120end 
    100121 
     
    103124  getter toString(): String = "List reversal reduction" 
    104125  empty(): List[\E\] = emptyList[\E\]() 
    105   join(a:List[\E\], b:List[\E\]): List[\E\] = b.append(a) 
     126  join(a:List[\E\], b:List[\E\]): List[\E\] = b || a 
    106127end 
    107128 
     
    110131  getter toString(): String = "PureList concatenation reduction" 
    111132  empty(): PureList[\E\] = D0[\E\] 
    112   join(a:PureList[\E\], b:PureList[\E\]): PureList[\E\] = a.append(b) 
     133  join(a:PureList[\E\], b:PureList[\E\]): PureList[\E\] = a || b 
    113134end 
    114135 
     
    130151      it.generate[\R\](r,body) 
    131152  seq(self): SequentialGenerator[\E\] = SeqListGenerator[\E\](it) 
    132   opr ||(self, other:List[\E\]): List[\E\] = append(other)      
    133   append(f:List[\E\]): PureList[\E\] = 
    134       append(f.generate[\PureList[\E\]\](PLConcat[\E\],singleton[\E\])) 
    135   append(f:PureList[\E\]): PureList[\E\] = 
     153  opr ||(self, other:List[\E\]): List[\E\] = 
     154      self || f.generate[\PureList[\E\]\](PLConcat[\E\],singleton[\E\]) 
     155  opr ||(self, f:PureList[\E\]): PureList[\E\] = 
    136156      PureList[\E\](it.append(f.contents())) 
    137157  addLeft(e:E):PureList[\E\] = 
  • trunk/ProjectFortress/LibraryBuiltin/FortressBuiltin.fss

    r2150 r2155  
    207207    get(i:ZZ32): Char = 
    208208        builtinPrimitive("com.sun.fortress.interpreter.glue.prim.String$Index") 
    209     (** As a convenience, we permit LowerRange indexing to go 1 past the bounds 
    210         of the string, returning the empty string, in order to permit some convenient 
    211         string-trimming idioms. **) 
    212     opr[r0:LowerRange[\ZZ32\]]: String = do 
    213         l = r0.lower() 
    214         if l = |self| then "" 
    215         else self[l#(|self| - l)] 
    216         end 
    217       end 
    218209    opr[r0:Range[\ZZ32\]] : String = do 
    219210        r1 = (bounds())[r0] 
     
    259250    opr juxtaposition(self, b:Any):String = self || b 
    260251 
    261     (** opr // appends with a single newline separator. **) 
     252    (** opr %//% appends with a single newline separator.  Note that as 
     253        with %||% and %|||% at least one argument must be a String. 
     254        There is a postfix version in FortressLibrary that performs 
     255        string conversion, but the prefix version must occur before a 
     256        String. **) 
    262257    opr //(self) : String = "\n"||self 
    263258    opr //(self, a:String): String = self||"\n"||a 
     
    265260    opr //(a:Any, self): String    = a||"\n"||self 
    266261 
    267     (** opr /// appends with a double newline separator **) 
     262    (** opr %///% appends with a double newline separator.  Note that as 
     263        with %||% and %|||% at least one argument must be a String. 
     264        There is a postfix version in FortressLibrary that performs 
     265        string conversion, but the prefix version must occur before a 
     266        String. **) 
    268267    opr ///(self) : String = "\n\n"||self 
    269268    opr ///(self, a:String): String = self||"\n\n"||a 
  • trunk/ProjectFortress/demos/ArrayListLong.fss

    r1778 r2155  
    7979      chkExtract(li,i) 
    8080      (ll,lr) = li.split() 
    81       lii = ll.append(lr) 
     81      lii = ll || lr 
    8282      chkPop(lii,i) 
    8383      fli = li.filter(fn x => x REM 2 = 0) 
     
    114114          print(".") 
    115115          lj = list(i#j) 
    116           chkPop(li.append(lj),i+j) 
     116          chkPop(li || lj, i+j) 
    117117          gz = li.zip[\ZZ32\](lj) 
    118118          assert(|gz|,|li| MIN |lj|, "zip size wrong") 
  • trunk/ProjectFortress/demos/PureListLong.fss

    r1775 r2155  
    7979      chkExtract(li,i) 
    8080      (ll,lr) = li.split() 
    81       lii = ll.append(lr) 
     81      lii = ll || lr 
    8282      chkPop(lii,i) 
    8383      fli = li.filter(fn x => x REM 2 = 0) 
     
    114114          print(".") 
    115115          lj = list(i#j) 
    116           chkPop(li.append(lj),i+j) 
     116          chkPop(li || lj, i+j) 
    117117          gz = li.zip[\ZZ32\](lj) 
    118118          assert(|gz|,|li| MIN |lj|, "zip size wrong") 
  • trunk/ProjectFortress/demos/wordcount.fss

    r1825 r2155  
    7777 
    7878opr UNIONUNION(a:Map[\ZZ32,List[\String\]\], b:Map[\ZZ32, List[\String\]\]):Map[\ZZ32,List[\String\]\] = 
    79     a.union(fn(k,x,y) =>x.append(y),b) 
     79    a.union(fn(k,x,y) => x || y, b) 
    8080 
    8181opr BIG UNIONUNION(): BigReduction[\Map[\ZZ32, List[\String\]\],Map[\ZZ32, List[\String\]\]\] = 
  • trunk/ProjectFortress/src/com/sun/fortress/numerics/DirectedRounding.java

    r1566 r2155  
    2626 * in pure Java. 
    2727 */ 
    28 public class DirectedRounding { 
     28public final class DirectedRounding { 
     29 
     30  private DirectedRounding() {} 
    2931 
    3032  public static float nextUp(float x) { 
  • trunk/ProjectFortress/tests/ArrayListQuick.fss

    r1775 r2155  
    9999      (ll,lr) = li.split() 
    100100      print(".") 
    101       lii = ll.append(lr) 
     101      lii = ll || lr 
    102102      chkPop(lii,i) 
    103103      print(".") 
     
    145145          chkPop(l2,j) 
    146146          chkPop(r2,j,i-j) 
     147          (l3,r3) = (li[#j],li[j#]) 
     148          chkPop(l3,j) 
     149          chkPop(r3,j,i-j) 
     150          (l4,r4) = (li[:(j-1)],li[j:]) 
     151          chkPop(l4,j) 
     152          chkPop(r4,j,i-j) 
    147153      end 
    148154      for j <- testLens do 
    149155          print(".") 
    150156          lj = list(i#j) 
    151           chkPop(li.append(lj),i+j) 
     157          chkPop(li || lj, i+j) 
    152158          print(".") 
    153159          gz = li.zip[\ZZ32\](lj) 
     
    159165  end 
    160166  testStr : List[\String\] = <| "Hello" asif String |> 
    161   testU : List[\Any\] = testStr.append(testLens) 
     167  testU : List[\Any\] = testStr || testLens 
    162168  chkApp(testLens,testU) 
    163   chkApp(testLens,testU.append(testStr).drop(1)) 
    164   chkApp(testLens,testStr.append(testU).drop(1)) 
     169  chkApp(testLens,(testU || testStr).drop(1)) 
     170  chkApp(testLens,(testStr || testU).drop(1)) 
    165171  chkApp(testLens,testLens.addLeft("Hello")) 
    166172  chkApp(testLens,testLens.addRight("Hello")) 
  • trunk/ProjectFortress/tests/ListTest.fss

    r1481 r2155  
    3131    assert(list'.drop(1),<|5 asif ZZ32,7|>," list'.drop(1)") 
    3232    assert((list'.drop(1))[1], 7," list'.drop(1)[1]") 
    33     l = list'.append(list'') 
     33    l = list' || list'' 
    3434    assert(3 IN list'', false, "3 IN ", list'') 
    3535    assert(BIG AND [e <- list''] e IN l, true, 
  • trunk/ProjectFortress/tests/PureListQuick.fss

    r1775 r2155  
    3333  if NOT a then 
    3434    fail("Failed assertion: " s l.toString() " and " r.toString()) 
     35  end 
     36 
     37chkApp(tl: List[\ZZ32\], t : List[\Any\]) = do 
     38    assert("Hello" IN t, true, "missing Hello from ", t) 
     39    assert(l IN t, true, "missing ",l," from ",t), l <- tl 
    3540  end 
    3641 
     
    8186  assert(20,SUM testLens,"sum wrong") 
    8287  for i <- seq(testLens) do 
    83       print( //i ":") 
     88      print( // i ":") 
    8489      li = list(0#i) 
    8590      print(li) 
     
    8994      assert(li,li,"Lists unequal") 
    9095      assert(li CMP li,EqualTo,"Lists CMP unequal") 
     96      chkPop(li[#],i) 
     97      chkPop(li.addRight(i),i+1) 
     98      chkPop(li.addLeft(-1),-1,i+1) 
    9199      (ll,lr) = li.split() 
    92100      print(".") 
    93       lii = ll.append(lr) 
     101      lii = ll || lr 
    94102      chkPop(lii,i) 
    95103      print(".") 
     
    137145          chkPop(l2,j) 
    138146          chkPop(r2,j,i-j) 
     147          (l3,r3) = (li[#j],li[j#]) 
     148          chkPop(l3,j) 
     149          chkPop(r3,j,i-j) 
     150          (l4,r4) = (li[:(j-1)],li[j:]) 
     151          chkPop(l4,j) 
     152          chkPop(r4,j,i-j) 
    139153      end 
    140154      for j <- testLens do 
    141155          print(".") 
    142156          lj = list(i#j) 
    143           chkPop(li.append(lj),i+j) 
     157          chkPop(li || lj, i+j) 
    144158          print(".") 
    145159          gz = li.zip[\ZZ32\](lj) 
  • trunk/ProjectFortress/tests/asifTest.fss

    r1597 r2155  
    6262    y : List[\Foo\] = <| Baz asif Foo, Baz |> 
    6363    (* Now appending the two ought to work. *) 
    64     println(x.append(y)
     64    println(x || y
    6565 
    6666    (* Top-level overloading *)