shithub: sl

Download patch

ref: 02f22fc85aad29658e7300fbbc4587a29677e574
parent: 58cbac8c929d52b2af670d14888f08c7c5a5ad1b
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Tue Apr 15 22:29:54 EDT 2025

defstruct: better error reporting

--- a/src/system.sl
+++ b/src/system.sl
@@ -1060,7 +1060,7 @@
   (apply (getprop struct 'constructor) rest))
 
 (defmacro (defstruct name (:type 'vec)
-                          (:named NIL)
+                          (:named NIL named-supplied)
                           (:constructor T)
                           (:conc-name NIL)
                           (:predicate T)
@@ -1139,16 +1139,24 @@
          ; slots, but with default values added (if not set)
          ; and keywords for names
          [slots-kw (tokw slots)]
-         ; underlying type, either a vector or list
-         [isvec (eq? type 'vec)]
+         ; underlying type, either vector or list
+         [isvec (if (eq? type 'vec)
+                    T
+                    (unless (eq? type 'list)
+                      (arg-error "invalid struct type: " type)))]
          ; should the struct name appear as the first element?
-         [named (and (or named isvec) name)]
+         [named (and (if isvec
+                         (or (unless (or (not named-supplied) (eq? named T))
+                               (arg-error "structs of type `vec` are always :named T"))
+                             T)
+                         named)
+                     name)]
          ; struct's predicate name
          [is? (and predicate
                    (if (eq? predicate T)
                        (and named (sym name #\?)) ; FIXME(sigrid): need a "is set?" third arg
                        (if (not named)
-                           (raise 'arg-error '("predicate not possible unless the struct is :named"))
+                           (arg-error "predicate not possible unless the struct is :named T")
                            predicate)))]
          ; what (type-of ...) should return if predicate is defined
          [type-of-value (if isvec
@@ -1214,7 +1222,7 @@
                           `(def (,fun s (v NIL v-supplied?))
                              ,(when is?
                                 `(unless (,is? s)
-                                   (raise (list 'type-error ',type-of-value s))))
+                                   (type-error ',type-of-value s)))
                              (if (not v-supplied?)
                                  (aref s ,[+ (if named 1 0) iv])
                                  ,(if (member :read-only opts)
--