PageRenderTime 50ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/lisp-bootstrap.lisp

http://github.com/manuel/ell
Lisp | 239 lines | 184 code | 55 blank | 0 comment | 2 complexity | 6cd711b2d29ba35713513a076b9d96ad MD5 | raw file
  1. (ell-mdef defmacro
  2. (ell-lam (defmacro-form)
  3. #`(ell-mdef ,(second defmacro-form)
  4. (ell-lam (macro-call-form)
  5. (apply-syntax-list
  6. (ell-lam ,(third defmacro-form)
  7. ,(fourth defmacro-form))
  8. (syntax-list-rest macro-call-form))))))
  9. (defmacro defsyntax (name expander)
  10. #`(ell-mdef ,name ,expander))
  11. (defmacro progn (&rest exprs)
  12. #`(ell-seq ,@exprs))
  13. (defmacro lambda (sig &rest body)
  14. #`(ell-lam ,sig (progn ,@body)))
  15. (defmacro if (test then &optional (else #'unspecified))
  16. #`(ell-cond ,test ,then ,else))
  17. (defmacro when (test &rest body)
  18. #`(if ,test (progn ,@body)))
  19. (defmacro not (x)
  20. #`(if ,x #f #t))
  21. (defmacro unless (test &rest body)
  22. #`(when (not ,test) ,@body))
  23. (defmacro definedp (name)
  24. #`(ell-defp ,name))
  25. (defmacro fdefinedp (name)
  26. #`(ell-fdefp ,name))
  27. (defmacro defparameter (name value)
  28. #`(progn (ell-def ,name ,value) ',name))
  29. (defmacro defvar (name &optional (value #'unspecified))
  30. #`(defparameter ,name (if (definedp ,name) ,name ,value)))
  31. (defmacro defun/f (name function)
  32. #`(progn (ell-fdef ,name ,function) ',name))
  33. (defmacro defun (name sig &rest body)
  34. #`(defun/f ,name (ell-lam ,sig (progn ,@body))))
  35. (defmacro funcall (fun &rest args)
  36. #`(ell-app ,fun ,@args))
  37. (defmacro function (name)
  38. #`(ell-fref ,name))
  39. (defmacro setq (name value)
  40. #`(ell-set ,name ,value))
  41. (defmacro fsetq (name value)
  42. #`(ell-fset ,name ,value))
  43. (defmacro c-expression (&rest exprs)
  44. #`(ell-snip ,@exprs))
  45. (defmacro c-statement (&rest exprs)
  46. #`(ell-stmt ,@exprs))
  47. (defmacro block (label &rest body)
  48. #`(block/f (lambda (,label) ,@body)))
  49. (defmacro return-from (label &optional (value #'unspecified))
  50. #`(funcall ,label ,value))
  51. (defmacro unwind-protect (protected &rest cleanups)
  52. #`(unwind-protect/f (lambda () ,protected)
  53. (lambda () ,@cleanups)))
  54. (defmacro loop (&rest exprs)
  55. #`(ell-loop (progn ,@exprs)))
  56. (defmacro while (test &rest body)
  57. #`(block exit
  58. (loop
  59. (if ,test
  60. (progn ,@body)
  61. (return-from exit unspecified)))))
  62. (defmacro until (test &rest body)
  63. #`(while (not ,test) ,@body))
  64. (defmacro let (bindings &rest body)
  65. #`(funcall (lambda (,@(map-list (lambda (binding) (send binding (function first))) bindings))
  66. ,@body)
  67. ,@(map-list (lambda (binding) (send binding (function second))) bindings)))
  68. (defmacro do (vars test &rest body)
  69. #`(let ,(map-list (lambda (var)
  70. #`(,(send var (function first))
  71. ,(send var (function second))))
  72. vars)
  73. (while ,test
  74. ,@body
  75. ,@(map-list (lambda (var)
  76. #`(setq ,(send var (function first))
  77. ,(send var (function third))))
  78. vars))))
  79. (defmacro defclass (name &optional (superclasses #'()) &rest slot-specs)
  80. #`(progn
  81. (defvar ,name (make-class ',name))
  82. (add-superclass ,name <object>)
  83. ,@(map-list (lambda (superclass)
  84. #`(add-superclass ,name ,superclass))
  85. superclasses)
  86. ',name))
  87. (defmacro defgeneric (name &optional params)
  88. #`(defun/f ,name (if (fdefinedp ,name)
  89. (function ,name)
  90. (make-generic-function ',name))))
  91. (defmacro defmethod (name params &rest body)
  92. #`(progn
  93. (defgeneric ,name)
  94. (put-method (function ,name)
  95. (lambda ,params ,@body)
  96. ,@(dissect-generic-function-params params))
  97. ',name))
  98. (defgeneric print-object)
  99. (defmethod print-object ((o <object>))
  100. (print-object "#<object>"))
  101. (defun print (object) (print-object object))
  102. (defmacro c (&rest snippets)
  103. #`(c-expression ,@snippets))
  104. (defmacro fluid-let (name value &rest body)
  105. #`(let ((tmp ,name))
  106. (setq ,name ,value)
  107. (unwind-protect (progn ,@body)
  108. (setq ,name tmp))))
  109. (defclass <string>)
  110. (defclass <symbol>)
  111. (defclass <integer>)
  112. (defclass <boolean>)
  113. (defclass <function>)
  114. (defclass <unspecified>)
  115. (defclass <linked-list>)
  116. (defclass <linked-list-range>)
  117. (defclass <syntax-list>)
  118. (defclass <syntax-symbol>)
  119. (defclass <syntax-string>)
  120. (defclass <syntax-number>)
  121. (defclass <condition>)
  122. (defclass <unbound-variable> (<condition>)
  123. name)
  124. (defclass <unbound-function> (<condition>)
  125. name)
  126. (defclass <restart> (<condition>))
  127. (defclass <use-value> (<restart>)
  128. value)
  129. (defclass <handler>)
  130. (defclass <default-handler> (<handler>))
  131. (defclass <user-handler> (<handler>)
  132. condition-class
  133. handler-function
  134. next-handler)
  135. (defmethod print-object ((h <handler>))
  136. (print-object '#<handler>))
  137. (defun make-user-handler (condition-class handler-function next-handler)
  138. (let ((h (make <user-handler>)))
  139. (set-slot-value h 'condition-class condition-class)
  140. (set-slot-value h 'handler-function handler-function)
  141. (set-slot-value h 'next-handler next-handler)
  142. h))
  143. (defparameter *current-handler* (make <default-handler>))
  144. (defgeneric handle-condition (handler condition))
  145. (defmethod handle-condition ((h <default-handler>) (c <condition>))
  146. (print condition)
  147. (exit))
  148. (defmethod handle-condition ((h <user-handler>) (c <condition>))
  149. (if (handler-matches? h condition)
  150. (funcall (slot-value h 'handler-function)
  151. condition
  152. (lambda ()
  153. (handle-condition (slot-value h 'next-handler) condition)))
  154. (handle-condition (slot-value h 'next-handler) condition)))
  155. (defgeneric handler-matches? (user-handler condition))
  156. (defmethod handler-matches? ((h <user-handler>) (c <condition>))
  157. (type? condition (slot-value h 'condition-class)))
  158. (defun handler-bind/f (condition-class user-handler-function body-thunk)
  159. (let ((the-handler-function (lambda (condition call-next-handler)
  160. (block resume
  161. (funcall user-handler-function
  162. condition
  163. (lambda (value) (return-from resume value)))
  164. (funcall call-next-handler)))))
  165. (fluid-let *current-handler* (make-user-handler condition-class
  166. the-handler-function
  167. *current-handler*)
  168. (funcall body-thunk))))
  169. (defmacro handler-bind (condition-class user-handler-function &rest body)
  170. #`(handler-bind/f ,condition-class ,user-handler-function
  171. (lambda () ,@body)))
  172. (defun signal (condition)
  173. (handle-condition *current-handler* condition))
  174. (defun warn (condition)
  175. (signal condition)
  176. (print condition))
  177. (defun error (condition)
  178. (signal condition)
  179. (invoke-debugger condition))
  180. (defun cerror (condition)
  181. (block use-value
  182. (handler-bind <use-value> (lambda (restart resume)
  183. (return-from use-value (slot-value restart 'value)))
  184. (error condition))))