We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.

Braisnack

From Esolang
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)))))