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
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 |