home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / PROG / MISC / PCLISP30.ZIP / PC-LISP.L < prev    next >
Encoding:
Text File  |  1987-04-05  |  13.3 KB  |  352 lines

  1. ;; PC-LISP.L  for PC-LISP.EXE V2.15                                
  2. ;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                     
  3. ;;     A small library of functions to help fill in the gap between PC and      
  4. ;; Franz Lisp. These functions are not documented in the PC-LISP.DOC file but 
  5. ;; any Franz manual will cover them in detail. Especially the backquote 
  6. ;; and other macro definitions towards the end of the file. These functions
  7. ;; were written pretty hastily so there could be bugs. Check them out for
  8. ;; yourself to make sure they behave in the way you are used to with Franz.
  9. ;;
  10. ;;    This file is automatically loaded by PC-LISP.EXE. It should either    
  11. ;; be located in the current working directory, or in a library directory
  12. ;; whose path is set in the LISP_LIB environment variable. All load files
  13. ;; should be put in one of your LISP_LIB directories. You could also strip 
  14. ;; comments and white space from this file to make it load faster. This
  15. ;; is important if you load this file every time you run PC-LISP. 
  16. ;;      
  17. ;;              Peter Ashwood-Smith
  18. ;;                November 1986
  19. ;;
  20. ;; Pretty Print: (pp [(F file) (E expr) (P port)] symbol)
  21. ;; ~~~~~~~~~~~~
  22. ;;    Print in a readable way the function associated with 'symbol'. If
  23. ;; the parameter (F file) is specified the output goes to file 'file. If
  24. ;; the parameter (P port) is specified the output goes to the open port
  25. ;; 'port'. If the parameter (E expr) is specified the expression 'expr'
  26. ;; is evaluated before the function is pretty printed. Makes use of the
  27. ;; predefined symbol poport whose binding is 'stdout'.
  28.  
  29. (setq displace-macros t)        ; override Franz default (faster do loops)
  30.  
  31. (defun pp fexpr(l)
  32.        (prog (expr name port alt)
  33.          (setq port poport)
  34.          (cond ((= (length l) 1) (setq name (car l)))
  35.            ((= (length l) 2) (setq name (cadr l) alt (car l)))
  36.            (t (return nil))
  37.          )
  38.          (cond ((null (getd name)) (return nil)))
  39.          (setq expr (cons 'def (cons name (list (getd name)))))
  40.          (cond ((null alt) (go SKIP)))   
  41.          (cond ((eq (car alt) 'F) (setq port (fileopen (cadr alt) 'w)))
  42.            ((eq (car alt) 'P) (setq port (cadr alt)))
  43.            ((eq (car alt) 'E) (eval (cadr alt)))
  44.            (t (return nil)))
  45.          (cond ((null port) (patom "cannot open port\n") (return nil)))
  46.        SKIP  (pp-form expr port 0)
  47.          (cond ((not (equal port poport)) (close port)))
  48.          (return t)
  49.        )
  50. )
  51.  
  52. ;; _SCL_ Spit Character Loop 
  53. ;; ~~~~~~~~~~~~~~~~~~~~~~~~~
  54. ;; Prints 'char' 'n' times on port 'port', used by msg for (N) and (B)
  55.   
  56. (defun _SCL_(port char n)
  57.        (prog nil
  58.      nxt: (cond ((zerop n) (return)))
  59.           (patom char port)
  60.           (setq n (1- n))
  61.           (go nxt:)
  62.        )
  63. )     
  64.  
  65. ;; (msg [B|N|D] [ (P pt) (B n) | (N n)] s*)
  66. ;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  67. ;; Prints a message on standard output port 'poport'. Where N is a new
  68. ;; line, (N n) means n new lines. B is a blank, (B n) means n blanks 
  69. ;; D means (Dran port) unsupported in PC-LISP. (P pt) means switch output
  70. ;; to port pt rather than poport. s, is any s expression which will be 
  71. ;; evaluated and then printed on current output port.
  72.  
  73. (defun msg fexpr(l)
  74.        (prog (s op)
  75.          (setq op poport)   
  76.     nxt: (cond ((null l)(return)))
  77.          (setq s (car l) l (cdr l))
  78.          (cond ((eq s 'N) (patom "\n" op))
  79.            ((eq s 'B) (patom " " op))
  80.            ((eq s 'D) (patom "msg : Drain unsupported\n"))
  81.            ((listp s)
  82.                (cond ((eq (car s) 'P)(setq op (cadr s)))
  83.                  ((eq (car s) 'B)(_SCL_ op " " (cadr s)))
  84.                  ((eq (car s) 'N)(_SCL_ op "\n" (cadr s)))
  85.                  (t (patom (eval s) op)) 
  86.                )
  87.            )
  88.            (t (patom (eval s) op))
  89.          )
  90.          (go nxt:)
  91.        )
  92.  
  93. ;; (lineread [port])
  94. ;; ~~~~~~~~~~~~~~~~~
  95. ;; Very simple line read function. Takes atoms from the piport or port until
  96. ;; a new line is encountered. It returns these atoms or S-expressions as a
  97. ;; list 'ret. 
  98.  
  99. (defun lineread fexpr(l)
  100.        (prog (port ret)
  101.          (setq port piport)   
  102.          (cond ((not (null l)) (setq port (eval (car l)))))
  103.          (setq ret (list (read port)))
  104.     nxt: (cond ((eq (readc port) '|\n|)(return ret)))
  105.          (setq ret (append ret (list (read port))))
  106.          (go nxt:)
  107.        )
  108. )
  109.  
  110. ;; ----------- ASSORTED SMALL FUNCTIONS ------------
  111.  
  112. (defun tailp(l1 l2)(cond ((null l2) nil)((eq l1 l2) l1)(t(tailp l1(cdr l2]  
  113. (defun bcdp(x) nil)             
  114. (defun bigp(x) nil)             
  115. (defun dtpr(x) (and (listp x) (not (null x))))  
  116. (defun consp(x) (and (listp x) (not (null x))))
  117. (defun litatom(n) (and(atom n)(not(floatp n]   
  118. (defun purep(n) nil)
  119. (defun symbolp(n) (litatom n))                  
  120. (defun valuep(n) nil)
  121. (defun vectorp(n) nil)
  122. (defun typep(n)(type n))
  123. (defun eqstr(a b)(equal a b))
  124. (defun neq(a b)(not(eq a b)))
  125. (defun nequal(a b)(not(equal a b)))
  126. (defun append1(a b)(append a (list b)))
  127. (defun ncons(a)(cons a nil))
  128. (defun xcons(a b)(cons b a))
  129. (defun nthelem(n l) (nth (1- n) l))
  130. (defun minus(n)(- 0 n))
  131. (defun onep(n)(= 1 n))
  132. (defun infile(f)(fileopen f 'r)) 
  133. (defun pntlen(a) (flatsize a))
  134. (defun probef(f &aux tmp)(setq tmp (fileopen f 'r))(and tmp (close tmp)))
  135. (defun shell()(exec "COMMAND.COM"))     ; must have a COMMAND.COM on PATH!
  136.  
  137. (defun error n
  138.        (cond ((= n 1) (patom (arg 1)) (terpri) (err nil))
  139.          ((= n 2) (patom (arg 1)) (patom (arg 2)) (terpri) (err nil))
  140.          (t (error "error bad args"))]
  141.  
  142. (defun signp(test exp)
  143.        (cond ((eq test 'ge) (or (zerop exp)(plusp exp)))
  144.          ((eq test 'g ) (plusp exp))
  145.          ((eq test 'n ) (not (zerop exp)))
  146.          ((eq test 'e ) (zerop exp))
  147.          ((eq test 'le) (or (zerop exp)(minusp exp)))
  148.          ((eq test 'l)  (minusp exp))
  149.          (t (princ "-- error signp bad test ---\n"))))
  150.  
  151. ;; ----------- ASSORTED SMALL MACROS --------------
  152.  
  153. (defun >&  macro(l) (cons '> (cdr l)))                
  154. (defun >=  macro(l) (cons 'not (list (cons '< (cdr l))))) 
  155. (defun >=& macro(l) (cons 'not (list (cons '< (cdr l)))))
  156. (defun <&  macro(l) (cons '< (cdr l)))
  157. (defun <=  macro(l) (cons 'not (list (cons '> (cdr l)))))
  158. (defun <=& macro(l) (cons 'not (list (cons '> (cdr l)))))
  159. (defun =&  macro(l) (cons '= (cdr l)))
  160.  
  161. (defun terpri macro(l)                      ; makes (terpri [port])
  162.       (append (list 'princ "\n")(cdr l)))   ; into  (princ "\n" [port])
  163. (defun tyo macro(l)                         ; makes (princ (asci f) [port])
  164.       (cons 'princ (cons (cons 'ascii (list (cadr l))) (cddr l))))
  165. (defun store macro(l)                       ; makes (store (x -dims-) exp)
  166.       (cons (caadr l)                       ; into  (x exp -dims-)
  167.         (append (cddr l) (cdadr l))))
  168. (defun arraycall macro(l)                   ; makes (arraycall f a -n-)
  169.       (cddr l))                             ; into  (a -n-)
  170.  
  171. ;; BACKQUOTE READ MACRO AND PARTS  
  172. ;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  173. ;;      This  file  describes  the back quote macro for PC-LISP. It works in
  174. ;; exactly the same way as the  FRANZ  backquote  macro works. Basically the
  175. ;; backquote macro ` is supposed to  work  together  with the comma , and at
  176. ;; @ macros. As follows: Backquote  has the same effect as ' except that any
  177. ;; elements or  sub  elements  that  are preceeded by , are evaluated. If an
  178. ;; element  is  preceeded  by  ,@  then  the element is evaluated and should 
  179. ;; evaluate to  a  list.  This  list  is  spliced into the built list. I use 
  180. ;; cons  to  do  list  building  and append to do list splicing. For example
  181. ;; the  input:  `(a ,b c)  will  be  read in  as  (a (*unquote* b) c) by the
  182. ;; back quote read macro because the  comma  macro  will have read the b and
  183. ;; built up the list (*unquote* b). Next the back quote macro passes control
  184. ;; to the _BQB_ function (Back Quote  Builder). This will construct the list
  185. ;; (cons 'a (cons b (cons 'c nil)))  which  when evaluated gives the desired    
  186. ;; result. If the , were  followed  by  an @ then the @ would build the form
  187. ;; (*splice* b). Then the  , would get this form and the function _CB_ comma
  188. ;; builder would then make  then pass the form unchanged. Next the backquote
  189. ;; builder  _BQB_  would  get the form (a (*splice* b) c) and build the form
  190. ;; (cons 'a (append b (cons 'c nil)))  which will cause the value of b to be
  191. ;; spliced into the list rather than forming a sublist element as desired.
  192.  
  193. (defun _BQB_(Sexp) 
  194.        (cond ((null Sexp) Sexp)
  195.          ((atom Sexp) (list 'quote Sexp))
  196.          ((eq (car Sexp) '*unquote*)
  197.           (cadr Sexp))
  198.          ((and(listp (car Sexp)) (eq (caar Sexp) '*splice*))
  199.           (list 'append (cadar Sexp)
  200.                  (_BQB_ (cdr Sexp))))
  201.          ( t (list 'cons (_BQB_ (car Sexp))
  202.                  (_BQB_ (cdr Sexp))))
  203.        )
  204. )
  205.  
  206. (defun _CB_(Sexp)
  207.        (cond ((null Sexp) Sexp)
  208.          ((atom Sexp) (list '*unquote* Sexp))
  209.          ((eq (car Sexp) '*splice*) Sexp)
  210.          (t (list '*unquote* Sexp))
  211.        )
  212. )
  213.  
  214. (setsyntax '|`| 'vmacro '(lambda()(_BQB_ (read))))
  215. (setsyntax '|,| 'vmacro '(lambda()(_CB_  (read))))
  216. (setsyntax '|@| 'vmacro '(lambda()(list '*splice* (read))))
  217.  
  218.  
  219. ;; macro  : (let ((p1 v1)(p2 v2)...(pn vn)) e1 e2 ... en)
  220. ;; ~~~~~  
  221. ;;      Let macro introduces local variables. Much used in Franz code it
  222. ;; basically creates a lambda expression of the form:
  223. ;;
  224. ;;          ((lambda(p1 p2 ... pn) e1 e2 ... en) v1 v2 ...vn)
  225. ;; Note that (p1 v1) may be of the form p1 in which case the variable
  226. ;; is bound to nil. 
  227.  
  228. (defun let macro(l)
  229.     `((lambda ,(mapcar '_lvar (cadr l))
  230.          ,@(cddr l)
  231.       )
  232.       ,@(mapcar '_lval (cadr l] 
  233.  
  234. (defun _lvar (l)(cond ((atom l) l) (t (car l]    
  235.  
  236. (defun _lval (l)(cond ((atom l) nil) (t (cadr l]    
  237.  
  238. ;; macro defmacro
  239. ;; ~~~~~~~~~~~~~~
  240. ;;    Like defun except that it declares a macro. This is more convenient
  241. ;; than using the defun name macro(l) because access to variables can be
  242. ;; named. 
  243.  
  244. (defun defmacro fexpr(l)
  245.     (putd (car l)
  246.       (cons 'macro 
  247.          (list '(defmacroarg)
  248.            `((lambda ,(__dmlats (cadr l))  
  249.                  ,@(cddr l))
  250.              ,@(__dmal (cadr l))]
  251.  
  252. (defun defcmacro fexpr(l)         ; no such thing as compiler yet but
  253.     (putd (car l)                 ; keeps interpreter happy
  254.       (cons 'macro 
  255.          (list '(defmacroarg)
  256.            `((lambda ,(__dmlats (cadr l))  
  257.                  ,@(cddr l))
  258.              ,@(__dmal (cadr l))]
  259.  
  260. (defun __dma(l a)
  261.       (cond ((null l) nil)
  262.         ((atom l) (setq __dmalhold (cons a __dmalhold)))      
  263.         (t (__dma (car l) (cons 'car (list a)))
  264.            (__dma (cdr l) (cons 'cdr (list a)))]
  265.  
  266. (defun __dmal(l &aux __dmalhold)
  267.     (__dma l '(cdr defmacroarg)) 
  268.     (reverse __dmalhold ]
  269.  
  270. (defun __dmlats(l)
  271.     (cond ((null l) nil)
  272.           ((atom l) (list l))
  273.           ( t (append (__dmlats (car l)) (__dmlats (cdr l)))]
  274.  
  275. ;;  (do "symbol" "exp1" "exp2" "test" -"exps"-)        ; case 1
  276. ;;  (do -"(symbol [exp1 [exp2]])"- "test" -"exps"-)    ; case 2
  277. ;;   
  278. (defun _do2a_(l) (cond ((cdr l)(cons (car l) (list(cadr l))))(t nil]  
  279. (defun _do2b_(l) (cond ((cddr l)(cons (car l) (list(caddr l))))(t nil]  
  280.  
  281. (defun _do2_(l)                            ; complex do loop case, many locals
  282.      `(prog ,(mapcar 'car (cadr l))
  283.         (PAR-setq ,@(apply 'append (mapcar '_do2a_ (cadr l))))
  284.      _dlab_ 
  285.         (cond (,(caaddr l) (return ,@(cdaddr l)) )) 
  286.         ,@(cdddr l)
  287.         (PAR-setq ,@(apply 'append (mapcar '_do2b_ (cadr l))))
  288.         (go _dlab_)
  289.       )
  290. )
  291.  
  292. (defun _do1_(l)                            ; simple do loop case, one local
  293.      `(prog (,(nth 1 l))
  294.         (setq ,(nth 1 l) ,(nth 2 l))
  295.      _dlab_ (cond (,(nth 4 l) (return))) 
  296.         ,@(cdddddr l)
  297.         (setq ,(nth 1 l) ,(nth 3 l))
  298.         (go _dlab_)
  299.       )
  300. )
  301.  
  302. (defun do macro(l)                        ; select simple/complex case.
  303.        (cond ((atom (cadr l)) (_do1_ l))
  304.          (t (_do2_ l))))
  305.  
  306. ;; This macro allow the following forms:
  307. ;;      (if a then b)   ==>  (cond (a b))
  308. ;;      (if a thenret)  ==>  (cond (a))
  309. ;;      (if a then b else c) ==> (cond (a b) (t c))
  310. ;;      (if a then b b2              ==> (cond (a b b2) (c d d2) (t e))
  311. ;;       elseif c then d d2
  312. ;;       else e)
  313. ;;
  314. ;;  I stole this from the SLANG package and changed its name to 'if from
  315. ;; 'If.
  316. ;;
  317. (defun if macro  (lis) 
  318.        (prog (majlis minlis revl)
  319.          (do ((revl (reverse lis) (cdr revl)))
  320.          ((null revl))
  321.          (cond ((eq (car revl) 'else)
  322.             (setq majlis `((t ,@minlis) ,@majlis)
  323.                   minlis nil))
  324.                ((or (eq (car revl) 'then) (eq (car revl) 'thenret))
  325.             (setq revl (cdr revl)
  326.                   majlis `((,(car revl) ,@minlis) ,@majlis)
  327.                   minlis nil))
  328.                ((eq (car revl) 'elseif))
  329.                ((eq (car revl) 'if)
  330.             (setq majlis `(cond ,@majlis)))
  331.                (t (setq minlis `( ,(car revl) ,@minlis)))))
  332.          ; we displace the previous macro, that is we actually replace
  333.          ; the if list structure with the corresponding cond, meaning
  334.          ; that the expansion is done only once
  335.          (rplaca  lis (car majlis))
  336.          (rplacd lis (cdr majlis))
  337.          (return majlis)))
  338.  
  339. ;; A couple of rareley used definitions but just to complete the chapter
  340. ;; on mapping functions, here they are:
  341. ;;
  342. (defun mapcan macro(l) `(apply 'nconc (mapcar ,@(cdr l))))
  343. (defun mapcon macro(l) `(apply 'nconc (maplist ,@(cdr l))))
  344.  
  345. ;; The progS functions again to fill in some gaps
  346. ;;
  347. (defun progn macro(l) `(prog nil ,@(cdr l)))
  348. (defmacro prog1(a . b) `(prog (__p1ret) (setq __p1ret ,a) ,@b __p1ret))
  349. (defmacro prog2(a b . c) `(prog (__p2ret) ,a (setq __p2ret ,b) ,@c __p2ret))
  350.  
  351.