git.fiddlerwoaroof.com
Browse code

Add macros for class creation and convenience entrypoint definition

Ed Langley authored on 07/02/2019 01:48:20
Showing 3 changed files
... ...
@@ -3,4 +3,26 @@
3 3
 (defmacro with-accessors* ((&rest accessors) object &body body)
4 4
   `(with-accessors ,(ensure-mapping accessors) ,object
5 5
      ,@body))
6
-       
6
+
7
+(defmacro new (class &rest initializer-syms)
8
+  (multiple-value-bind (required optional rest) (parse-ordinary-lambda-list initializer-syms)
9
+    (when optional
10
+      (error "new doesn't handle optional arguments"))
11
+    (if rest
12
+        `(make-instance ,class
13
+                        ,@(mapcan (serapeum:op (list (alexandria:make-keyword _1) _1))
14
+                                  required)
15
+                        ,(make-keyword rest) ,rest)
16
+        `(make-instance ,class
17
+                        ,@(mapcan (serapeum:op (list (alexandria:make-keyword _1) _1))
18
+                                  initializer-syms)))))
19
+
20
+(defun-ct %constructor-name (class)
21
+  (format nil "~a-~a" '#:make class))
22
+
23
+(defmacro make-constructor (class &rest args)
24
+  (destructuring-bind (class &optional (constructor-name (intern (%constructor-name class))))
25
+      (ensure-list class)
26
+    `(defgeneric ,constructor-name (,@args)
27
+       (:method (,@args)
28
+         (new ',class ,@args)))))
... ...
@@ -3,3 +3,16 @@
3 3
 (defmacro twice (&body body)
4 4
   `(progn ,@body
5 5
           ,@body))
6
+
7
+(defmacro define-cluser-entrypoint ((&rest args) &body body)
8
+  "Use the current package name to generate a <PACKAGE-NAME>.MAIN function in CL-USER.
9
+
10
+This will throw an error if :FW.DEV is not in features as it's not
11
+intended to be usd in distributed code."
12
+  (unless (featurep :fw.dev)
13
+    (error "will not define cluser entrypoint without :FW.DEV in *FEATURES*"))
14
+  (let ((entrypoint-symbol (intern (format nil "~a.~a" (package-name *package*) '#:main)
15
+                                   :cl-user)))
16
+    `(progn (defun ,entrypoint-symbol ,args
17
+              ,@body)
18
+            (export ',entrypoint-symbol :cl-user))))
... ...
@@ -29,7 +29,10 @@
29 29
            #+null #:ensure-list #:pick #:vector-destructuring-bind #:with-accessors*
30 30
            #:skip-values #:limit-values #:substitute-values #:op #:pick/r
31 31
            #:pick-error #:twice #:glambda #:default-unless #:transform-first-value
32
-           #:may #:defun-ct)) 
32
+           #:may #:defun-ct
33
+           #:define-cluser-entrypoint
34
+           #:new
35
+           #:make-constructor)) 
33 36
 
34 37
 
35 38
 (defpackage :fwoar.lisputils.shortcuts