ORIGIN 'container'; LIB_DEF 'list' '../lib'; BODY 'private/listBody'; (* * COPYRIGHT * Copyright (C) Mjolner Informatics, 1992-96 * All rights reserved. *) --- lib: attributes --- list: container (* This list pattern defines a double-linked list data structure. * Most operations either enters or exits a list position. List * positions are references into a particular place in the list, * containing an element. These positions are instances of * theCellType. * * list * cyclicList --- prev and next operations to impl. cyclic list * priorityList --- elements ordered by priority * recList --- allows for recursive lists (in separate fragment) * * Defines the following new operations: prepend, append, head, * tail, last, preample, at, locate, concatenate, splitBefore, * splitAfter, insertBefore, insertAfter, delete, deleteBefore, * deleteAfter, scanReverse, iterate, iterateFrom, * iterateReverse, iterateReverseFrom *) (# <<SLOT listLib: attributes>>; theCellType::< (* theCellType is the pattern from which the individual list * positions are created. It defines the succ and pred * references to the list positions immediately before/after * this position in the list (NONE means the end of the list * (either end). The elm attribute refers to the element at * this position in the list. *) (# succ, pred: ^theCelltype; do INNER #); clear::< (# ... #); size::< (# ... #); empty::< (# ... #); has:: (# ... #); copy::<(# ... #); prepend: (* insert elm as first element *) (# elm: ^element; position: ^theCellType enter elm[] ... exit position[] #); append: (* insert elm as last element *) (# elm: ^element; position: ^theCellType enter elm[] ... exit position[] #); head: (* returns the position element of the first position in the * list *) (# position: ^theCellType ... exit position[] #); tail: (* returns a copy of THIS(list), except the first element *) (# lst: ^list ... exit lst[] #); last: (* returns the position element of the last position in the * list *) (# position: ^theCellType ... exit position[] #); preample: (* returns a copy of THIS(list), except the last element *) (# lst: ^list ... exit lst[] #); concatenate: (* returns a new list, containing the concatenated list *) (# otherList, newlist: ^list; enter otherList[] ... exit newlist[] #); insertBefore: (* if position=NONE, insert elm as last element *) (# elm: ^element; position, newPosition: ^theCellType enter (elm[], position[]) ... exit newPosition[] #); insertAfter: (* if position=NONE, insert elm as first element *) (# elm: ^element; position, newPosition: ^theCellType enter (elm[], position[]) ... exit newPosition[] #); delete: (* if position=NONE, delete nothing *) (# deletedPosition, position: ^theCellType; empty:< emptyContainer enter position[] ... exit deletedPosition[] #); deleteBefore: (* if position=NONE, delete last position element *) (# deletedPosition, position: ^theCellType; empty:< emptyContainer enter position[] ... exit deletedPosition[] #); deleteAfter: (* if position=NONE, delete first position element *) (# deletedPosition, position: ^theCellType; empty:< emptyContainer enter position[] ... exit deletedPosition[] #); splitBefore: (* splits this(list) into two lists, where the elements before * position (excluding position) is placed in preList and the * rest of this(list) is placed in postList. PositionElm will * be the head of postList. If position=NONE, preList will * become a copy of the entire list and postList will become * NONE *) (# position: ^theCellType; preList, postList: ^list; listSplitBeforePrivate: @... enter position[] do listSplitBeforePrivate; INNER exit (preList[], postList[]) #); splitAfter: (* splits this(list) into two lists, where the elements before * position (including position) is placed in preList and the * rest of this(list) is placed in postList. PositionElm will * be the last element in postList If position=NONE, preList * will become a copy of the entire list and postList will * become NONE *) (# position: ^theCellType; preList, postList: ^list; listSplitAfterPrivate: @... enter position[] do listSplitAfterPrivate; INNER exit (preList[], postList[]) #); at: (* returns the position of elm in the list *) (# elm: ^element; position: ^theCellType enter elm[] ... exit position[] #); locate: (* returns the position of the element in the list, satisfying * predicate. This operation is similar to find, except that * it returns the position, not the element. *) (# predicate:< cellPredicate; notFound:< Notification (# do none->position[]; 'Element not found in list'->msg.putLine; INNER #); start:< object; end:< object; position: ^theCellType; ... exit position[] #); find:: (# ... #); thescanner::< (* private *) (# theCell:^theCelltype; notdone:@boolean; ... #); theReverseScanner:< (* private *) (# w:^elementPredicate; s:^scanreverse; aCell:^theCellType; notdone:@boolean; enter (s[],w[]) ... #); theFromScanner:< (* private *) (# w:^elementPredicate; s:^scanFrom; aCell:^theCellType; notdone:@boolean; enter (s[],w[],aCell[]) ... #); scanReverse: (* similar to scan, except that it scans the list in reverse * direction *) (# first:@boolean; where:< elementPredicate; current: ^element; start:< object; end:< object; ... #); scanFrom: (* similar to scan, except that it scans the list from the * given position *) (# first:@boolean; where:< elementPredicate; current: ^element; start:< object; end:< object; position:^theCelltype; (* start cell *) enter position[] ... #); scanReverseFrom: (* similar to scanReverse, except that it scans the list in * reverse direction from the given position *) (# where:< elementPredicate; position: ^theCellType; current: ^element; theCell:^theCelltype; start:< object; end:< object; enter position[] ... #); iterate: (* similar to scan, except that "current" refers to the * current cell in the list. If furthermore the list is an * instance of the recList subpattern, iterate respects the * sublist structure by not scanning the elements in the * sublists (as scan does). I.e. during an iterate of a * recList, "current" may refer to a cell containing either an * element, or a sublist. *) (# where:< cellPredicate; current: ^theCellType; start:< object; end:< object; listIteratePrivate: @... ... #); iterateFrom: (* similar to iterate, except that it takes a position, and * starts the iteration from that position. *) (# where:< cellPredicate; position: ^theCellType; current: ^theCellType; start:< object; end:< object; listIterateFromPrivate: @... enter position[] ... #); iterateReverse: (* similar to iterate, except that it iterates backwards. *) (# where:< cellPredicate; current: ^theCellType; start:< object; end:< object; listIterateReversePrivate: @... ... #); iterateReverseFrom: (* similar to iterateReverse, except that it takes a position, * and starts the reverse iteration from that position. *) (# where:< cellPredicate; position: ^theCellType; current: ^theCellType; start:< object; end:< object; listIterateReverseFromPrivate: @... enter position[] ... #); cellPredicate: booleanValue (* This pattern is used as the superpattern for the predicates * in the locate and iterate operations. *) (# current: ^theCellType enter current[] do true->value; INNER #); doEnter::< (# containerType::<list; doneInInner:@boolean ... #); private:@...; do INNER #) (* list *); cyclicList: list (* Add operations next and prev to enable traverse the list as a * cycle list *) (# theCellType::< (# prev: (# position: ^theCellType do pred[]->position[]; (if position[]=NONE then last->position[] if); exit position[] #); next: (# position: ^theCellType do succ[]->position[]; (if position[]=NONE then head->position[] if); exit position[] #); #); #); priorityList: list (* implements a priority list where the elements added to the list * are ordered according to their priority (implemented by the * ordering relation 'less') *) (# less:< booleanValue (# left,right: ^element enter (left[],right[]) do INNER #); add: (# elm: ^element; added: @boolean enter elm[] do loop: iterate (# do (if (elm[],current.elm[])->less then (elm[],current[])->insertBefore; true->added; leave loop if) #); (if not added then elm[]->append if) #) #)
6.8 List Interface | © 1992-2002 Mjølner Informatics |
[Modified: Thursday September 9th 1999 at 16:18]
|