|
1 | 1 | ;; Functions support complex arg lists in wart. |
2 | 2 |
|
3 | | -(defmacro def(name params &rest body) |
4 | | - `(defun ,name ,@(compile-params params body))) |
| 3 | +(defmacro$ def(name params &rest body) |
| 4 | + `(defun ,name(&rest ,$args) |
| 5 | + ,(compile-params params body $args))) |
5 | 6 |
|
6 | | -(defmacro mac(name params &rest body) |
7 | | - (wt-transform `(defmacro$ ,name ,@(compile-params params body)))) |
| 7 | +(defmacro$ mac(name params &rest body) |
| 8 | + (wt-transform |
| 9 | + `(defmacro$ ,name(&rest ,$args) |
| 10 | + ,(compile-params params body $args)))) |
8 | 11 |
|
9 | | -(defmacro fn(params &rest body) |
10 | | - `(lambda ,@(compile-params params body))) |
| 12 | +(defmacro$ fn(params &rest body) |
| 13 | + `(lambda(&rest ,$args) |
| 14 | + ,(compile-params params body $args))) |
11 | 15 |
|
12 | 16 |
|
13 | 17 |
|
14 | 18 | ;; Internals |
15 | 19 | ;; Use let* everywhere here because wart will soon override let |
16 | 20 |
|
17 | | -; returns arglist and body suitable for insertion into defun or lambda |
18 | | -; new body understands keyword args |
19 | | -; params format (optionals* ? lazy-optionals* . rest) |
| 21 | +; convert body to parse keyword args and params format (optionals* ? lazy-optionals . rest) |
20 | 22 | ; optionals can be destructured |
| 23 | +; lazy optionals alternate var and default |
21 | 24 | ; lazy optionals require keywords if rest is present |
22 | | -(defun compile-params(params body) |
23 | | - (let* ((args (uniq)) |
24 | | - (positionals (uniq)) |
25 | | - (keywords (uniq))) |
26 | | - `((&rest ,args) |
27 | | - (let* ((,positionals (positional-args ,args ',(rest-param params))) |
28 | | - (,keywords (keyword-args ,args ',(rest-param params)))) |
29 | | - (let* ,(append |
30 | | - (get-required-arg-exprs params positionals keywords) |
31 | | - ; args go to rest before optional |
32 | | - (get-rest-arg-expr params positionals keywords) |
33 | | - (get-optional-arg-exprs params positionals keywords)) |
34 | | - ,@body))))) |
| 25 | +(defun$ compile-params(params body args) |
| 26 | + `(let* ((,$positionals (positional-args ,args ',(rest-param params))) |
| 27 | + (,$keywords (keyword-args ,args ',(rest-param params)))) |
| 28 | + (let* ,(append |
| 29 | + (get-required-arg-exprs params $positionals $keywords) |
| 30 | + ; args go to rest before optional |
| 31 | + (get-rest-arg-expr params $positionals $keywords) |
| 32 | + (get-optional-arg-exprs params $positionals $keywords)) |
| 33 | + ,@body))) |
35 | 34 |
|
36 | 35 | (defun get-required-arg-exprs(params positionals keywords) |
37 | 36 | (let ((required-params (required-params params))) |
|
0 commit comments