R"lisplibrary( #| Simple Package Manager v2 - 23rd February 2026 by @apiarian. See http://www.ulisp.com/show?5KTN |# (defvar *pkgs* nil) (defun package-load (file) "Load and eval a Lisp file from SD, tracking new symbols as a package. Returns the list of new symbols." (package-unload file) (let ((before (globals))) (with-sd-card (s file) (loop (let ((form (read s))) (unless form (return)) (eval form)))) (let ((new (mapcan (lambda (s) (unless (member s before) (list s))) (globals)))) (setf *pkgs* (cons (cons file new) *pkgs*)) new))) (defun package-save (file) "Save a loaded package's symbols back to file on SD as defun/defvar forms. Returns file." (let ((pkg (assoc file *pkgs* :test #'string=))) (unless pkg (error "package not found: ~a" file)) (with-sd-card (s file 2) (dolist (sym (cdr pkg)) (let ((val (eval sym))) (if (and (consp val) (eq (car val) 'lambda)) (pprint (cons 'defun (cons sym (cdr val))) s) (pprint (list 'defvar sym (list 'quote val)) s))))) file)) (defun package-unload (file) "Unbind all symbols tracked by package file and remove it from *pkgs*." (let ((pkg (assoc file *pkgs* :test #'string=))) (when pkg (dolist (sym (cdr pkg)) (makunbound sym)) (setf *pkgs* (mapcan (lambda (p) (unless (string= (car p) file) (list p))) *pkgs*))))) (defun package-add (file &rest syms) "Add symbols syms to package file's tracking list, creating the package if it doesn't exist. Returns syms." (let ((pkg (assoc file *pkgs* :test #'string=))) (unless pkg (setf *pkgs* (cons (cons file nil) *pkgs*)) (setf pkg (car *pkgs*))) (dolist (sym syms) (unless (atom sym) (error "please quote symbols")) (unless (member sym (cdr pkg)) (setf (cdr pkg) (cons sym (cdr pkg))))) syms)) (defun package-remove (file sym &optional unbind) "Remove sym from package file's tracking list. If unbind is true, also makunbound sym. Returns sym." (let ((pkg (assoc file *pkgs* :test #'string=))) (unless pkg (error "package not found: ~a" file)) (setf (cdr pkg) (mapcan (lambda (s) (unless (eq s sym) (list s))) (cdr pkg))) (when unbind (makunbound sym)) sym)) (defun package-symbols (file) "Return the list of symbols tracked by package file." (let ((pkg (assoc file *pkgs* :test #'string=))) (unless pkg (error "package not found: ~a" file)) (cdr pkg))) (defun package-list () "Return a list of all loaded package filenames." (mapcar #'car *pkgs*)) )lisplibrary"