Recently Written · git

LispBrain

The best Brainfuck debugger available, if you know how the Common Lisp debugger works. Uses Common Lisp's ease of debugging to make debugging Brainfuck code easy. Almost entirely useless.

git clone https://github.com/equwal/LispBrain

Log | Files | Refs


commit 3201e41ee1948be15dcf947a85cc468b8c271ced
Spenser Truex <struex0@gmail.com>
2016-02-15 20:24:22 -0800

Provided debugging facilities

 README.md        | 54 ++++++++++++++++++++++++++++++------------------------
 interpreter.lisp | 20 +++++++++++---------
 packages.lisp    | 25 +++++++++++++++++++++----
 3 files changed, 62 insertions(+), 37 deletions(-)
diff --git a/README.md b/README.md
index e3c5246..e46d83e 100644
--- a/README.md
+++ b/README.md
@@ -50,40 +50,46 @@ If everything runs smoothly you will be ready to brainfuck. If not then please *
 


 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„
†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"
 ```
 
-#Debugging
+#Debugging Brainfuck
 
-Debugging brainfuck code can be done using all the normal Common Lisp functions: `step`, `trace`, `time`, etc., but require the user to understand how the internal code works. For this reason there is no tutorial on how to properly debug your brainfuck code, just a couple examples. The user is encouraged to read the Common Lisp source code to get all the features of the Lisp debugging environment in their brainfuck.
+Debugging brainfuck code can be done using all the normal Common Lisp functions: `step`, `trace`, `time`, etc. The following functions and variables are exported and may be useful for debugging brainfuck code:
+```
+brain:fuck ;Used to execute a brainfuck string directly
+brain:*tape-size-default* ;Number of cells in the tape Default: 30,000
+brain:decf-byte ;The - operator function
+brain:incf-byte ;The + operator function
+brain:read-this-byte ;The , operator function
+brain:print-this-byte ;The . operator function
+brain:right-shift ;The > operator function
+brain:left-shift ;The < operator function
+brain:one-off-fuck ;Function called to loop over each character in the code
+brain:*separators* ;Characters that terminate #F brainfuck code Default: (#\Space, #\Newline)
+brain:byte-value ;Returns the value of the curren byte at the *pointer* position
+brain:*tape* ;Returns the entire tape
+brain:*pointer* ;The current position in the byte tape. Useful with byte-value Default: Exactly in the middle of the tape. (15,000)
+```
+Note that the variables `*tape*` and `*pointer*` are reset upon executing new brainfuck code. Once the execution is finished their state is frozen in time and ready to be debugged.
 
-To debug your brainfuck code you should start with:
+#Examples for Debugging:
+Suppose you want to make the tape only 10 bytes long (instead of the default 30000) This way you can easily view the tape contents after execution:
 ```
-> (in-package :brain)
+> (setf brain:*tape-size-default* 10) ;Sets the tape to only elements 0 to 9
+> #f->+
+> brain:*tape* ;Holds the byte tape vector
+#(0 0 0 0 0 255 1 0 0 0)
+> brain:*pointer*
+6
 ```
-to get access to the internal functions.
-
-Suppose you want to make the tape only 10 bytes long (instead of the default 30000):
-```
-> (in-package :brain)
-> (setf *tape-size-default* 10) ;Sets the tape to only elements 0 to 9
-> (reset-globals) ;Resets the tape, pointer, and a few other things
-> *tape* ;Holds the byte tape vector
-#(0 0 0 0 0 0 0 0 0 0)
-> *pointer* ;This shows that the pointer gets moved to the middle regardless of the size
-5
+Suppose you want to find information about how often and with what values + and - were used:
 ```
-Suppose you want to find information about the + and - operations:
-```
-> (trace incf-byte decf-byte)
-> (fuck "+-")
-;;;; The following text is implementation dependent, and looks like this only on SBCL
+> (trace brain:incf-byte brain:decf-byte)
+> (brain:fuck "+-")
+;;;; The following text is implementation dependent, and looks exactly like this only on SBCL
   0: (INCF-BYTE)
   0: INCF-BYTE returned 1
   0: (DECF-BYTE)
   0: DECF-BYTE returned 0
 ""
 ```
-#TODO:
-- Test on other implementations and operating systems (CCL, ECL, ABCL, CLISP, AllegroCL, LispWorks), to verify that it works.
-- Make debugging more user friendly. Better documentation and some external functions to be called with `brain:function` or `brain:*variable*`
-
 This software is licensed under the MIT free software license.
 ====
\ No newline at end of file
diff --git a/interpreter.lisp b/interpreter.lisp
index cda089a..d33923b 100644
--- a/interpreter.lisp
+++ b/interpreter.lisp
@@ -22,12 +22,19 @@
 (defvar *output* ""
   "Defaults to an empty string because it is setf'd by other functions")
 
+(defparameter *initial-element* 0
+  "initial value for inside the byte array")
+
+(defparameter *separators* '(#\Newline #\Space)
+  "#F notation separators.
+These can be changed to allow whitespace comments")
 
 (defun make-tape-array ()
   "Creates a new tape array"
   (make-array *tape-size-default*
 	      :element-type '(unsigned-byte 8)
-	      :initial-element 0))
+	      :initial-element *initial-element*))
+
 (defvar *tape* (make-tape-array)
   "The tape array used to store each byte")
 
@@ -65,9 +72,8 @@
 (defun shorthand-fuck-aux (stream list)
   (let ((char (read-char stream nil nil)))
     ;; TODO: Replace the #\Space, #\Newline, #\Tab with proper separations
-    (if (or (char-equal char #\Space)
-	    (char-equal char #\Newline)
-	    (char-equal char #\Tab)
+    (if (or (some #'(lambda (x) (char-equal x char))
+		  *separators*)
 	    (null char))
 	(char-list->string (nreverse list))
 	(shorthand-fuck-aux stream (push char list)))))
@@ -179,7 +185,7 @@
 (defun skip-loop (position)
   (skip-loop-aux position 0))
 
-(defun interpret (brainfuck-string)
+(defun fuck (brainfuck-string)
   "Interpret the brainfuck"
   (reset-globals)
   (setf *brainfuck* brainfuck-string)
@@ -193,7 +199,3 @@
 				      (1- (skip-loop position))))))
   *output*)
 
-(defun fuck (brainfuck-string)
-  "An alias for the interpret function"
-  (interpret brainfuck-string))
-
diff --git a/packages.lisp b/packages.lisp
index 91b907f..62f268e 100644
--- a/packages.lisp
+++ b/packages.lisp
@@ -8,7 +8,24 @@
 (in-package :cl-user)
 (defpackage :brain
   (:use :cl)
-  (:export :interpret
-	   :fuck))
-
-
+  (:export :fuck ;Used to execute a brainfuck string directly
+	   :*tape-size-default* ;Number of cells in the tape
+	   :decf-byte ;The - operator
+	   :incf-byte ;The + operator
+	   :read-this-byte ;The , operator
+	   :print-this-byte ;The . operator
+	   :right-shift ;The > operator
+	   :left-shift ;The < operator
+	   
+	   ;;Function called to loop over each character in the code
+	   :one-off-fuck
+	   
+	   :*separators* ;Characters that terminate #F brainfuck code
+	   
+	   ;; Returns the value of the current byte, most probably the one
+	   ;; that the code finished executing over
+	   :byte-value
+	   
+	   :*tape* ;contains the entire byte tape. Useful to view contents.
+	   :*pointer* ;The current position in the byte tape. Useful with byte-value
+	   ))