Commit | Line | Data |
---|---|---|
6502a929 C |
1 | (setq rcs-ucifnc- |
2 | "$Header: /usr/lib/lisp/ucifnc.l,v 1.1 83/01/29 18:41:16 jkf Exp $") | |
3 | ||
4 | ; | |
5 | ; There is problems with the ucilisp do being | |
6 | ; incompatible with maclisp/franz do, | |
7 | ; The problems with compiling do are gone, but | |
8 | ; due to these possible problems, the ucilisp do function | |
9 | ; is in a seperate file ucido.l and users of it | |
10 | ; should also load that file in at compile time before | |
11 | ; any call to do (since do is a macro) (and | |
12 | ; at runtime if do is to be interpreted). | |
13 | ; | |
14 | ; This file is meant to be fasl'd or used with liszt -u | |
15 | ; not to be read in interpretively (the syntax changes | |
16 | ; will not work in that case. | |
17 | ; | |
18 | ; to compile this file do liszt ucifnc.l | |
19 | ; | |
20 | ; one who wants to use these functions or compile and run | |
21 | ; a ucilisp program should do both | |
22 | ; liszt -u file.l when compiling. | |
23 | ; and | |
24 | ; (fasl '/usr/lib/lisp/ucifnc) | |
25 | ; before loading in and running them | |
26 | ; programs in lisp. | |
27 | ; This is because some functions are macros and others are too | |
28 | ; complicated and need other functions around. | |
29 | ; Note this file will not load in directly and when fasl'd in will | |
30 | ; cause the syntax of lisp to change to ucilisp syntax. | |
31 | ; | |
32 | (declare (macros t)) | |
33 | ||
34 | ; | |
35 | ; ucilisp (de df dm) declare function macros. | |
36 | ; | |
37 | ; (de name args body) -> declare exprs and lexprs. | |
38 | ; | |
39 | (defun de macro (l) | |
40 | `(defun ,@(cdr l))) | |
41 | ||
42 | ; | |
43 | ; (df name args body) -> declare fexprs. | |
44 | ; | |
45 | (defun df macro (l) | |
46 | `(defun ,(cadr l) | |
47 | fexpr | |
48 | ,@(cddr l))) | |
49 | ||
50 | ; | |
51 | ; macro's are not compiled except under the same | |
52 | ; conditions as in franz lisp. | |
53 | ; (usually just do (declare (macros t)) | |
54 | ; to have macros also compiled). | |
55 | ; | |
56 | ; | |
57 | ; (dm name args body) -> declare macros. same as (defun name 'macro body) | |
58 | ; | |
59 | (defun dm macro (l) | |
60 | `(defun ,(cadr l) | |
61 | macro | |
62 | ,@(cddr l))) | |
63 | ||
64 | ; | |
65 | ; ucilisp let macro. | |
66 | ; | |
67 | (eval-when (compile load eval) | |
68 | (defun let1 (l vars vals body) | |
69 | (cond ((null l) | |
70 | (cons (cons 'lambda (cons vars body)) vals)) | |
71 | (t | |
72 | (let1 (cddr l) | |
73 | (cons (car l) vars) | |
74 | (cons (cadr l) vals) body))))) | |
75 | ||
76 | (defun let macro (l) | |
77 | (let1 (cadr l) nil nil (cddr l))) | |
78 | ||
79 | (defun nconc1 macro (l) | |
80 | `(nconc ,(cadr l) (list ,(caddr l)))) | |
81 | ||
82 | (putd 'expandmacro (getd 'macroexpand)) | |
83 | ||
84 | ; | |
85 | ; ucilisp selectq function. (written by jkf) | |
86 | ; | |
87 | (def selectq | |
88 | (macro (form) | |
89 | ((lambda (x) | |
90 | `((lambda (,x) | |
91 | (cond | |
92 | ,@(maplist | |
93 | '(lambda (ff) | |
94 | (cond ((null (cdr ff)) | |
95 | `(t ,(car ff))) | |
96 | ((atom (caar ff)) | |
97 | `((eq ,x ',(caar ff)) | |
98 | . ,(cdar ff))) | |
99 | (t | |
100 | `((memq ,x ',(caar ff)) | |
101 | . ,(cdar ff))))) | |
102 | (cddr form)))) | |
103 | ,(cadr form))) | |
104 | (gensym 'Z)))) | |
105 | ||
106 | ; | |
107 | ; ucilisp functions which declare read macros. | |
108 | ; | |
109 | ; dsm - declare splicing read macro. | |
110 | ; | |
111 | (defun dsm macro (l) | |
112 | `(eval-when (compile load eval) | |
113 | (setsyntax ',(cadr l) 'splicing ',(caddr l)))) | |
114 | ||
115 | ; | |
116 | ; drm - declare read macro. | |
117 | ; | |
118 | (defun drm macro (l) | |
119 | `(eval-when (compile load eval) | |
120 | (setsyntax ',(cadr l) 'macro ',(caddr l)))) | |
121 | ||
122 | ; | |
123 | ;(:= a b) -> ucilisp assignment macro. | |
124 | ; | |
125 | (defun := macro (expression) | |
126 | (let (lft (macroexpand (cadr expression)) rgt (caddr expression)) | |
127 | (cond ((atom lft) | |
128 | `(setq ,lft ,(subst lft '*-* rgt))) | |
129 | ((get (car lft) 'set-program) | |
130 | (cons (get (car lft) 'set-program) | |
131 | (append (cdr lft) (list (subst lft '*-* rgt)))))))) | |
132 | ||
133 | (defprop car rplaca set-program) | |
134 | (defprop cdr rplacd set-program) | |
135 | (defprop cadr rplacad set-program) | |
136 | (defprop cddr rplacdd set-program) | |
137 | (defprop caddr rplacadd set-program) | |
138 | (defprop cadddr rplacaddd set-program) | |
139 | (defprop get get-set-program set-program) | |
140 | ||
141 | (defun get-set-program (atm prop val) | |
142 | (putprop atm val prop)) | |
143 | ||
144 | (defun rplacad (exp1 exp2) | |
145 | (rplaca (cdr exp1) exp2)) | |
146 | ||
147 | (defun rplacdd (exp1 exp2) | |
148 | (rplacd (cdr exp1) exp2)) | |
149 | ||
150 | (defun rplacadd (exp1 exp2) | |
151 | (rplaca (cddr exp1) exp2)) | |
152 | ||
153 | (defun rplacaddd (exp1 exp2) | |
154 | (rplaca (cdddr exp1) exp2)) | |
155 | ||
156 | ; | |
157 | ; ucilisp record-type package to declare records and field extraction | |
158 | ; macros. | |
159 | ; | |
160 | ||
161 | (declare (special *type*)) | |
162 | ||
163 | (defun record-type macro (l) | |
164 | (let (*type* (cadr l) *flag* (caddr l) slots (car (last l))) | |
165 | `(progn 'compile | |
166 | (defun ,*type* | |
167 | ,(slot-funs-extract slots (and *flag* '(d))) | |
168 | ,(cond ((null *flag*) (struc-cons-form slots)) | |
169 | (t (append `(cons ',*flag*) | |
170 | (list (struc-cons-form slots)))))) | |
171 | ,(cond (*flag* | |
172 | (cond ((dtpr *flag*) (setq *flag* *type*))) | |
173 | `(defun ,(concat 'is- *type*) | |
174 | macro | |
175 | (l) | |
176 | (list 'and (list 'dtpr (cadr l)) | |
177 | (list 'eq (list 'car (cadr l)) | |
178 | '',*flag*)))))))) | |
179 | ||
180 | (defun slot-funs-extract (slots path) | |
181 | (cond ((null slots) nil) | |
182 | ((atom slots) | |
183 | (eval `(defun ,(concat slots ': *type*) | |
184 | macro | |
185 | (l) | |
186 | (list ',(readlist `(c ,@path r)) | |
187 | (cadr l)))) | |
188 | (list slots)) | |
189 | ((nconc (slot-funs-extract (car slots) (cons 'a path)) | |
190 | (slot-funs-extract (cdr slots) (cons 'd path)))))) | |
191 | ||
192 | (defun struc-cons-form (struc) | |
193 | (cond ((null struc) nil) | |
194 | ((atom struc) struc) | |
195 | (t `(cons ,(struc-cons-form (car struc)) | |
196 | ,(struc-cons-form (cdr struc)))))) | |
197 | ||
198 | (defun some macro (l) | |
199 | `((lambda (f a) | |
200 | (prog () | |
201 | loop | |
202 | (cond ((null a) (return nil)) | |
203 | ((funcall f (car a)) | |
204 | (return a)) | |
205 | (t (setq a (cdr a)) | |
206 | (go loop))))) | |
207 | ,(cadr l) | |
208 | ,(caddr l))) | |
209 | ||
210 | (declare (special vars)) | |
211 | ||
212 | (defun for macro (*l*) | |
213 | (let (vars (vars:for *l*) | |
214 | args (args:for *l*) | |
215 | test (test:for *l*) | |
216 | type (type:for *l*) | |
217 | body (body:for *l*)) | |
218 | (cons (make-mapfn vars test type body) | |
219 | (cons (list 'quote | |
220 | (make-lambda | |
221 | vars (add-test test | |
222 | (make-body vars test type body)))) | |
223 | args)))) | |
224 | ||
225 | (defun type:for (*l*) | |
226 | (let (item (item:for '(do save splice filter) *l*)) | |
227 | (cond (item (car item)) | |
228 | ((error '"No body in for loop"))))) | |
229 | ||
230 | (defun error (l &optional x) | |
231 | (cond (x (terpri) (patom l) (terpri) (drain) (break) l) | |
232 | (t l))) | |
233 | ||
234 | (defun vars:for (*m*) | |
235 | (mapcan '(lambda (x) (cond ((is-var-form x) (list (var:var-form x))))) *m*)) | |
236 | ||
237 | (defun args:for (*n*) | |
238 | (mapcan '(lambda (x) | |
239 | (cond ((is-var-form x) (list (args:var-form x))))) | |
240 | *n*)) | |
241 | ||
242 | (defun is-var-form (x) (and (eq (length x) 3) (eq (cadr x) 'in))) | |
243 | ||
244 | (defun var:var-form (x) (car x)) | |
245 | (defun args:var-form (x) (caddr x)) | |
246 | ||
247 | (defun test:for (*o*) | |
248 | (let (item (item:for '(when) *o*)) | |
249 | (cond (item (cadr item))))) | |
250 | ||
251 | (defun body:for (*p*) | |
252 | (let (item (item:for '(do save splice filter) *p*)) | |
253 | (cond ((not item) (error '"NO body in for loop")) | |
254 | ((eq (length (cdr item)) 1) (cadr item)) | |
255 | ((cons 'progn (cdr item)))))) | |
256 | ||
257 | (declare (special *l* item)) | |
258 | ||
259 | (defun item:for (keywords *l*) | |
260 | (let (item nil) | |
261 | (some '(lambda (key) (setq item (assoc key (cdr *l*)))) | |
262 | keywords) | |
263 | item)) | |
264 | ||
265 | (defun make-mapfn (vars test type body) | |
266 | (cond ((equal type 'do) 'mapc) | |
267 | ((not (equal type 'save)) 'mapcan) | |
268 | ((null test) 'mapcar) | |
269 | ((subset-test vars body) 'subset) | |
270 | ('mapcan))) | |
271 | ||
272 | (defun subset-test (vars body) | |
273 | (and (equal (length vars) 1) (equal (car vars) body))) | |
274 | ||
275 | (defun make-body (vars test type body) | |
276 | (cond ((equal type 'filter) | |
277 | (list 'let (list 'x body) '(cond (x (list x))))) | |
278 | ((or (not (equal type 'save)) (null test)) body) | |
279 | ((subset-test vars body) nil) | |
280 | ((list 'list body)))) | |
281 | ||
282 | (defun add-test (test body) | |
283 | (cond ((null test) body) | |
284 | ((null body) test) | |
285 | (t (list 'cond (cond ((eq (car body) 'progn) (cons test (cdr body))) | |
286 | ((list test body))))))) | |
287 | ||
288 | (defun make-lambda (var body) | |
289 | (cond ((equal var (cdr body)) (car body)) | |
290 | ((eq (car body) 'progn) (cons 'lambda (cons vars (cdr body)))) | |
291 | ((list 'lambda vars body)))) | |
292 | ||
293 | (defun pop macro (q) | |
294 | `(prog (*q*) | |
295 | (setq *q* (car ,(cadr q))) | |
296 | (setq ,(cadr q) (cdr ,(cadr q))) | |
297 | (return *q*))) | |
298 | ||
299 | (defun length (*u*) | |
300 | (cond ((null *u*) 0) | |
301 | ((atom *u*) 0) | |
302 | ((add1 (length (cdr *u*)))))) | |
303 | ||
304 | (declare (special l)) | |
305 | ||
306 | (defun every macro (l) | |
307 | `(prog ($$k $v) | |
308 | (setq $$k ,(caddr l)) | |
309 | loop | |
310 | (cond ((null $$k) | |
311 | (return t)) | |
312 | ((apply ,(cadr l) (list (car $$k))) | |
313 | (setq $$k (cdr $$k)) | |
314 | (go loop))) | |
315 | (return nil))) | |
316 | ||
317 | (defun timer fexpr (request) | |
318 | (prog (timein timeout result cpu garbage) | |
319 | (setq timein (ptime)) | |
320 | (prog () | |
321 | loop (setq result (eval (car request))) | |
322 | (setq request (cdr request)) | |
323 | (cond ((null request) (return result)) | |
324 | ((go loop)))) | |
325 | (setq timeout (ptime)) | |
326 | (setq cpu (quotient (times 1000.0 | |
327 | (quotient (difference (car timeout) | |
328 | (car timein)) | |
329 | 60.0)) | |
330 | 1000.0)) | |
331 | (setq garbage (quotient (times 1000.0 | |
332 | (quotient (difference (cadr timeout) | |
333 | (cadr timein)) | |
334 | 60.0)) | |
335 | 1000.0)) | |
336 | (print (cons cpu garbage)) | |
337 | (terpri) | |
338 | (return result))) | |
339 | ||
340 | (defun addprop (id value prop) | |
341 | (putprop id (enter value (get id prop)) prop)) | |
342 | ||
343 | (defun enter (v l) | |
344 | (cond ((member v l) l) | |
345 | (t (cons v l)))) | |
346 | ||
347 | (defmacro subset (fun lis) | |
348 | `(mapcan '(lambda (ele) | |
349 | (cond ((funcall ,fun ele) (ncons ele)))) | |
350 | ,lis)) | |
351 | ||
352 | (defun push macro (varval) | |
353 | `(setq ,(cadr varval) | |
354 | (cons ,(caddr varval) | |
355 | ,(cadr varval)))) | |
356 | ||
357 | (putd 'consp (getd 'dtpr)) | |
358 | ||
359 | (defun prelist (a b) | |
360 | (cond ((null a) nil) | |
361 | ((eq b 0) nil) | |
362 | ((cons (car a) (prelist (cdr a) (sub1 b)))))) | |
363 | ||
364 | (defun suflist (a b) | |
365 | (cond ((null a) nil) | |
366 | ((eq b 0) a) | |
367 | ((suflist (cdr a) (sub1 b))))) | |
368 | ||
369 | (defun loop macro (l) | |
370 | `(prog ,(var-list (get-keyword 'initial l)) | |
371 | ,@(subset (function caddr) | |
372 | (setq-steps (get-keyword 'initial l))) | |
373 | loop | |
374 | ,@(apply (function append) (mapcar (function do-clause) (cdr l))) | |
375 | (go loop) | |
376 | exit | |
377 | (return ,@(get-keyword 'result l)))) | |
378 | ||
379 | (defun do-clause (clause) | |
380 | (cond ((memq (car clause) '(initial result)) nil) | |
381 | ((eq (car clause) 'while) | |
382 | (list (list 'or (cadr clause) '(go exit)))) | |
383 | ((eq (car clause) 'do) (cdr clause)) | |
384 | ((eq (car clause) 'next) (setq-steps (cdr clause))) | |
385 | ((eq (car clause) 'until) | |
386 | (list (list 'and (cadr clause) '(go exit)))) | |
387 | (t (terpri) (patom '"unknown keyword clause") | |
388 | (patom (car clause)) | |
389 | (terpri)))) | |
390 | ||
391 | (defun get-keyword (key l) | |
392 | (cdr (assoc key (cdr l)))) | |
393 | ||
394 | (defun var-list (r) | |
395 | (and r (cons (car r) (var-list (cddr r))))) | |
396 | ||
397 | (defun setq-steps (s) | |
398 | (and s (cons (list 'setq (car s) (cadr s)) | |
399 | (setq-steps (cddr s))))) | |
400 | ||
401 | (putd 'readch (getd 'readc)) | |
402 | ||
403 | ||
404 | ; | |
405 | ; ucilisp msg function. (written by jkf) | |
406 | ; | |
407 | (defmacro msg ( &rest body) | |
408 | `(progn ,@(mapcar | |
409 | '(lambda (form) | |
410 | (cond ((eq form t) '(line-feed 1)) | |
411 | ((numberp form) | |
412 | (cond ((greaterp form 0) | |
413 | `(msg-space ,form)) | |
414 | (t `(line-feed ,(minus form))))) | |
415 | ((atom form) `(patom ,form)) | |
416 | ((eq (car form) t) '(patom '/ )) | |
417 | ((eq (car form) 'e) | |
418 | `(patom ,(cadr form))) | |
419 | (t `(patom ,form)))) | |
420 | body))) | |
421 | ||
422 | ; | |
423 | ; this must be fixed to not use do. | |
424 | ; | |
425 | (defmacro msg-space (n) | |
426 | (cond ((eq 1 n) '(patom '" ")) | |
427 | (t `(do i ,n (sub1 i) (lessp i 1) (patom '/ ))))) | |
428 | ||
429 | (defmacro line-feed (n) | |
430 | (cond ((eq 1 n) '(terpr)) | |
431 | (t `(do i ,n (sub1 i) (lessp i 1) (terpr))))) | |
432 | ||
433 | (defmacro prog1 ( first &rest rest &aux (foo (gensym))) | |
434 | `((lambda (,foo) ,@rest ,foo) ,first)) | |
435 | ||
436 | (defun append1 (l x) (append l (list x))) | |
437 | ||
438 | ; compatability functions: functions required by uci lisp but not | |
439 | ; present in franz | |
440 | ; | |
441 | ; union uses the franz do loop (not the ucilisp one defined in this file). | |
442 | ; | |
443 | ||
444 | (def union | |
445 | (lexpr (n) | |
446 | (do ((res (arg n)) | |
447 | (i (sub1 n) (sub1 i))) | |
448 | ((zerop i) res) | |
449 | (mapc '(lambda (arg) | |
450 | (cond ((not (member arg res)) | |
451 | (setq res (cons arg res))))) | |
452 | (arg i))))) | |
453 | ||
454 | ||
455 | (putd 'newsym (getd 'gensym)) ; this is not exactly correct. | |
456 | ; it only uses the first letter of the arg. | |
457 | (putd 'remove (getd 'delete)) | |
458 | ||
459 | ; ignore column count | |
460 | (def sprint | |
461 | (lambda (form column) | |
462 | ($prpr form))) | |
463 | ||
464 | (def save (lambda (f) (putprop f (getd f) 'olddef))) | |
465 | ||
466 | (def unsave | |
467 | (lambda (f) | |
468 | (putd f (get f 'olddef)))) | |
469 | ||
470 | (putd 'atcat (getd 'concat)) | |
471 | (putd 'consp (getd 'dtpr)) | |
472 | ||
473 | (defun neq macro (x) | |
474 | `(not (eq ,@(cdr x)))) | |
475 | ||
476 | (putd 'gt (getd '>)) | |
477 | (putd 'lt (getd '<)) | |
478 | ||
479 | (defun le macro (x) | |
480 | `(not (> ,@(cdr x)))) | |
481 | ||
482 | (defun ge macro (x) | |
483 | `(not (< ,@(cdr x)))) | |
484 | ||
485 | (defun litatom macro (x) | |
486 | `(and (atom ,@(cdr x)) | |
487 | (not (numberp ,@(cdr x))))) | |
488 | ||
489 | (putd 'apply\# (getd 'apply)) | |
490 | ||
491 | (defun tconc (ptr x) | |
492 | (cond ((null ptr) | |
493 | (prog (temp) | |
494 | (setq temp (list x)) | |
495 | (return (setq ptr (cons temp (last temp)))))) | |
496 | ((null (car ptr)) | |
497 | (rplaca ptr (list x)) | |
498 | (rplacd ptr (last (car ptr))) | |
499 | ptr) | |
500 | (t (prog (temp) | |
501 | (setq temp (cdr ptr)) | |
502 | (rplacd (cdr ptr) (list x)) | |
503 | (rplacd ptr (cdr temp)) | |
504 | (return ptr))))) | |
505 | ||
506 | ; | |
507 | ; unbound - (setq x (unbound)) will unbind x. | |
508 | ; "this [code] is sick" - jkf. | |
509 | ; | |
510 | (defun unbound macro (l) | |
511 | `(fake -4)) | |
512 | ||
513 | ; | |
514 | ; | |
515 | ; due to problems with franz do in the compiler, this | |
516 | ; has been commented out and is left in a seperate | |
517 | ; file called /usr/lib/lisp/ucido.l | |
518 | ; | |
519 | ;(defun do macro (l) | |
520 | ; ((lambda (dotype alist) | |
521 | ; (selectq dotype | |
522 | ; (while (dowhile (car alist) (cdr alist))) | |
523 | ; (until (dowhile (list 'not (car alist)) | |
524 | ; (cdr alist))) | |
525 | ; (for (dofor (car alist) | |
526 | ; (cadr alist) | |
527 | ; (caddr alist) | |
528 | ; (cdddr alist))) | |
529 | ; `((lambda () | |
530 | ; ,@alist)))) | |
531 | ; (cadr l) | |
532 | ; (cddr l))) | |
533 | ; | |
534 | ;(defun dowhile (expr alist) | |
535 | ; `(prog (returnvar) | |
536 | ; loop | |
537 | ; (cond (,expr | |
538 | ; (setq returnvar ((lambda () | |
539 | ; ,@alist))) | |
540 | ; (go loop)) | |
541 | ; (t (return returnvar))))) | |
542 | ; | |
543 | ;(defun dofor (var fortype varlist stmlist) | |
544 | ; (selectq fortype | |
545 | ; (in `(prog (returnvar l1 l2) | |
546 | ; (setq l2 ',varlist) | |
547 | ; loop | |
548 | ; (setq l1 (car l2)) | |
549 | ; (setq l2 (cdr l2)) | |
550 | ; (cond ((null l1) | |
551 | ; (return returnvar))) | |
552 | ; (setq returnvar | |
553 | ; ((lambda (,var) | |
554 | ; ,@stmlist) | |
555 | ; (l1))) | |
556 | ; (go loop))) | |
557 | ; (on `(prog (returnvar l1 l2) | |
558 | ; (setq l2 ',varlist) | |
559 | ; loop | |
560 | ; (cond ((null l2) | |
561 | ; (return returnvar))) | |
562 | ; (setq returnvar | |
563 | ; ((lambda (,var) | |
564 | ; ,@stmlist) | |
565 | ; (l2))) | |
566 | ; (setq l2 (cdr l2)) | |
567 | ; (go loop))) | |
568 | ; (rpt `(prog (returnvar ,var) | |
569 | ; (setq ,var 1) | |
570 | ; loop | |
571 | ; (cond ((not (> ,var ,varlist)) | |
572 | ; (setq returnvar ((lambda () | |
573 | ; ,@stmlist))) | |
574 | ; (setq ,var (1+ ,var)) | |
575 | ; (go loop)) | |
576 | ; (t (return returnvar))))) | |
577 | ; nil)) | |
578 | ; | |
579 | (putd 'dddd* (getd 'boundp)) | |
580 | (defun boundp (l) | |
581 | (cond ((arrayp l)) | |
582 | ((dddd* l)))) | |
583 | ||
584 | ; | |
585 | ; now change to ucilisp syntax. | |
586 | ; | |
587 | (sstatus uctolc t) | |
588 | ; | |
589 | ; Leave backquote macro in for now. | |
590 | ; These characters should be declared as follows for real | |
591 | ; ucilisp syntax though. | |
592 | ;(setsyntax '\` 2) | |
593 | ;(setsyntax '\, 2) | |
594 | ;(setsyntax '\@ 201) | |
595 | ;(setsyntax '\@ 'macro '(lambda () (list 'quote (read)))) | |
596 | ; | |
597 | ; ~ as comment character, not ; and / instead of \ for escape | |
598 | (setsyntax '\~ 'splicing 'zapline) | |
599 | (setsyntax '\; 2) | |
600 | (setsyntax '\# 2) | |
601 | (setsyntax '\/ 143) | |
602 | (setsyntax '\\ 2) | |
603 | (setsyntax '\! 2) |