if.sl 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. % IF macro
  2. % Cris Perdue 8/19/82
  3. (setq *usermode nil)
  4. % Syntax of new IF is:
  5. % (if <expr> [then <expr> ... ] [<elseif-part> ... ] [else <expr> ... ])
  6. % <elseif-part> = elseif <expr> [then <expr> ... ]
  7. % This syntax allows construction of arbitrary CONDs.
  8. (defun construct-new-if (form)
  9. (let (
  10. (clause)
  11. (next-clause)
  12. (stmt (list 'cond))
  13. (e form))
  14. (while e
  15. (cond
  16. ((or (sym= (first e) 'if)
  17. (sym= (first e) 'elseif))
  18. (cond ((or (null (rest e))
  19. (not (or (null (rest (rest e)))
  20. (sym= (third e) 'then)
  21. (sym= (third e) 'else)
  22. (sym= (third e) 'elseif))))
  23. (error 0 "Can't expand IF.")))
  24. (setq next-clause (next-if-clause e))
  25. (setq clause
  26. (cond ((and (rest (rest e))
  27. (sym= (third e) 'then))
  28. (cons (second e)
  29. (ldiff (pnth e 4) next-clause)))
  30. (t (list (second e)))))
  31. (nconc stmt (list clause))
  32. (setq e next-clause)
  33. (next))
  34. ((sym= (first e) 'else)
  35. (cond ((or (null (rest e)) (next-if-clause e))
  36. (error 0 "Can't expand IF.")))
  37. (nconc stmt (list (cons t (rest e))))
  38. (exit))))
  39. stmt))
  40. (defun next-if-clause (tail)
  41. (for (on x (rest tail))
  42. (do (cond ((or (sym= (first x) 'else)
  43. (sym= (first x) 'elseif))
  44. (return x))))
  45. (returns nil)))
  46. (defun sym= (a b) (eq a b))
  47. (defun ldiff (x y)
  48. (cond ((null x) nil)
  49. ((eq x y) nil)
  50. (t (cons (first x) (ldiff (rest x) y)))))
  51. % Checks for (IF <expr> <KEYWORD> . . . ) form. If keyword form,
  52. % does fancy expansion, otherwise expands compatibly with MacLISP
  53. % IF expression. <KEYWORD> ::= THEN | ELSE | ELSEIF
  54. (dm if (form)
  55. (let ((b (rest (rest form)))
  56. (test (second form)))
  57. (cond
  58. ((or (sym= (first b) 'then)
  59. (sym= (first b) 'else)
  60. (sym= (first b) 'elseif))
  61. (construct-new-if form))
  62. ((eq (length b) 1) `(cond (,test ,(nth b 1))))
  63. (t `(cond (,test ,(nth b 1)) (t ,@(pnth b 2)))))))