diff options
| author | 2024-09-24 18:14:46 -0400 | |
|---|---|---|
| committer | 2024-09-24 18:14:46 -0400 | |
| commit | 0d5f4545d0d3db7c9ec63cac005bb71b85fe6b23 (patch) | |
| tree | b06bed159a4f3df5fbd0f6a58243494657ae21df /linked-list.scm | |
| parent | miniscm: string->symbol and symbol->string (diff) | |
add object helper functions
Diffstat (limited to 'linked-list.scm')
| -rw-r--r-- | linked-list.scm | 93 |
1 files changed, 32 insertions, 61 deletions
diff --git a/linked-list.scm b/linked-list.scm index 356b2b2..c9dff5b 100644 --- a/linked-list.scm +++ b/linked-list.scm @@ -12,71 +12,42 @@ ;;; along with this program. If not, see <https://www.gnu.org/licenses/>. ;;; Singly linked list with tail pointer, message passing style. - -;;; LINKED-LIST-ELEM: ;;; -;;; (NEXT): Goes to the next element, if it exists. Does nothing if the -;;; iterator is at the end of the list. -;;; (GET): Gets the element at this list, signals error if at the end -;;; of the list. -;;; (EMPTY?): True if there are no more values to go to. - -(define linked-list-elem:new - (lambda (ptr) - (lambda args - (let ((op (car args))) - (cond - ((eq? op 'next) - (if (not (null? ptr)) - (set! ptr (cdr ptr)) - #f) - (null? ptr)) - ((eq? op 'get) (car ptr)) - ((eq? op 'empty?) (null? ptr))))))) - ;;; LINKED-LIST: ;;; -;;; (PUSH): Pushes a value to the head of the list. -;;; (PUSH-TAIL): Pushes a value to the end of the list. +;;; (PUSH! VAL): Pushes a value to the head of the list. +;;; (PUSH-TAIL! VAL): Pushes a value to the end of the list. +;;; (SET-CDR! VAL): Set the cdr of TAIL to VAL. This will be overrwitten +;;; if PUSH-TAIL! is called again. ;;; (TO-LIST): Returns a list structure. -;;; (TRAVERSE-FROM-HEAD): Returns an instance of LINKED-LIST-ELEM pointing -;;; to the head of the list. (define linked-list:new (lambda () - (let ((head '()) - (tail '())) - (letrec ((push - (lambda (val) - (set! head (cons val head)) - (if (null? tail) - (set! tail head) - #f))) - (push-tail - (lambda (val) - (if (null? tail) - (push val) - (begin - (set-cdr! tail (cons val '())) - (set! tail (cdr tail)))))) - (%set-cdr! - (lambda (val) - (if (null? tail) - (error "cannot set cdr of empty list") - (set-cdr! tail val))))) - (lambda args - (let ((op (car args))) - (cond - ((eq? op 'push) (apply push (cdr args))) - ((eq? op 'push-tail) (apply push-tail (cdr args))) - ((eq? op 'set-cdr!) (apply %set-cdr! (cdr args))) - ((eq? op 'to-list) head) - ((eq? op 'traverse-from-head) (linked-list-elem:new head)) - (else (error (cons "invalid operation" args)))))))))) - -(define x (linked-list:new)) -(x 'push-tail 1) -(x 'push-tail 2) -(x 'push-tail 3) -(x 'to-list) - + (letrec + ((head '()) + (tail '()) + (this + (object/procedures + 'push! + (lambda (val) + (set! head (cons val head)) + (if (null? tail) + (set! tail head)) + this) + 'push-tail! + (lambda (val) + (if (null? tail) + (this 'push! val) + (begin + (set-cdr! tail (cons val '())) + (set! tail (cdr tail)))) + this) + 'set-cdr! + (lambda (val) + (if (null? tail) + (error "cannot set cdr of empty list") + (set-cdr! tail val)) + this) + 'to-list + (lambda () head)))) + this))) |
