Advertisement
eudoxia

Brainfuck Interpreter in Common Lisp

Mar 19th, 2011
360
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 4.42 KB | None | 0 0
  1. ;;;; Created on 2011-03-09 19:46:53
  2. ; Updated to v0.1: 2011-08-05 23:40:51
  3.  
  4. ;;;; The author is indebted to Sylwester (http://sylwester.no/)
  5. ;;;; for accidentally being my very first tester
  6.  
  7. (defparameter *tape* (make-array 100 :initial-element 0))
  8. (defparameter *position* 0)
  9. (defparameter *userposition* 0)
  10. (defparameter *openbracket-appear* 0)
  11. (defparameter *closebracket-appear* 0)
  12. (defparameter loopback-appear 0) ;Piece of shit helper variable that doesn't even deserve its earmuffs
  13. (defparameter loopforward-appear 0)
  14.  
  15. ;(defparameter *errors* (make-hash-table))
  16. ;;Defining error types:
  17. ;   (setf (gethash 'input-type-str *errors*) '(Input cannot be of type string))
  18. ;   (setf (gethash 'input-type-nil *errors*) '(Input cannot be of type null))
  19. ;   (setf (gethash 'tape-string *errors*)    '(Cannot concatenate string with number objects))
  20. ;   (setf (gethash 'input-unknown *errors*)  '(Input unknown or invalid))
  21.    
  22. ;(defun err (code)
  23. ;   (format t "~&Error:~s" (gethash *errors* code)))
  24. ; Get rid of this... Maybe
  25.    
  26. (defparameter output-opcodes? nil)
  27.  
  28. (defun output-opcodes (value)
  29.     (if (not (null value))
  30.         (setf output-opcodes? t)
  31.         (setf output-opcodes?`nil)))
  32.  
  33. (defun outputdata()
  34.     (format t "~a" (code-char (aref *tape* *position*))))
  35.  
  36. (defun readindata()
  37.     (force-output *query-io*)
  38.     (setf (aref *tape* *position*) (char-code (elt (string (read)) 0)))) ;only uppercase. bummer. I can't get READ-LINE to work in LispIDE >:c
  39.    
  40. (defun turn-literal-input (literal-input)
  41.     (coerce literal-input 'list)
  42. )
  43.  
  44. (defun bf(userinput)
  45.   (setf userinput (turn-literal-input userinput))
  46.    (loop
  47.         (if (not (< *userposition* (length userinput)))
  48.             (return))
  49.         (cond   ((equal (nth *userposition* userinput) #\+)
  50.                     (incf (aref *tape* *position*))
  51.                     (if output-opcodes? (format t "OP1;")))
  52.                 ((equal (nth *userposition* userinput) #\-)
  53.                     (if (eql 0 (aref *tape* *position*))
  54.                         (return)
  55.                         (decf (aref *tape* *position*)))
  56.                     (if output-opcodes? (format t "OP2;")))
  57.                 ((equal (nth *userposition* userinput) #\>)
  58.                     (if (eql *position* (1- (length *tape*)))
  59.                         (setf *position* 0)
  60.                         (incf *position*))
  61.                     (if output-opcodes? (format t "OP3;")))
  62.                 ((equal (nth *userposition* userinput) #\<)
  63.                     (if (eql 0 *position*)
  64.                         (setf *position* (1- (length *tape*)))
  65.                         (decf *position*))
  66.                     (if output-opcodes? (format t "OP4;")))
  67.                 ((equal (nth *userposition* userinput) #\.)
  68.                     (outputdata)
  69.                     (if output-opcodes? (format t "OP5;")))
  70.                 ((equal (nth *userposition* userinput) #\,)
  71.                     (readindata)
  72.                     (if output-opcodes? (format t "OP6;")))
  73.                 ((equal (nth *userposition* userinput) #\!)
  74.                     (return)
  75.                     (if output-opcodes? (format t "OP7;")))
  76.                 ((equal (nth *userposition* userinput) #\[)
  77.                     (if output-opcodes? (format t "OP8;"))
  78.                     (incf *openbracket-appear*)
  79.                     (if (eql (aref *tape* *position*) 0)
  80.                         (loop
  81.                             (if (equal (nth *userposition* userinput) #\])
  82.                                     (progn (incf loopforward-appear)
  83.                                            (if (equal loopforward-appear *openbracket-appear*)
  84.                                                (progn (if (not (eql *userposition* (1- (length userinput))))
  85.                                                             (incf *userposition*))
  86.                                                       (return)))))
  87.                             (incf *userposition*))))
  88.                 ((equal (nth *userposition* userinput) #\])
  89.                     (if output-opcodes? (format t "OP9;"))
  90.                     ;;Oh dear
  91.                     (incf *closebracket-appear*)
  92.                     (if (not (eql (aref *tape* *position*) 0))
  93.                         (loop
  94.                             (cond ((equal (nth *userposition* userinput) #\[)
  95.                                     (incf loopback-appear)
  96.                                     (if (eql loopback-appear *closebracket-appear*)
  97.                                             (return))))
  98.                             (decf *userposition*)))))
  99.         (incf *userposition*)
  100.     )
  101.     (if output-opcodes? (format t "EOF;;"))
  102.     (setf *userposition* 0 *openbracket-appear* 0 *closebracket-appear* 0 loopback-appear 0 loopforward-appear 0)
  103.   *tape*
  104. )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement