-
Notifications
You must be signed in to change notification settings - Fork 0
/
keywords.zp
74 lines (67 loc) · 2.58 KB
/
keywords.zp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
(define (atom->symbol a)
"converts an atom to a symbol.
params:
- a: the atom to convert
complexity: O(n) where n is the length of <par>a</par>
returns: a symbol"
(let ((s (cdr (->string a))))
(eval (macro-expand `(->symbol ,s)))))
(define-syntax defkeywords
(syntax-rules "defines a function with keywords.
Example:
<zepto>
(defkeywords (kw regular-arg) (:kw-wo-default
:kw-w-default :default 10)
(map write (list regular-arg kw-wo-default kw-w-default)))
</zepto>
params:
- nargs: the name and normal arguments
- kwargs: the keywords arguments
- docs : optional documentation
- body: the function body
complexity: O(1)
returns: a function" ()
((_ nargs kwargs body)
(defkeywords nargs kwargs "No documentation available" body))
((_ nargs kwargs docs body)
(with-environment env
(begin
(define (treat-keywords args)
(case (length args)
((0) args)
((1) (list args))
(else
(let ((key (car args))
(meta (cadr args)))
(if (eq? :default meta)
(++ `((,key ,(caddr args))) (treat-keywords (cdddr args)))
(++ `((,key)) (treat-keywords (cdr args))))))))
(eval (eval (macro-expand
`(define ,(reduce (flip cons) (cons 'args) (reverse 'nargs)) ,docs
(begin
(with-environment env
(let ((dict (apply make-hash args)))
(map
($ (let* ((k (car %))
(s (atom->symbol k)))
(eval (+= [define] s
(if (in? dict k) (dict k) (eval (get-from % 1)))) env)))
(quote ,(treat-keywords 'kwargs)))))
,'body))) env) env))))))
(defkeywords (string:pluralize num singular) (:plural :default (++ singular "s"))
"Return a pluralized phrase, appending an s to the singular form if no plural
is provided.
Example:
<zepto>
(pluralize 5 \"month\") => \"5 months\"
(pluralize 1 \"month\") => \"1 month\"
(pluralize 1 \"radius\" :plural \"radii\") => \"1 radius\"
(pluralize 9 \"radius\" :plural \"radii\") => \"9 radii\"
</zepto>
params:
- num: the number of things
- singular: the name of the things
- plural: the pluralization (defaults to singular + \"s\")
complexity: O(1)
returns: the new string"
(format "~a ~a" num (if (= 1 num) singular plural)))