|
1 | 1 | ;;; cl.lsp --- Common Lisp like functions
|
2 | 2 |
|
| 3 | +;;; NOTE: |
| 4 | +;; |
| 5 | +;; see "Differences to Other LISPs" |
| 6 | +;; - http://www.newlisp.org/index.cgi?page=Differences_to_Other_LISPs |
| 7 | +;; * Case-sensitive |
| 8 | +;; * 関数部分は事前に評価される |
| 9 | +;; * LISP-1 |
| 10 | +;; * ダイナミックスコープ |
| 11 | +;; * ドット対が存在しない |
| 12 | +;; * 関数引数はデフォルトでオプショナル |
| 13 | +;; * 存在しないシンボルは生成時にnilに束縛される |
| 14 | +;; * GCの代わりにORO |
| 15 | +;; * Fexprマクロは引数を評価しない |
| 16 | +;; * パッケージの代わりにコンテキスト |
| 17 | +;; * Implicit Indexing |
| 18 | + |
3 | 19 | ;; (constant (global 't) true)
|
| 20 | +;; (define t true) |
4 | 21 | (define (null x) (not (true? x)))
|
5 |
| -(define car first) |
| 22 | +;;(define car first) |
| 23 | +(define (car x) |
| 24 | + (if (member x '(nil ())) nil (first x))) |
6 | 25 | (define cdr rest)
|
7 | 26 | (define defconstant
|
8 | 27 | (lambda-macro ()
|
9 | 28 | (constant (args 0) (eval (args 1)))))
|
10 | 29 | (define export global)
|
11 | 30 | (define progn begin)
|
12 | 31 | (define (funcall f) (apply f (args)))
|
| 32 | +(define (atom obj) |
| 33 | + (or (atom? obj) |
| 34 | + (= obj '()))) |
| 35 | +(define eq =) |
| 36 | +(define eql =) |
| 37 | +(define equal =) |
13 | 38 | (define let* letn)
|
14 | 39 | (define intern sym) ; or make-symbol
|
15 |
| -(define symbol-name name) |
| 40 | +(define symbol-name term) |
| 41 | +(define symbol-package prefix) |
16 | 42 | (define char-code char) ; (char "A") => 65
|
17 | 43 | (define code-char char) ; (char 65) => "A"
|
18 | 44 | (define rplaca ; (rplaca x y)
|
19 | 45 | (lambda-macro ()
|
20 | 46 | (setf (first (eval (args 0))) (eval (args 1)))
|
21 | 47 | (eval (args 0))))
|
22 |
| -(define rotatef swap) |
| 48 | +(define rotatef swap) ; swap accept only two variables |
23 | 49 | (define complement
|
24 | 50 | (lambda-macro ()
|
25 | 51 | (letex ((f (args 0)))
|
26 | 52 | (lambda ()
|
27 | 53 | (not (apply f (args)))))))
|
28 | 54 | (define identity
|
29 |
| - ;; なんでマクロにしたんだっけ? |
30 |
| - (lambda-macro () |
31 |
| - (eval (args 0)))) |
| 55 | + ;; 引数のコピーを避けるためマクロを利用している |
| 56 | + (lambda-macro () (eval (args 0)))) |
| 57 | + |
| 58 | +;; FIXME: short `uuid' name is safe to use? |
| 59 | +(define (gensym) (sym (append "g-" (slice (uuid) 0 8)))) |
32 | 60 |
|
33 | 61 | (define (find-symbol str (ctx (context)))
|
| 62 | + ;; or (context ctx str) |
34 | 63 | (sym str ctx nil))
|
35 | 64 |
|
36 | 65 | (define read-from-string read-expr)
|
|
39 | 68 | (constant 'most-positive-fixnum 0x7fffffffffffffff)
|
40 | 69 | (constant 'most-negative-fixnum 0x8000000000000000)
|
41 | 70 | (defconstant pi (mul (atan 1) 4)) ; 3.141592654 (mul (acos 0) 2)
|
42 |
| -(define equal =) |
43 |
| -(define incf inc) |
44 |
| -(define decf dec) |
| 71 | +(define incf inc) ; or ++ |
| 72 | +(define decf dec) ; or -- |
45 | 73 | (define (plusp number) (< 0 number)) ; or (> number) , (sgn number nil nil true)
|
46 | 74 | (define (minusp number) (< number 0)) ; or (< number) , (sgn number true nil nil)
|
| 75 | +(define (evenp i) (= (& i 1) 0)) |
| 76 | +(define (oddp i) (= (& i 1) 1)) |
47 | 77 | (define (ash i cnt) (sgn cnt (>> i (abs cnt)) i (<< i cnt)))
|
48 | 78 | (define logand &)
|
49 | 79 | (define logxor ^)
|
|
65 | 95 | ((- n) lst))
|
66 | 96 | (define every for-all)
|
67 | 97 | (define (some f lst)
|
| 98 | + (if (symbol? f) (setq f (eval f))) |
68 | 99 | (dolist (obj lst (f obj))))
|
| 100 | +(define (notany f lst) |
| 101 | + (setq f (eval f)) |
| 102 | + (not (apply exists (list f lst $args)))) |
69 | 103 | (define position find)
|
70 | 104 | (define find-if exists)
|
71 | 105 | (define remove-duplicates unique)
|
|
95 | 129 | ;; (map list '(1 2 3 4) '(10 nil 30) '(100 200 300 400 500 600))
|
96 | 130 | ;; => ((1 10 100) (2 nil 200) (3 30 300) (4 nil 400))
|
97 | 131 |
|
| 132 | +(define (list* ) |
| 133 | + (cond ((empty? (rest (args))) |
| 134 | + (first (args))) |
| 135 | + (true |
| 136 | + (cons (first (args)) |
| 137 | + (apply list* (rest (args))))))) |
| 138 | + |
98 | 139 | ;;; @@sequence
|
99 | 140 | ;(define concat string)
|
100 | 141 | (define (concat) (join (args)))
|
|
107 | 148 | (cond (end (slice seq start (- end start)))
|
108 | 149 | (true (slice seq start))))
|
109 | 150 |
|
110 |
| -(define (string-equal string1 string2) |
111 |
| - "Compare two strings ignore case." |
112 |
| - (let ((PCRE_CASELESS 1)) |
113 |
| - (list? (regex (string "^" (regex-quote string1) "$") |
114 |
| - string2 |
115 |
| - PCRE_CASELESS)))) |
| 151 | +(define (string-equal str1 str2) |
| 152 | + (= (upper-case str1) (upper-case str2))) |
116 | 153 |
|
117 | 154 | (define (string-left-trim char-bag str)
|
118 | 155 | (if (string? char-bag)
|
|
133 | 170 | (define (string-trim char-bag str)
|
134 | 171 | (string-right-trim char-bag (string-left-trim char-bag str)))
|
135 | 172 |
|
136 |
| -;; (define (string-trim char-bag str) (trim str char-bag char-bag)) |
137 |
| -;; (define (string-left-trim char-bag str) (trim str char-bag "")) |
138 |
| -;; (define (string-right-trim char-bag str) (trim str "" char-bag)) |
139 |
| - |
140 | 173 | (define-macro (ignore-errors form)
|
141 | 174 | (eval-string (prin1-to-string form) (context) nil))
|
142 | 175 |
|
143 | 176 | ;; @syntax (unwind-protect protected-form cleanup-form*) => result
|
144 | 177 | ;; (context 'unwind-protect)
|
145 |
| -(letex ((result (sym (uuid)))) |
| 178 | +(letex ((result (gensym))) |
146 | 179 | (define-macro (unwind-protect )
|
147 | 180 | (local (result)
|
148 | 181 | (if (catch (eval (args 0)) 'result)
|
|
151 | 184 | )
|
152 | 185 |
|
153 | 186 | (define (prin1-to-string obj)
|
154 |
| - (cond ((string? obj) (format"\"%s\"" (replace "\\" obj "\\\\"))) |
| 187 | + (cond ((string? obj) (format {"%s"} (replace "\\" obj "\\\\"))) |
155 | 188 | ("else" (string obj))))
|
156 | 189 |
|
| 190 | +;; parallel setq |
| 191 | +;; @syntax (psetq var form ...) |
| 192 | +(define psetq |
| 193 | + (letex ((v (gensym)) |
| 194 | + (s (gensym))) |
| 195 | + (lambda-macro () |
| 196 | + (unless (= (& (length $args) 1) 0) |
| 197 | + (throw-error "missing argument")) |
| 198 | + (dolist (v (map (lambda (s) (list (s 0) (eval (s 1)))) |
| 199 | + ;; ((var1 val1) (var2 val2) ...) |
| 200 | + (explode $args 2))) |
| 201 | + (set (v 0) (v 1)))))) |
| 202 | + |
157 | 203 | (context MAIN)
|
158 | 204 | ;;; EOF
|
0 commit comments