changelog shortlog graph tags branches files raw help

Mercurial > core / changeset: std/tests, clap tweaks

changeset 563: 8b10eabe89dd
parent 562: 18143155dc5c
child 564: 953ef5152f84
author: Richard Westhaver <ellis@rwest.io>
date: Sun, 28 Jul 2024 20:49:47 -0400
files: emacs/lib/publish.el lisp/bin/skel.lisp lisp/lib/cli/clap/macs.lisp lisp/lib/cli/clap/opt.lisp lisp/lib/cli/clap/vars.lisp lisp/lib/io/pkg.lisp lisp/std/condition.lisp lisp/std/err.lisp lisp/std/num/leb128.lisp lisp/std/pkg.lisp lisp/std/std.asd lisp/std/tests.lisp lisp/std/tests/num.lisp lisp/std/tests/pkg.lisp lisp/std/tests/task.lisp lisp/std/tests/tasks.lisp
description: std/tests, clap tweaks
     1.1--- a/emacs/lib/publish.el	Sat Jul 27 00:40:29 2024 -0400
     1.2+++ b/emacs/lib/publish.el	Sun Jul 28 20:49:47 2024 -0400
     1.3@@ -8,7 +8,7 @@
     1.4 ;; vendored
     1.5 (require 'htmlize)
     1.6 (defvar project-dir "~/comp/org")
     1.7-(defvar publish-dir "/mnt/y/stash/compiler.company")
     1.8+(defvar publish-dir "/tmp/www")
     1.9 (defvar html-theme nil)
    1.10 (defvar url "https://compiler.company")
    1.11 (defvar vc-url "https://vc.compiler.company")
     2.1--- a/lisp/bin/skel.lisp	Sat Jul 27 00:40:29 2024 -0400
     2.2+++ b/lisp/bin/skel.lisp	Sun Jul 28 20:49:47 2024 -0400
     2.3@@ -32,7 +32,8 @@
     2.4 
     2.5 (defcmd skc-init
     2.6   (let ((file (when *args* (pop *args*)))
     2.7-	(name (when (> *argc* 1) (pop *args*)))) ;; TODO: test, may need to be
     2.8+	(name (when (> *argc* 1) (pop *args*))))
     2.9+    ;; TODO: test, may need to be
    2.10     ;; sequential for side-effect
    2.11     ;; of pop
    2.12     (handler-bind
     3.1--- a/lisp/lib/cli/clap/macs.lisp	Sat Jul 27 00:40:29 2024 -0400
     3.2+++ b/lisp/lib/cli/clap/macs.lisp	Sun Jul 28 20:49:47 2024 -0400
     3.3@@ -32,7 +32,8 @@
     3.4 ;; TODO fix these macros
     3.5 (defmacro defcmd (name &body body)
     3.6   `(defun ,name (args opts) 
     3.7-     (declare (ignorable args opts))
     3.8+     (declare (ignorable args opts)
     3.9+              (list args opts))
    3.10      (setq
    3.11       *argc* (length args)
    3.12       *optc* (length opts)
    3.13@@ -42,7 +43,7 @@
    3.14 
    3.15 (defmacro defopt (name &body body)
    3.16   `(defun ,name (&optional arg)
    3.17-     (declare (ignorable arg))
    3.18+     (declare (ignorable arg) (list arg))
    3.19      (setq *arg* arg)
    3.20        ,@body))
    3.21 
     4.1--- a/lisp/lib/cli/clap/opt.lisp	Sat Jul 27 00:40:29 2024 -0400
     4.2+++ b/lisp/lib/cli/clap/opt.lisp	Sun Jul 28 20:49:47 2024 -0400
     4.3@@ -6,7 +6,6 @@
     4.4 (in-package :cli/clap/obj)
     4.5 
     4.6 ;;; Parsers
     4.7-;;  TODO 2024-03-16: this should map directly to Lisp types (fixnum, boolean, etc)
     4.8 (make-opt-parser string $val)
     4.9 
    4.10 (make-opt-parser boolean (when $val t))
     5.1--- a/lisp/lib/cli/clap/vars.lisp	Sat Jul 27 00:40:29 2024 -0400
     5.2+++ b/lisp/lib/cli/clap/vars.lisp	Sun Jul 28 20:49:47 2024 -0400
     5.3@@ -36,7 +36,7 @@
     5.4   "Current command options.
     5.5 Bound for the lifetime of a DEFOPT function.")
     5.6 
     5.7-(declaim (integer *argc* *optc*))
     5.8+(declaim (unsigned-byte *argc* *optc*))
     5.9 (defvar *argc* 0
    5.10   "Current count of command arguments.
    5.11 This value may be updated throughout the lifetime of a function defined with
     6.1--- a/lisp/lib/io/pkg.lisp	Sat Jul 27 00:40:29 2024 -0400
     6.2+++ b/lisp/lib/io/pkg.lisp	Sun Jul 28 20:49:47 2024 -0400
     6.3@@ -13,7 +13,7 @@
     6.4 
     6.5 ;;; Code:
     6.6 (defpackage :io/proto
     6.7-  (:use :cl :std/err)
     6.8+  (:use :cl :std/condition)
     6.9   (:export :io-error))
    6.10 
    6.11 (defpackage :io/ring
     7.1--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2+++ b/lisp/std/condition.lisp	Sun Jul 28 20:49:47 2024 -0400
     7.3@@ -0,0 +1,193 @@
     7.4+;;; condition.lisp --- Conditions and other exception handlers
     7.5+
     7.6+;;; Code:
     7.7+(in-package :std/condition)
     7.8+
     7.9+(defvar *std-error-message* "An error occured")
    7.10+
    7.11+(define-condition std-error (error)
    7.12+  ((message :initarg :message
    7.13+            :initform *std-error-message*
    7.14+            :reader std-error-message))
    7.15+  (:documentation "Std Error")
    7.16+  (:report (lambda (condition stream)
    7.17+             (format stream "~X" (std-error-message condition)))))
    7.18+
    7.19+(defun std-error (&rest args)
    7.20+  (cerror
    7.21+   "Ignore and continue"
    7.22+   'std-error
    7.23+   :message (format nil "~A: ~A" *std-error-message* args)))
    7.24+
    7.25+(defun car-eql (a cons)
    7.26+  (eql a (car cons)))
    7.27+
    7.28+(defmacro deferror (name (&rest parent-types) (&rest slot-specs) &rest options)
    7.29+  "Define an error condition."
    7.30+  (let ((fun (member :auto options :test #'car-eql)))
    7.31+    (when fun (setq options (remove (car fun) options)))
    7.32+    `(prog1
    7.33+         (define-condition ,name ,(or parent-types '(std-error)) ,slot-specs ,@options)
    7.34+       (when ',fun (def-error-reporter ,name)))))
    7.35+
    7.36+(defmacro def-error-reporter (err)
    7.37+    `(defun ,err (&rest args)
    7.38+       ,(format nil "Signal an error of type ~A with ARGS." err)
    7.39+       (cerror
    7.40+        "Ignore and continue"
    7.41+        ',err
    7.42+        :message (format nil "~A: ~A" *std-error-message* args))))
    7.43+
    7.44+(defmacro nyi! (&optional comment)
    7.45+  `(prog1
    7.46+       (error "Not Yet Implemented!")
    7.47+     (when ',comment (print ',comment))))
    7.48+
    7.49+(defun required-argument (&optional name)
    7.50+  "Signals an error for a missing argument of NAME. Intended for
    7.51+use as an initialization form for structure and class-slots, and
    7.52+a default value for required keyword arguments."
    7.53+  (error "Required argument ~@[~S ~]missing." name))
    7.54+
    7.55+(define-condition simple-style-warning (simple-warning style-warning)
    7.56+  ())
    7.57+
    7.58+(defun simple-style-warning (message &rest args)
    7.59+  (warn 'simple-style-warning :format-control message :format-arguments args))
    7.60+
    7.61+;; We don't specify a :report for simple-reader-error to let the
    7.62+;; underlying implementation report the line and column position for
    7.63+;; us. Unfortunately this way the message from simple-error is not
    7.64+;; displayed, unless there's special support for that in the
    7.65+;; implementation. But even then it's still inspectable from the
    7.66+;; debugger...
    7.67+(define-condition simple-reader-error
    7.68+    (sb-int:simple-reader-error)
    7.69+  ())
    7.70+
    7.71+(defun simple-reader-error (stream message &rest args)
    7.72+  (error 'simple-reader-error
    7.73+         :stream stream
    7.74+         :format-control message
    7.75+         :format-arguments args))
    7.76+
    7.77+(define-condition simple-parse-error (simple-error parse-error)
    7.78+  ())
    7.79+
    7.80+(defun simple-parse-error (message &rest args)
    7.81+  (error 'simple-parse-error
    7.82+         :format-control message
    7.83+         :format-arguments args))
    7.84+
    7.85+(define-condition simple-program-error (simple-error program-error)
    7.86+  ())
    7.87+
    7.88+(defun simple-program-error (message &rest args)
    7.89+  (error 'simple-program-error
    7.90+         :format-control message
    7.91+         :format-arguments args))
    7.92+
    7.93+(define-condition circular-dependency (simple-error)
    7.94+  ((items
    7.95+    :initarg :items
    7.96+    :initform (error "Must specify items")
    7.97+    :reader circular-dependency-items))
    7.98+  (:report (lambda (condition stream)
    7.99+             (declare (ignore condition))
   7.100+             (format stream "Circular dependency detected")))
   7.101+  (:documentation "A condition which is signalled when a circular dependency is encountered."))
   7.102+
   7.103+(define-condition unknown-argument (error)
   7.104+  ((name
   7.105+    :initarg :name
   7.106+    :initform (error "Must specify argument name")
   7.107+    :reader unknown-argument-name)
   7.108+   (kind
   7.109+    :initarg :kind
   7.110+    :initform (error "Must specify argument kind")
   7.111+    :reader unknown-argument-kind))
   7.112+  (:report (lambda (condition stream)
   7.113+             (format stream "Unknown argument ~A of kind ~A"
   7.114+                     (unknown-argument-name condition)
   7.115+                     (unknown-argument-kind condition))))
   7.116+  (:documentation "A condition which is signalled when an unknown argument is encountered."))
   7.117+
   7.118+(defun unknown-argument-p (value)
   7.119+  (typep value 'unknown-argument))
   7.120+
   7.121+(define-condition missing-argument (simple-error)
   7.122+  ((item
   7.123+    :initarg :item
   7.124+    :initform (error "Must specify argument item")
   7.125+    :reader missing-argument-item)
   7.126+   (command
   7.127+    :initarg :command
   7.128+    :initform (error "Must specify command")
   7.129+    :reader missing-argument-command))
   7.130+  (:report (lambda (condition stream)
   7.131+             (declare (ignore condition))
   7.132+             (format stream "Missing argument")))
   7.133+  (:documentation "A condition which is signalled when an option expects an argument, but none was provided"))
   7.134+
   7.135+(defun missing-argument-p (value)
   7.136+  (typep value 'missing-argument))
   7.137+
   7.138+(define-condition invalid-argument (simple-error)
   7.139+  ((item
   7.140+    :initarg :item
   7.141+    :initform (error "Must specify argument item")
   7.142+    :reader invalid-argument-item
   7.143+    :documentation "The argument which is identified as invalid")
   7.144+   (reason
   7.145+    :initarg :reason
   7.146+    :initform (error "Must specify reason")
   7.147+    :reader invalid-argument-reason
   7.148+    :documentation "The reason why this argument is invalid"))
   7.149+  (:report (lambda (condition stream)
   7.150+             (format stream "Invalid argument: ~A~%Reason: ~A" (invalid-argument-item condition) (invalid-argument-reason condition))))
   7.151+  (:documentation "A condition which is signalled when an argument is identified as invalid."))
   7.152+
   7.153+(defmacro ignore-some-conditions ((&rest conditions) &body body)
   7.154+  "Similar to CL:IGNORE-ERRORS but the (unevaluated) CONDITIONS
   7.155+list determines which specific conditions are to be ignored."
   7.156+  `(handler-case
   7.157+       (progn ,@body)
   7.158+     ,@(loop for condition in conditions collect
   7.159+             `(,condition (c) (values nil c)))))
   7.160+
   7.161+(defmacro unwind-protect-case ((&optional abort-flag) protected-form &body clauses)
   7.162+  "Like CL:UNWIND-PROTECT, but you can specify the circumstances that
   7.163+the cleanup CLAUSES are run.
   7.164+
   7.165+  clauses ::= (:NORMAL form*)* | (:ABORT form*)* | (:ALWAYS form*)*
   7.166+
   7.167+Clauses can be given in any order, and more than one clause can be
   7.168+given for each circumstance. The clauses whose denoted circumstance
   7.169+occured, are executed in the order the clauses appear.
   7.170+
   7.171+ABORT-FLAG is the name of a variable that will be bound to T in
   7.172+CLAUSES if the PROTECTED-FORM aborted preemptively, and to NIL
   7.173+otherwise.
   7.174+
   7.175+Examples:
   7.176+
   7.177+  (unwind-protect-case ()
   7.178+       (protected-form)
   7.179+     (:normal (format t \"This is only evaluated if PROTECTED-FORM executed normally.~%\"))
   7.180+     (:abort  (format t \"This is only evaluated if PROTECTED-FORM aborted preemptively.~%\"))
   7.181+     (:always (format t \"This is evaluated in either case.~%\")))
   7.182+
   7.183+  (unwind-protect-case (aborted-p)
   7.184+       (protected-form)
   7.185+     (:always (perform-cleanup-if aborted-p)))
   7.186+"
   7.187+  (check-type abort-flag (or null symbol))
   7.188+  (let ((gflag (gensym "FLAG+")))
   7.189+    `(let ((,gflag t))
   7.190+       (unwind-protect (multiple-value-prog1 ,protected-form (setf ,gflag nil))
   7.191+	 (let ,(and abort-flag `((,abort-flag ,gflag)))
   7.192+	   ,@(loop for (cleanup-kind . forms) in clauses
   7.193+		   collect (ecase cleanup-kind
   7.194+			     (:normal `(when (not ,gflag) ,@forms))
   7.195+			     (:abort  `(when ,gflag ,@forms))
   7.196+			     (:always `(progn ,@forms)))))))))
     8.1--- a/lisp/std/err.lisp	Sat Jul 27 00:40:29 2024 -0400
     8.2+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3@@ -1,193 +0,0 @@
     8.4-;;; err.lisp --- Conditions and other exception handlers
     8.5-
     8.6-;;; Code:
     8.7-(in-package :std/err)
     8.8-
     8.9-(defvar *std-error-message* "An error occured")
    8.10-
    8.11-(define-condition std-error (error)
    8.12-  ((message :initarg :message
    8.13-            :initform *std-error-message*
    8.14-            :reader std-error-message))
    8.15-  (:documentation "Std Error")
    8.16-  (:report (lambda (condition stream)
    8.17-             (format stream "~X" (std-error-message condition)))))
    8.18-
    8.19-(defun std-error (&rest args)
    8.20-  (cerror
    8.21-   "Ignore and continue"
    8.22-   'std-error
    8.23-   :message (format nil "~A: ~A" *std-error-message* args)))
    8.24-
    8.25-(defun car-eql (a cons)
    8.26-  (eql a (car cons)))
    8.27-
    8.28-(defmacro deferror (name (&rest parent-types) (&rest slot-specs) &rest options)
    8.29-  "Define an error condition."
    8.30-  (let ((fun (member :auto options :test #'car-eql)))
    8.31-    (when fun (setq options (remove (car fun) options)))
    8.32-    `(prog1
    8.33-         (define-condition ,name ,(or parent-types '(std-error)) ,slot-specs ,@options)
    8.34-       (when ',fun (def-error-reporter ,name)))))
    8.35-
    8.36-(defmacro def-error-reporter (err)
    8.37-    `(defun ,err (&rest args)
    8.38-       ,(format nil "Signal an error of type ~A with ARGS." err)
    8.39-       (cerror
    8.40-        "Ignore and continue"
    8.41-        ',err
    8.42-        :message (format nil "~A: ~A" *std-error-message* args))))
    8.43-
    8.44-(defmacro nyi! (&optional comment)
    8.45-  `(prog1
    8.46-       (error "Not Yet Implemented!")
    8.47-     (when ',comment (print ',comment))))
    8.48-
    8.49-(defun required-argument (&optional name)
    8.50-  "Signals an error for a missing argument of NAME. Intended for
    8.51-use as an initialization form for structure and class-slots, and
    8.52-a default value for required keyword arguments."
    8.53-  (error "Required argument ~@[~S ~]missing." name))
    8.54-
    8.55-(define-condition simple-style-warning (simple-warning style-warning)
    8.56-  ())
    8.57-
    8.58-(defun simple-style-warning (message &rest args)
    8.59-  (warn 'simple-style-warning :format-control message :format-arguments args))
    8.60-
    8.61-;; We don't specify a :report for simple-reader-error to let the
    8.62-;; underlying implementation report the line and column position for
    8.63-;; us. Unfortunately this way the message from simple-error is not
    8.64-;; displayed, unless there's special support for that in the
    8.65-;; implementation. But even then it's still inspectable from the
    8.66-;; debugger...
    8.67-(define-condition simple-reader-error
    8.68-    (sb-int:simple-reader-error)
    8.69-  ())
    8.70-
    8.71-(defun simple-reader-error (stream message &rest args)
    8.72-  (error 'simple-reader-error
    8.73-         :stream stream
    8.74-         :format-control message
    8.75-         :format-arguments args))
    8.76-
    8.77-(define-condition simple-parse-error (simple-error parse-error)
    8.78-  ())
    8.79-
    8.80-(defun simple-parse-error (message &rest args)
    8.81-  (error 'simple-parse-error
    8.82-         :format-control message
    8.83-         :format-arguments args))
    8.84-
    8.85-(define-condition simple-program-error (simple-error program-error)
    8.86-  ())
    8.87-
    8.88-(defun simple-program-error (message &rest args)
    8.89-  (error 'simple-program-error
    8.90-         :format-control message
    8.91-         :format-arguments args))
    8.92-
    8.93-(define-condition circular-dependency (simple-error)
    8.94-  ((items
    8.95-    :initarg :items
    8.96-    :initform (error "Must specify items")
    8.97-    :reader circular-dependency-items))
    8.98-  (:report (lambda (condition stream)
    8.99-             (declare (ignore condition))
   8.100-             (format stream "Circular dependency detected")))
   8.101-  (:documentation "A condition which is signalled when a circular dependency is encountered."))
   8.102-
   8.103-(define-condition unknown-argument (error)
   8.104-  ((name
   8.105-    :initarg :name
   8.106-    :initform (error "Must specify argument name")
   8.107-    :reader unknown-argument-name)
   8.108-   (kind
   8.109-    :initarg :kind
   8.110-    :initform (error "Must specify argument kind")
   8.111-    :reader unknown-argument-kind))
   8.112-  (:report (lambda (condition stream)
   8.113-             (format stream "Unknown argument ~A of kind ~A"
   8.114-                     (unknown-argument-name condition)
   8.115-                     (unknown-argument-kind condition))))
   8.116-  (:documentation "A condition which is signalled when an unknown argument is encountered."))
   8.117-
   8.118-(defun unknown-argument-p (value)
   8.119-  (typep value 'unknown-argument))
   8.120-
   8.121-(define-condition missing-argument (simple-error)
   8.122-  ((item
   8.123-    :initarg :item
   8.124-    :initform (error "Must specify argument item")
   8.125-    :reader missing-argument-item)
   8.126-   (command
   8.127-    :initarg :command
   8.128-    :initform (error "Must specify command")
   8.129-    :reader missing-argument-command))
   8.130-  (:report (lambda (condition stream)
   8.131-             (declare (ignore condition))
   8.132-             (format stream "Missing argument")))
   8.133-  (:documentation "A condition which is signalled when an option expects an argument, but none was provided"))
   8.134-
   8.135-(defun missing-argument-p (value)
   8.136-  (typep value 'missing-argument))
   8.137-
   8.138-(define-condition invalid-argument (simple-error)
   8.139-  ((item
   8.140-    :initarg :item
   8.141-    :initform (error "Must specify argument item")
   8.142-    :reader invalid-argument-item
   8.143-    :documentation "The argument which is identified as invalid")
   8.144-   (reason
   8.145-    :initarg :reason
   8.146-    :initform (error "Must specify reason")
   8.147-    :reader invalid-argument-reason
   8.148-    :documentation "The reason why this argument is invalid"))
   8.149-  (:report (lambda (condition stream)
   8.150-             (format stream "Invalid argument: ~A~%Reason: ~A" (invalid-argument-item condition) (invalid-argument-reason condition))))
   8.151-  (:documentation "A condition which is signalled when an argument is identified as invalid."))
   8.152-
   8.153-(defmacro ignore-some-conditions ((&rest conditions) &body body)
   8.154-  "Similar to CL:IGNORE-ERRORS but the (unevaluated) CONDITIONS
   8.155-list determines which specific conditions are to be ignored."
   8.156-  `(handler-case
   8.157-       (progn ,@body)
   8.158-     ,@(loop for condition in conditions collect
   8.159-             `(,condition (c) (values nil c)))))
   8.160-
   8.161-(defmacro unwind-protect-case ((&optional abort-flag) protected-form &body clauses)
   8.162-  "Like CL:UNWIND-PROTECT, but you can specify the circumstances that
   8.163-the cleanup CLAUSES are run.
   8.164-
   8.165-  clauses ::= (:NORMAL form*)* | (:ABORT form*)* | (:ALWAYS form*)*
   8.166-
   8.167-Clauses can be given in any order, and more than one clause can be
   8.168-given for each circumstance. The clauses whose denoted circumstance
   8.169-occured, are executed in the order the clauses appear.
   8.170-
   8.171-ABORT-FLAG is the name of a variable that will be bound to T in
   8.172-CLAUSES if the PROTECTED-FORM aborted preemptively, and to NIL
   8.173-otherwise.
   8.174-
   8.175-Examples:
   8.176-
   8.177-  (unwind-protect-case ()
   8.178-       (protected-form)
   8.179-     (:normal (format t \"This is only evaluated if PROTECTED-FORM executed normally.~%\"))
   8.180-     (:abort  (format t \"This is only evaluated if PROTECTED-FORM aborted preemptively.~%\"))
   8.181-     (:always (format t \"This is evaluated in either case.~%\")))
   8.182-
   8.183-  (unwind-protect-case (aborted-p)
   8.184-       (protected-form)
   8.185-     (:always (perform-cleanup-if aborted-p)))
   8.186-"
   8.187-  (check-type abort-flag (or null symbol))
   8.188-  (let ((gflag (gensym "FLAG+")))
   8.189-    `(let ((,gflag t))
   8.190-       (unwind-protect (multiple-value-prog1 ,protected-form (setf ,gflag nil))
   8.191-	 (let ,(and abort-flag `((,abort-flag ,gflag)))
   8.192-	   ,@(loop for (cleanup-kind . forms) in clauses
   8.193-		   collect (ecase cleanup-kind
   8.194-			     (:normal `(when (not ,gflag) ,@forms))
   8.195-			     (:abort  `(when ,gflag ,@forms))
   8.196-			     (:always `(progn ,@forms)))))))))
     9.1--- a/lisp/std/num/leb128.lisp	Sat Jul 27 00:40:29 2024 -0400
     9.2+++ b/lisp/std/num/leb128.lisp	Sun Jul 28 20:49:47 2024 -0400
     9.3@@ -88,7 +88,7 @@
     9.4          (incf in))
     9.5     ret))
     9.6 
     9.7-(declaim (ftype (function ((vector unsigned-byte) &optional t) integer) decode-uleb128))
     9.8+(declaim (ftype (function (vector &optional t) integer) decode-uleb128))
     9.9 (defun decode-uleb128 (bits &optional (start 0))
    9.10   "Decode an unsigned integer from ULEB128 byte array."
    9.11   (let ((result 0) (shift 0) (curr) (counter 0))
    10.1--- a/lisp/std/pkg.lisp	Sat Jul 27 00:40:29 2024 -0400
    10.2+++ b/lisp/std/pkg.lisp	Sun Jul 28 20:49:47 2024 -0400
    10.3@@ -9,7 +9,7 @@
    10.4 
    10.5 (in-package :std-int)
    10.6 
    10.7-(defpackage :std/err
    10.8+(defpackage :std/condition
    10.9   (:use :cl)
   10.10   (:export    ;; err
   10.11    :std-error :std-error-message
   10.12@@ -448,7 +448,7 @@
   10.13 
   10.14 (defpkg :std
   10.15   (:use :cl :sb-unicode :cl-ppcre :sb-mop :sb-c :sb-thread :sb-alien :sb-gray :sb-concurrency)
   10.16-  (:use-reexport :std/named-readtables :std/defpkg :std/err
   10.17+  (:use-reexport :std/named-readtables :std/defpkg :std/condition
   10.18    :std/sym :std/list :std/type :std/num
   10.19    :std/stream :std/fu :std/array :std/hash-table
   10.20    :std/alien :std/mop :std/thread :std/task
    11.1--- a/lisp/std/std.asd	Sat Jul 27 00:40:29 2024 -0400
    11.2+++ b/lisp/std/std.asd	Sun Jul 28 20:49:47 2024 -0400
    11.3@@ -21,7 +21,7 @@
    11.4   :serial t
    11.5   :components ((:file "defpkg")
    11.6                (:file "pkg")
    11.7-               (:file "err")
    11.8+               (:file "condition")
    11.9                (:file "sym")
   11.10                (:file "list")
   11.11                (:file "type")
   11.12@@ -65,5 +65,9 @@
   11.13 (defsystem :std/tests
   11.14   :depends-on (:std :rt)
   11.15   :serial t
   11.16-  :components ((:file "tests"))
   11.17+  :components ((:module "tests"
   11.18+                :components
   11.19+                ((:file "pkg")
   11.20+                 (:file "num")
   11.21+                 (:file "task"))))
   11.22   :perform (test-op (o c) (symbol-call :rt :do-tests :std)))
    12.1--- a/lisp/std/tests.lisp	Sat Jul 27 00:40:29 2024 -0400
    12.2+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3@@ -1,276 +0,0 @@
    12.4-;;; tests.lisp --- std system tests
    12.5-
    12.6-;;; Commentary:
    12.7-
    12.8-;; TODO: fix false positives when using (eval-test)
    12.9-
   12.10-;;; Code:
   12.11-(in-package :std-int)
   12.12-(defpkg :std/tests
   12.13-  (:use :cl :std :rt :sb-thread :std/fu))
   12.14-(in-package :std/tests)
   12.15-(defsuite :std)
   12.16-(in-suite :std)
   12.17-(in-readtable :std)
   12.18-;; prevent threadlocks
   12.19-;; (setf sb-unix::*on-dangerous-wait* :error)
   12.20-
   12.21-;; TODO 2024-05-14: fix compilation order of std/fu vs std/readtables
   12.22-(deftest readtables (:skip nil)
   12.23-  "Test :std readtable"
   12.24-  (is (typep #`(,a1 ,a1 ',a1 ,@a1) 'function))
   12.25-  (is (string= #"test "foo" "# "test \"foo\" "))
   12.26-  ;; from curry-compose-reader-macros test suite
   12.27-  (is (equal (funcall {list 1} 2) '(1 2))) ;; curry.1
   12.28-  (is (equal (mapcar {+ 1} '(1 2 3 4)) '(2 3 4 5))) ;; curry.2
   12.29-  (is (equal (funcall {1 list 1} 2) '(1 2))) ;; curry.fixed-arity
   12.30-  (is (equal (funcall {2 list _ 2} 3 4) '(3 4 2))) ;; curry.fixed-arity.2
   12.31-  (signals error
   12.32-    (let ((f {1 list 1}))
   12.33-      (progn (funcall f) nil))) ;; curry.fixed-arity.1
   12.34-  (signals error
   12.35-    (locally (declare (optimize safety))
   12.36-      (let ((f {1 list 1}))
   12.37-        (progn (funcall f 'a 'b) nil)))) ;; curry.fixed-arity-error.2
   12.38-  (is (equal (funcall {list _ 1} 2) '(2 1))) ;; rcurry.1
   12.39-  (is (equal (mapcar {- _ 1} '(1 2 3 4)) '(0 1 2 3))) ;; rcurry.2
   12.40-  (is (equal (funcall [{* 3} #'1+] 1) 6)) ;; compose.1
   12.41-  (is (equal (funcall ['1+ '1+] 1) 3)) ;; compose.2
   12.42-  (is (equal (funcall [#'1+] 1) 2)) ;; compose.3
   12.43-  (is (equal (funcall [#'values] 1 2 3) (values 1 2 3))) ;; compose.4
   12.44-  (is (equal (funcall «list {* 2} {* 3}» 4) '(8 12))) ;; join.1
   12.45-  (is (equal (mapcar «and {< 2} 'evenp (constantly t)» '(1 2 3 4)) (list nil nil nil t))) ;; join.2
   12.46-  ;; typecase-bracket
   12.47-  (is (equal (mapcar ‹typecase (number #'1+) (string :str)› '(1 "this" 2 "that")) '(2 :str 3 :str)))
   12.48-  ;; cond-bracket
   12.49-  (is (equal (mapcar ‹cond (#'evenp {+ 100}) (#'oddp {+ 200})› '(1 2 3 4)) '(201 102 203 104)))
   12.50-  ;; if-bracket
   12.51-  (is (equal (mapcar ‹if #'evenp {list :a} {list :b}› '(1 2 3 4))
   12.52-             '((:b 1) (:a 2) (:b 3) (:a 4))))
   12.53-  ;; when-bracket
   12.54-  (is (equal (mapcar ‹when 'evenp {+ 4}› '(1 2 3 4)) (list nil 6 nil 8)))
   12.55-  ;; unless-bracket
   12.56-  (is (equal (mapcar ‹unless 'evenp {+ 4}› '(1 2 3 4)) (list 5 nil 7 nil))))
   12.57-
   12.58-(deftest sym ()
   12.59-  "Test standard symbol utils"
   12.60-  ;; gensyms
   12.61-  (is (not (equalp (make-gensym 'a) (make-gensym 'a))))
   12.62-  (is (eq 'std/tests::foo (format-symbol :std/tests "~A" 'foo)))
   12.63-  (is (eq (make-keyword 'fizz) :fizz)))
   12.64-
   12.65-;;;; TODO
   12.66-(deftest string ()
   12.67-  "Test standard string utils"
   12.68-  (is (typep "test" 'string-designator))
   12.69-  (is (typep 'test 'string-designator))
   12.70-  (is (typep #\C 'string-designator))
   12.71-  (is (not (typep 0 'string-designator))))
   12.72-
   12.73-(deftest list ()
   12.74-  "Test standard list utils"
   12.75-  ;; same object - a literal
   12.76-  (is (eq (ensure-car '(0)) (ensure-car 0)))
   12.77-  (is (eq (ensure-car '(nil)) (ensure-car nil)))
   12.78-  ;; different objects
   12.79-  (is (not (eq (ensure-cons 0) (ensure-cons 0))))
   12.80-  (is (equal (ensure-cons 0) (ensure-cons 0))))
   12.81-
   12.82-(deftest err ()
   12.83-  "Test standard error handlers"
   12.84-  (is (eql 'testing-err (deferror testing-err (std-error) nil (:auto t) (:documentation "testing")))))
   12.85-
   12.86-(deftest threads ()
   12.87-  "Test standard thread functionality."
   12.88-  (is (eq *current-thread*
   12.89-          (find (thread-name *current-thread*) (list-all-threads)
   12.90-                :key #'thread-name :test #'equal)))
   12.91-  (is (find-thread-by-id (car (thread-id-list))))
   12.92-  (is (not (zerop (thread-count))))
   12.93-  (let ((threads
   12.94-          (make-threads 4 (lambda () (is (= 42 (1+ 41)))) :name "threads")))
   12.95-    (loop for th in threads
   12.96-          do (sb-thread:join-thread th))
   12.97-    (loop for th in threads
   12.98-          collect (is (not (sb-thread:thread-alive-p th)))))
   12.99-  (let ((m (make-mutex :name "mutex-test")))
  12.100-    (is
  12.101-     (and (not
  12.102-           (with-mutex (m)
  12.103-             (join-thread
  12.104-              (make-thread (lambda ()
  12.105-                             (with-mutex (m :timeout 0.1)
  12.106-                               t))))))
  12.107-          (join-thread
  12.108-           (make-thread (lambda ()
  12.109-                          (with-mutex (m :timeout 0.1)
  12.110-                            t)))))))
  12.111-  (let* ((sym (gensym))
  12.112-         (s (make-semaphore :name "semaphore-test"))
  12.113-         (th (make-thread (lambda () (wait-on-semaphore s)))))
  12.114-    (is (equal (multiple-value-list (join-thread th :timeout .001 :default sym))
  12.115-               (list sym :timeout)))
  12.116-    (signal-semaphore s)
  12.117-    (is (join-thread th)))
  12.118-  (signals join-thread-error (join-thread *current-thread*))
  12.119-  (is
  12.120-   (let ((m (make-mutex :name "rlock-test")))
  12.121-     (is (not (with-mutex (m) (join-thread (make-thread (lambda () (with-recursive-lock (m :wait-p nil) t)))))))
  12.122-     (join-thread (make-thread (lambda () (with-recursive-lock (m :wait-p nil) t))))))
  12.123-  (let ((queue (make-waitqueue :name "queue-test"))
  12.124-        (lock (make-mutex :name "lock-test"))
  12.125-        (n 0)
  12.126-        th)
  12.127-    (labels ((in-new-thread ()
  12.128-               (with-mutex (lock)
  12.129-                 (assert (eql (mutex-owner lock) *current-thread*))
  12.130-                 (condition-wait queue lock)
  12.131-                 (assert (eql (mutex-owner lock) *current-thread*))
  12.132-                 (is (= n 1))
  12.133-                 (decf n))))
  12.134-      (setf th (make-thread #'in-new-thread))
  12.135-      (sleep 1)
  12.136-      (is (null (mutex-owner lock)))
  12.137-      (with-mutex (lock)
  12.138-        (incf n)
  12.139-        (condition-notify queue))
  12.140-      (is (= 0 (join-thread th))))))
  12.141-
  12.142-(deftest timers ()
  12.143-  "Test various timer functionality."
  12.144-  (sb-int:with-progressive-timeout (ttl :seconds 2)
  12.145-    (sleep 0.1)
  12.146-    (is (/= (ttl) 2.0))))
  12.147-
  12.148-(deftest tasks ()
  12.149-  "Test task-pools, oracles, and workers."
  12.150-  (let ((pool (designate-oracle (make-task-pool) (make-oracle *current-thread*))))
  12.151-    ;; pool is bound to a task pool, *ORACLE-THREADS* contains the *CURRENT-THREAD*.
  12.152-    (spawn-workers pool 16)
  12.153-    ;; (with-threads (16 :args (&optional (a 0) (b 1) (c 2)))
  12.154-    ;;   (sb-thread:allocator-histogram)
  12.155-    ;;   (sb-concurrency:wait-on-gate (std/thread::task-pool-online pool))
  12.156-    ;;   (print (+ a b c)))
  12.157-    (is (= 16 (length (task-pool-workers pool))))
  12.158-    (is (sb-thread:semaphore-count (std/task::task-pool-online pool)))))
  12.159-
  12.160-(deftest fmt ()
  12.161-  "Test standard formatters"
  12.162-  (is (string= (format nil "| 1 | 2 | 3 |~%") (fmt-row '(1 2 3))))
  12.163-  (is (string= 
  12.164-       ;; note the read-time-eval..
  12.165-       #.(fmt-tree nil '(foobar (:a) (:b) (c) (d)) :layout :down)
  12.166-       #"FOOBAR
  12.167- ├─ :A
  12.168- ├─ :B
  12.169- ├─  C
  12.170- ╰─  D
  12.171-"#))
  12.172-  ;; with plist option
  12.173-  (is (string= 
  12.174-       #.(std:fmt-tree nil '(sk-project :name "foobar" :path "/a/b/c.asd" :vc :hg) :layout :down :plist t)
  12.175-       #"SK-PROJECT
  12.176- ├─ :NAME
  12.177- │   ╰─ "foobar"
  12.178- ├─ :PATH
  12.179- │   ╰─ "/a/b/c.asd"
  12.180- ╰─ :VC
  12.181-     ╰─ :HG
  12.182-"#)))
  12.183-
  12.184-(deftest ana ()
  12.185-  "Test standard anaphoric macros"
  12.186-  (is (= 8 
  12.187-	 (aif (+ 2 2)
  12.188-	      (+ it it))))
  12.189-  (is (= 42 (awhen 42 it)))
  12.190-  (is (= 3 (acond ((1+ 1) (1+ it)))))
  12.191-  (loop for x in '(1 2 3)
  12.192-        for y in (funcall (alet ((a 1) (b 2) (c 3))
  12.193-                                (lambda () (mapc #'1+ (list a b c)))))
  12.194-        collect (is (= x y))))
  12.195-
  12.196-(deftest pan ()
  12.197-  "Test standard pandoric macros"
  12.198-  (let ((p
  12.199-	  (plambda (a) (b c)
  12.200-		   (if (not a)
  12.201-		       (setq b 0
  12.202-			     c 0)
  12.203-		       (progn (incf b a) (incf c a))))))
  12.204-    (with-pandoric (b c) p
  12.205-      (is (= 0 (funcall p nil)))
  12.206-      (is (= 1 (funcall p 1)))
  12.207-      (is (= 11 (funcall p 10)))
  12.208-      (is (= 0 (funcall p nil)))
  12.209-      )))
  12.210-
  12.211-(deftest alien ()
  12.212-  "Test standard alien utils"
  12.213-  (is (= 0 (foreign-int-to-integer 0 4)))
  12.214-  (is (= 1 (bool-to-foreign-int t))))
  12.215-
  12.216-(deftest curry ()
  12.217-  "Test curry functions from Alexandria, found in std/fu.
  12.218-These tests are copied directly from the Alexandria test suite."
  12.219-  ;; curry.1
  12.220-  (let ((curried (curry '+ 3)))
  12.221-    (is (= (funcall curried 1 5) 9)))
  12.222-  ;; curry.2
  12.223-  (let ((curried (locally (declare (notinline curry))
  12.224-                   (curry '* 2 3))))
  12.225-    (is (= (funcall curried 7) 42)))
  12.226-  ;; curry.3
  12.227-  (let ((curried-form (funcall (compiler-macro-function 'curry)
  12.228-                               '(curry '/ 8)
  12.229-                               nil)))
  12.230-    (let ((fun (funcall (compile nil `(lambda () ,curried-form)))))
  12.231-      (is (= (funcall fun 2) 4)))) ;; maybe fails?
  12.232-  ;; curry.4
  12.233-  (let* ((x 1)
  12.234-         (curried (curry (progn
  12.235-                           (incf x)
  12.236-                           (lambda (y z) (* x y z)))
  12.237-                         3)))
  12.238-    (is (equal (list (funcall curried 7)
  12.239-                     (funcall curried 7)
  12.240-                     x)
  12.241-               '(42 42 2))))
  12.242-  ;; rcurry.1
  12.243-  (let ((r (rcurry '/ 2)))
  12.244-    (is (= (funcall r 8) 4)))
  12.245-  ;; rcurry.2
  12.246-  (let* ((x 1)
  12.247-         (curried (rcurry (progn
  12.248-                            (incf x)
  12.249-                            (lambda (y z) (* x y z)))
  12.250-                          3)))
  12.251-    (is (equalp 
  12.252-         (list (funcall curried 7) ;; 42
  12.253-               (funcall curried 7) ;; 42
  12.254-               x) ;; 2
  12.255-         '(42 42 2)))))
  12.256-
  12.257-(define-bitfield testbits
  12.258-  (a boolean)
  12.259-  (b (signed-byte 2))
  12.260-  (c (unsigned-byte 3) :initform 1)
  12.261-  (d (integer -100 100))
  12.262-  (e (member foo bar baz)))
  12.263-
  12.264-(deftest bits ()
  12.265-  (let ((bits (make-testbits)))
  12.266-    (is (not (testbits-a bits)))
  12.267-    (is (= 0 (testbits-b bits)))
  12.268-    (is (= 1 (testbits-c bits)))
  12.269-    (is (= -100 (testbits-d bits)))
  12.270-    (is (eql 'foo (testbits-e bits)))))
  12.271-
  12.272-(deftest leb128 ()
  12.273-  (loop for i from 0 below 1000
  12.274-        do (is (= i (decode-uleb128 (encode-uleb128 i)))))
  12.275-  (signals division-by-zero (decode-uleb128 (encode-uleb128 -1)))
  12.276-  (loop for i from -1000 below 0
  12.277-        do (is (= i (decode-leb128 (encode-leb128 i))))
  12.278-        do (is (= (* i i) (decode-leb128 (encode-leb128 (* i i)))))))
  12.279-
    13.1--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2+++ b/lisp/std/tests/num.lisp	Sun Jul 28 20:49:47 2024 -0400
    13.3@@ -0,0 +1,15 @@
    13.4+;;; num.lisp --- Number Tests
    13.5+
    13.6+;; 
    13.7+
    13.8+;;; Code:
    13.9+(in-package :std/tests)
   13.10+(in-suite :std)
   13.11+
   13.12+(deftest leb128 ()
   13.13+  (loop for i from 0 below 1000
   13.14+        do (is (= i (decode-uleb128 (encode-uleb128 i)))))
   13.15+  (signals division-by-zero (decode-uleb128 (encode-uleb128 -1)))
   13.16+  (loop for i from -1000 below 0
   13.17+        do (is (= i (decode-leb128 (encode-leb128 i))))
   13.18+        do (is (= (* i i) (decode-leb128 (encode-leb128 (* i i)))))))
    14.1--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2+++ b/lisp/std/tests/pkg.lisp	Sun Jul 28 20:49:47 2024 -0400
    14.3@@ -0,0 +1,255 @@
    14.4+;;; tests.lisp --- std system tests
    14.5+
    14.6+;;; Commentary:
    14.7+
    14.8+;; TODO: fix false positives when using (eval-test)
    14.9+
   14.10+;;; Code:
   14.11+(in-package :std-int)
   14.12+(defpkg :std/tests
   14.13+  (:use :cl :std :rt :sb-thread :std/fu))
   14.14+(in-package :std/tests)
   14.15+(defsuite :std)
   14.16+(in-suite :std)
   14.17+(in-readtable :std)
   14.18+;; prevent threadlocks
   14.19+;; (setf sb-unix::*on-dangerous-wait* :error)
   14.20+
   14.21+;; TODO 2024-05-14: fix compilation order of std/fu vs std/readtables
   14.22+(deftest readtables (:skip nil)
   14.23+  "Test :std readtable"
   14.24+  (is (typep #`(,a1 ,a1 ',a1 ,@a1) 'function))
   14.25+  (is (string= #"test "foo" "# "test \"foo\" "))
   14.26+  ;; from curry-compose-reader-macros test suite
   14.27+  (is (equal (funcall {list 1} 2) '(1 2))) ;; curry.1
   14.28+  (is (equal (mapcar {+ 1} '(1 2 3 4)) '(2 3 4 5))) ;; curry.2
   14.29+  (is (equal (funcall {1 list 1} 2) '(1 2))) ;; curry.fixed-arity
   14.30+  (is (equal (funcall {2 list _ 2} 3 4) '(3 4 2))) ;; curry.fixed-arity.2
   14.31+  (signals error
   14.32+    (let ((f {1 list 1}))
   14.33+      (progn (funcall f) nil))) ;; curry.fixed-arity.1
   14.34+  (signals error
   14.35+    (locally (declare (optimize safety))
   14.36+      (let ((f {1 list 1}))
   14.37+        (progn (funcall f 'a 'b) nil)))) ;; curry.fixed-arity-error.2
   14.38+  (is (equal (funcall {list _ 1} 2) '(2 1))) ;; rcurry.1
   14.39+  (is (equal (mapcar {- _ 1} '(1 2 3 4)) '(0 1 2 3))) ;; rcurry.2
   14.40+  (is (equal (funcall [{* 3} #'1+] 1) 6)) ;; compose.1
   14.41+  (is (equal (funcall ['1+ '1+] 1) 3)) ;; compose.2
   14.42+  (is (equal (funcall [#'1+] 1) 2)) ;; compose.3
   14.43+  (is (equal (funcall [#'values] 1 2 3) (values 1 2 3))) ;; compose.4
   14.44+  (is (equal (funcall «list {* 2} {* 3}» 4) '(8 12))) ;; join.1
   14.45+  (is (equal (mapcar «and {< 2} 'evenp (constantly t)» '(1 2 3 4)) (list nil nil nil t))) ;; join.2
   14.46+  ;; typecase-bracket
   14.47+  (is (equal (mapcar ‹typecase (number #'1+) (string :str)› '(1 "this" 2 "that")) '(2 :str 3 :str)))
   14.48+  ;; cond-bracket
   14.49+  (is (equal (mapcar ‹cond (#'evenp {+ 100}) (#'oddp {+ 200})› '(1 2 3 4)) '(201 102 203 104)))
   14.50+  ;; if-bracket
   14.51+  (is (equal (mapcar ‹if #'evenp {list :a} {list :b}› '(1 2 3 4))
   14.52+             '((:b 1) (:a 2) (:b 3) (:a 4))))
   14.53+  ;; when-bracket
   14.54+  (is (equal (mapcar ‹when 'evenp {+ 4}› '(1 2 3 4)) (list nil 6 nil 8)))
   14.55+  ;; unless-bracket
   14.56+  (is (equal (mapcar ‹unless 'evenp {+ 4}› '(1 2 3 4)) (list 5 nil 7 nil))))
   14.57+
   14.58+(deftest sym ()
   14.59+  "Test standard symbol utils"
   14.60+  ;; gensyms
   14.61+  (is (not (equalp (make-gensym 'a) (make-gensym 'a))))
   14.62+  (is (eq 'std/tests::foo (format-symbol :std/tests "~A" 'foo)))
   14.63+  (is (eq (make-keyword 'fizz) :fizz)))
   14.64+
   14.65+;;;; TODO
   14.66+(deftest string ()
   14.67+  "Test standard string utils"
   14.68+  (is (typep "test" 'string-designator))
   14.69+  (is (typep 'test 'string-designator))
   14.70+  (is (typep #\C 'string-designator))
   14.71+  (is (not (typep 0 'string-designator))))
   14.72+
   14.73+(deftest list ()
   14.74+  "Test standard list utils"
   14.75+  ;; same object - a literal
   14.76+  (is (eq (ensure-car '(0)) (ensure-car 0)))
   14.77+  (is (eq (ensure-car '(nil)) (ensure-car nil)))
   14.78+  ;; different objects
   14.79+  (is (not (eq (ensure-cons 0) (ensure-cons 0))))
   14.80+  (is (equal (ensure-cons 0) (ensure-cons 0))))
   14.81+
   14.82+(deftest err ()
   14.83+  "Test standard error handlers"
   14.84+  (is (eql 'testing-err (deferror testing-err (std-error) nil (:auto t) (:documentation "testing")))))
   14.85+
   14.86+(deftest threads ()
   14.87+  "Test standard thread functionality."
   14.88+  (is (eq *current-thread*
   14.89+          (find (thread-name *current-thread*) (list-all-threads)
   14.90+                :key #'thread-name :test #'equal)))
   14.91+  (is (find-thread-by-id (car (thread-id-list))))
   14.92+  (is (not (zerop (thread-count))))
   14.93+  (let ((threads
   14.94+          (make-threads 4 (lambda () (is (= 42 (1+ 41)))) :name "threads")))
   14.95+    (loop for th in threads
   14.96+          do (sb-thread:join-thread th))
   14.97+    (loop for th in threads
   14.98+          collect (is (not (sb-thread:thread-alive-p th)))))
   14.99+  (let ((m (make-mutex :name "mutex-test")))
  14.100+    (is
  14.101+     (and (not
  14.102+           (with-mutex (m)
  14.103+             (join-thread
  14.104+              (make-thread (lambda ()
  14.105+                             (with-mutex (m :timeout 0.1)
  14.106+                               t))))))
  14.107+          (join-thread
  14.108+           (make-thread (lambda ()
  14.109+                          (with-mutex (m :timeout 0.1)
  14.110+                            t)))))))
  14.111+  (let* ((sym (gensym))
  14.112+         (s (make-semaphore :name "semaphore-test"))
  14.113+         (th (make-thread (lambda () (wait-on-semaphore s)))))
  14.114+    (is (equal (multiple-value-list (join-thread th :timeout .001 :default sym))
  14.115+               (list sym :timeout)))
  14.116+    (signal-semaphore s)
  14.117+    (is (join-thread th)))
  14.118+  (signals join-thread-error (join-thread *current-thread*))
  14.119+  (is
  14.120+   (let ((m (make-mutex :name "rlock-test")))
  14.121+     (is (not (with-mutex (m) (join-thread (make-thread (lambda () (with-recursive-lock (m :wait-p nil) t)))))))
  14.122+     (join-thread (make-thread (lambda () (with-recursive-lock (m :wait-p nil) t))))))
  14.123+  (let ((queue (make-waitqueue :name "queue-test"))
  14.124+        (lock (make-mutex :name "lock-test"))
  14.125+        (n 0)
  14.126+        th)
  14.127+    (labels ((in-new-thread ()
  14.128+               (with-mutex (lock)
  14.129+                 (assert (eql (mutex-owner lock) *current-thread*))
  14.130+                 (condition-wait queue lock)
  14.131+                 (assert (eql (mutex-owner lock) *current-thread*))
  14.132+                 (is (= n 1))
  14.133+                 (decf n))))
  14.134+      (setf th (make-thread #'in-new-thread))
  14.135+      (sleep 1)
  14.136+      (is (null (mutex-owner lock)))
  14.137+      (with-mutex (lock)
  14.138+        (incf n)
  14.139+        (condition-notify queue))
  14.140+      (is (= 0 (join-thread th))))))
  14.141+
  14.142+(deftest timers ()
  14.143+  "Test various timer functionality."
  14.144+  (sb-int:with-progressive-timeout (ttl :seconds 2)
  14.145+    (sleep 0.1)
  14.146+    (is (/= (ttl) 2.0))))
  14.147+
  14.148+(deftest fmt ()
  14.149+  "Test standard formatters"
  14.150+  (is (string= (format nil "| 1 | 2 | 3 |~%") (fmt-row '(1 2 3))))
  14.151+  (is (string= 
  14.152+       ;; note the read-time-eval..
  14.153+       #.(fmt-tree nil '(foobar (:a) (:b) (c) (d)) :layout :down)
  14.154+       #"FOOBAR
  14.155+ ├─ :A
  14.156+ ├─ :B
  14.157+ ├─  C
  14.158+ ╰─  D
  14.159+"#))
  14.160+  ;; with plist option
  14.161+  (is (string= 
  14.162+       #.(std:fmt-tree nil '(sk-project :name "foobar" :path "/a/b/c.asd" :vc :hg) :layout :down :plist t)
  14.163+       #"SK-PROJECT
  14.164+ ├─ :NAME
  14.165+ │   ╰─ "foobar"
  14.166+ ├─ :PATH
  14.167+ │   ╰─ "/a/b/c.asd"
  14.168+ ╰─ :VC
  14.169+     ╰─ :HG
  14.170+"#)))
  14.171+
  14.172+(deftest ana ()
  14.173+  "Test standard anaphoric macros"
  14.174+  (is (= 8 
  14.175+	 (aif (+ 2 2)
  14.176+	      (+ it it))))
  14.177+  (is (= 42 (awhen 42 it)))
  14.178+  (is (= 3 (acond ((1+ 1) (1+ it)))))
  14.179+  (loop for x in '(1 2 3)
  14.180+        for y in (funcall (alet ((a 1) (b 2) (c 3))
  14.181+                                (lambda () (mapc #'1+ (list a b c)))))
  14.182+        collect (is (= x y))))
  14.183+
  14.184+(deftest pan ()
  14.185+  "Test standard pandoric macros"
  14.186+  (let ((p
  14.187+	  (plambda (a) (b c)
  14.188+		   (if (not a)
  14.189+		       (setq b 0
  14.190+			     c 0)
  14.191+		       (progn (incf b a) (incf c a))))))
  14.192+    (with-pandoric (b c) p
  14.193+      (is (= 0 (funcall p nil)))
  14.194+      (is (= 1 (funcall p 1)))
  14.195+      (is (= 11 (funcall p 10)))
  14.196+      (is (= 0 (funcall p nil)))
  14.197+      )))
  14.198+
  14.199+(deftest alien ()
  14.200+  "Test standard alien utils"
  14.201+  (is (= 0 (foreign-int-to-integer 0 4)))
  14.202+  (is (= 1 (bool-to-foreign-int t))))
  14.203+
  14.204+(deftest curry ()
  14.205+  "Test curry functions from Alexandria, found in std/fu.
  14.206+These tests are copied directly from the Alexandria test suite."
  14.207+  ;; curry.1
  14.208+  (let ((curried (curry '+ 3)))
  14.209+    (is (= (funcall curried 1 5) 9)))
  14.210+  ;; curry.2
  14.211+  (let ((curried (locally (declare (notinline curry))
  14.212+                   (curry '* 2 3))))
  14.213+    (is (= (funcall curried 7) 42)))
  14.214+  ;; curry.3
  14.215+  (let ((curried-form (funcall (compiler-macro-function 'curry)
  14.216+                               '(curry '/ 8)
  14.217+                               nil)))
  14.218+    (let ((fun (funcall (compile nil `(lambda () ,curried-form)))))
  14.219+      (is (= (funcall fun 2) 4)))) ;; maybe fails?
  14.220+  ;; curry.4
  14.221+  (let* ((x 1)
  14.222+         (curried (curry (progn
  14.223+                           (incf x)
  14.224+                           (lambda (y z) (* x y z)))
  14.225+                         3)))
  14.226+    (is (equal (list (funcall curried 7)
  14.227+                     (funcall curried 7)
  14.228+                     x)
  14.229+               '(42 42 2))))
  14.230+  ;; rcurry.1
  14.231+  (let ((r (rcurry '/ 2)))
  14.232+    (is (= (funcall r 8) 4)))
  14.233+  ;; rcurry.2
  14.234+  (let* ((x 1)
  14.235+         (curried (rcurry (progn
  14.236+                            (incf x)
  14.237+                            (lambda (y z) (* x y z)))
  14.238+                          3)))
  14.239+    (is (equalp 
  14.240+         (list (funcall curried 7) ;; 42
  14.241+               (funcall curried 7) ;; 42
  14.242+               x) ;; 2
  14.243+         '(42 42 2)))))
  14.244+
  14.245+(define-bitfield testbits
  14.246+  (a boolean)
  14.247+  (b (signed-byte 2))
  14.248+  (c (unsigned-byte 3) :initform 1)
  14.249+  (d (integer -100 100))
  14.250+  (e (member foo bar baz)))
  14.251+
  14.252+(deftest bits ()
  14.253+  (let ((bits (make-testbits)))
  14.254+    (is (not (testbits-a bits)))
  14.255+    (is (= 0 (testbits-b bits)))
  14.256+    (is (= 1 (testbits-c bits)))
  14.257+    (is (= -100 (testbits-d bits)))
  14.258+    (is (eql 'foo (testbits-e bits)))))
    15.1--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2+++ b/lisp/std/tests/task.lisp	Sun Jul 28 20:49:47 2024 -0400
    15.3@@ -0,0 +1,19 @@
    15.4+;;; tests/task.lisp --- Task Tests
    15.5+
    15.6+;; 
    15.7+
    15.8+;;; Code:
    15.9+(in-package :std/tests)
   15.10+(in-suite :std)
   15.11+
   15.12+(deftest tasks ()
   15.13+  "Test task-pools, oracles, and workers."
   15.14+  (let ((pool (designate-oracle (make-task-pool) (make-oracle *current-thread*))))
   15.15+    ;; pool is bound to a task pool, *ORACLE-THREADS* contains the *CURRENT-THREAD*.
   15.16+    (spawn-workers pool 16)
   15.17+    ;; (with-threads (16 :args (&optional (a 0) (b 1) (c 2)))
   15.18+    ;;   (sb-thread:allocator-histogram)
   15.19+    ;;   (sb-concurrency:wait-on-gate (std/thread::task-pool-online pool))
   15.20+    ;;   (print (+ a b c)))
   15.21+    (is (= 16 (length (task-pool-workers pool))))
   15.22+    (is (sb-thread:semaphore-count (std/task::task-pool-online pool)))))
    16.1--- a/lisp/std/tests/tasks.lisp	Sat Jul 27 00:40:29 2024 -0400
    16.2+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3@@ -1,7 +0,0 @@
    16.4-;;; tasks.lisp --- Task Pool Tests
    16.5-
    16.6-;; 
    16.7-
    16.8-;;; Code:
    16.9-(in-package :std/tests)
   16.10-(in-suite :std)