(define (new-directory-structure) (let* ((root (list 'DIRECTORY '/ '( ))) (working-directory root) ) ;; Change the working directory to the directory with the given name ;; (an entry in the working directory), or to the parent directory ;; if the name "^" is specified. Do nothing if a "cd ^" command is ;; given from the root directory. (define (execute-cd name) (if (eq? name '^) (if (not (null? (parent working-directory))) _____ ) (let ((dir (find-if (lambda (entry) (eq? (entry-name entry) name)) (file-entries working-directory) ) )) (cond ((not dir) (print-err-msg (append '(no file named) (list name))) ) ((not (eq? (entry-type dir) 'DIRECTORY)) (print-err-msg (cons name '(not a directory))) ) (else _____ ) ) ) ) ) ;; Create a directory with the given name in the working directory. ;; The ls command should list this directory's name before that of any ;; of the other entries already in the working directory. (define (execute-mkdir name) (let ((already-there (find-if (lambda (entry) (eq? (entry-name entry) name)) (file-entries working-directory) ) )) (if already-there (print-err-msg (cons name '(already exists))) _____ ) ) ) ;; Create a non-directory file with the given name in the working directory. ;; The ls command should list this file's name before that of any ;; of the other entries already in the working directory. (define (execute-create name) (let ((already-there (find-if (lambda (entry) (eq? (entry-name entry) name)) (file-entries working-directory) ) )) (if already-there (print-err-msg (cons name '(already exists))) _____ ) ) ) ;; Remove the entry with the given name from the working directory. (define (execute-rm name) (let ((dir (find-if (lambda (entry) (eq? (entry-name entry) name)) (file-entries working-directory) ) )) (if (not entry) (print-err-msg (append '(no file named) (list name))) _____ ) ) ) ;; Rename the entry named old-name to have name new-name. ;; (An entry named old-name must already exist in the working directory.) ;; Do this by first removing any entry already named new-name, then ;; updating the name of the entry named old-name. (define (execute-mv old-name new-name) (let ((old-entry (find-if (lambda (entry) (eq? (entry-name entry) old-name)) (file-entries working-directory) ) ) (new-entry (find-if (lambda (entry) (eq? (entry-name entry) new-name)) (file-entries working-directory) ) )) (cond ((not old-entry) (print-err-msg (append '(no file named) (list old-name))) ) ((not new-entry) _____ ) (else _____ ) ) ) ) ;; List the names of entries in the working directory. (define (execute-ls) (display (map entry-name (file-entries working-directory))) (newline) ) ;; Print the path from the root directory to the working directory. (define (execute-pwd) (print-from-root-to working-directory) (newline) ) (define (respond-to-msg msg) (cond ((eq? msg 'cd) execute-cd) ((eq? msg 'mkdir) execute-mkdir) ((eq? msg 'create) execute-create) ((eq? msg 'rm) execute-rm) ((eq? msg 'mv) execute-mv) ((eq? msg 'ls) (execute-ls)) ((eq? msg 'pwd) (execute-pwd)) (else (error "unrecognized message")) ) ) respond-to-msg ) ) (define (entry-type entry) (car entry)) (define (entry-name entry) (cadr entry)) (define (parent directory) (caddr directory)) (define (file-entries directory) (cdddr directory)) (define (new-directory name current-dir) (list 'directory name current-dir)) (define (new-file name) (list 'file name)) (define (print-from-root-to directory) (if (null? (parent directory)) (display (entry-name directory)) (begin (print-from-root-to (parent directory)) (display (entry-name directory)) (display '/) ) ) ) (define (find-if pred? L) (cond ((null? L) #f) ((pred? (car L)) (car L)) (else (find-if pred? (cdr L))) ) ) (define (print-err-msg msg) (display msg) (newline) )