/brainfuck.lisp

https://github.com/derrida/cl-ffff · Lisp · 105 lines · 81 code · 18 blank · 6 comment · 3 complexity · 5b3b959670aed3d29528f86ee4b2d917 MD5 · raw file

  1. ;;;; brainfuck.lisp
  2. ;;;; .polyvalent.org
  3. ;;;; michael simpson
  4. ;;;;
  5. ;;;; bsd-license. have fun!
  6. (defpackage #:brainfuck
  7. (:use #:cl))
  8. (in-package #:brainfuck)
  9. (defparameter index 0)
  10. (defparameter ptr '(0))
  11. (defparameter *code* "")
  12. (defun set-reader-macro ()
  13. (set-macro-character #\] (get-macro-character #\) ))
  14. (defun bf-read (stream char arg)
  15. (declare (ignore char arg))
  16. (read-delimited-list #\] stream t))
  17. (set-dispatch-macro-character #\# #\[ #'bf-read))
  18. (let ((reader))
  19. (set-reader-macro)
  20. (defun main ()
  21. (format t "~A " "/>>")
  22. (setq reader (read))
  23. (brainfuck-reader reader)
  24. (main)))
  25. (defun brainfuck-reader (input)
  26. (cond
  27. ((stringp input) (bf-read-string input))
  28. ((typep input 'symbol) (bf-read-char input)))
  29. (setf index 0))
  30. ;(let ((string (loop for char across string collect char)))
  31. (defun bf-read-string (string)
  32. (loop for c on `,(coerce string 'list) do (bf-read-char (car c))))
  33. (defun bf-read-char (char)
  34. (case char
  35. (#\+ (funcall #'bf+))
  36. (#\- (funcall #'bf-))
  37. (#\> (bf>))
  38. (#\< (bf<))
  39. (#\. (funcall #'bf\.))
  40. (#\, (funcall #'bf\,))
  41. (ptr (format t "=> ~A~%" ptr))
  42. (code (format t "=> ~A~%" *code*))
  43. (index (format t "=> ~A~%" index))
  44. (zero (bf-zero))
  45. (clear (bf-zero))
  46. (quit (error "You quit deliberately."))
  47. (otherwise (error "Not a valid BrainFuck command."))))
  48. (defun record-to-*code* (c)
  49. (setf *code* (concatenate 'string *code* (string c))))
  50. (defun add-cell ()
  51. (setf ptr (reverse ptr))
  52. (push 0 ptr)
  53. (incf index)
  54. (setf ptr (reverse ptr)))
  55. (defun pop-cell ()
  56. (setf ptr (reverse ptr))
  57. (pop ptr)
  58. (setf ptr (reverse ptr)))
  59. (defun bf> ()
  60. (add-cell)
  61. (record-to-*code* #\>)
  62. (nth index ptr))
  63. (defun bf< ()
  64. (record-to-*code* #\<)
  65. (pop-cell)
  66. (decf index)
  67. (nth index ptr))
  68. (defun bf+ ()
  69. (record-to-*code* #\+)
  70. (setf (elt ptr index) (incf (elt ptr index))))
  71. (defun bf- ()
  72. (record-to-*code* #\-)
  73. (decf (nth index ptr)))
  74. (defun bf\. ()
  75. (record-to-*code* #\.)
  76. (format t "=> ~A~%"
  77. (mapcar #'code-char (loop for i in ptr collect i))))
  78. (defun bf\, ()
  79. (record-to-*code* #\,)
  80. (format t "~A =>" ptr)
  81. (format t "~A~%"
  82. (mapcar #'code-char (loop for i in ptr collect i))))
  83. (defun bf-zero ()
  84. (setf ptr '(0))
  85. (setf index 0)
  86. (setf *code* "")
  87. (format t "=> Fresh symbols have now been initialized. Have some brainfuck.~%"))