Braisnack
Jump to navigation
Jump to search
Braisnack uses the SNACBIT. Every cell starts as peanut butter cracker.
Commands
| Command | Description |
|---|---|
>
|
Move the pointer to the next cell |
<
|
Move the pointer to the previous |
+
|
Increment the snack in the cell at the pointer, wrapping around at the edges |
-
|
Decrement the snack in the cell at the pointer, wrapping around at the edges |
[
|
Go to the corresponding ] if the snack in the cell at pointer is peanut butter cracker
|
]
|
Go to the corresponding [ if the snack in the cell at pointer is not peanut butter cracker
|
.
|
Print out the name of the snack in the cell at the pointer |
,
|
Save the input snack in the cell at the pointer |
Examples
Cat
,.
picklepickledoritotortilla chipapplesauce
-..+++++.+.+++.
Iterative snack printing
This program prints all SNACBIT states in their natural order by mediation of the jump facility:
.+[.+]
Interpreter
An interpreter implementation in Common Lisp follows:
(declaim (type (simple-array simple-string (11)) +SNACBIT-STATES+))
(defparameter +SNACBIT-STATES+
(make-array 11
:element-type 'string
:initial-contents
'("Peanut butter cracker"
"Cosmic brownie"
"Cheezit"
"Cheeto"
"Dorito"
"Tortilla chip"
"Cheese cracker"
"Potato chip"
"Applesauce"
"Peanut butter cup"
"Pickle")))
(defun normalize-state-number (state-number)
(declare (type integer state-number))
(the (integer 1 11) (+ 1 (mod (- state-number 1) 11))))
(defun find-snack-number (input)
(declare (type string input))
(the (or null (integer 0 10))
(position-if
#'(lambda (probed-snack)
(declare (type string probed-snack))
(string-equal (remove #\Space input) (remove #\Space probed-snack)))
+SNACBIT-STATES+)))
(defun query-snack ()
(the (or null (integer 0 10))
(prog ((input NIL)
(selected-snack NIL))
(declare (type (or null string) input))
(declare (type (or null (integer 0 10)) selected-snack))
query-for-input
(format T "~&>> ")
(setf input (read-line NIL NIL ""))
(clear-input)
(if (plusp (length input))
(go check-input)
(go end))
check-input
(setf selected-snack (find-snack-number input))
(if selected-snack
(go end)
(go query-for-input))
end
(return selected-snack))))
(defun compute-jump-table (code)
(declare (type string code))
(the hash-table
(loop
with jump-table of-type hash-table = (make-hash-table :test #'eql)
with start-points of-type list = NIL
for token of-type character across code
and position of-type fixnum from 0 by 1
do (case token
(#\[ (push position start-points))
(#\] (if start-points
(let ((start-position (pop start-points)))
(declare (type fixnum start-position))
(setf (gethash start-position jump-table) position)
(setf (gethash position jump-table) start-position))
(error "Unmatched \"]\" at position ~d." position)))
(otherwise NIL))
finally
(if start-points
(error "Unmatched \"[\"s at positions ~{~d~^, ~}." start-points)
(return jump-table)))))
(defun interpret-Braisnack (code)
(declare (type string code))
(let ((jump-table (compute-jump-table code))
(memory (make-hash-table :test #'eql))
(cell-pointer 0))
(declare (type hash-table jump-table memory))
(declare (type integer cell-pointer))
(symbol-macrolet ((current-snack (the (integer 1 11) (gethash cell-pointer memory 1))))
(loop with ip of-type fixnum = 0 while (< ip (length code)) do
(case (char code ip)
(#\> (incf cell-pointer))
(#\< (decf cell-pointer))
(#\- (setf current-snack (normalize-state-number (1- current-snack))))
(#\+ (setf current-snack (normalize-state-number (1+ current-snack))))
(#\[ (when (= current-snack 1)
(setf ip (gethash ip jump-table))))
(#\] (unless (= current-snack 1)
(setf ip (gethash ip jump-table))))
(#\. (format T "~&~a" (aref +SNACBIT-STATES+ (1- current-snack))))
(#\, (let ((new-snack-index (query-snack)))
(declare (type (or null (integer 0 10)) new-snack-index))
(when new-snack-index
(setf current-snack (1+ new-snack-index)))))
(otherwise NIL))
(incf ip)))))