Mildfuck

Mildfuck is a brainfuck and infinite abacus inspired esolang created by Yb1 with only 6 commands. The name is derived from the first 4 commands, reading mild.
Storing data is a carbon copy of brainfuck, a tape with cells containing values from 0 to 255.
== Commands ==
 Commands
Command	Description
m 	Move pointer in pointer direction (right on start).
i 	Increase current cell if less than 255.
l 	No op, used as a skipping point for d.
d 	Invert pointer direction and if current cell is 0, skip to last l or else decrease the current cell.
g 	Get 1 ascii character input, and store it into the cell.
o 	Output current cells value as an ascii character.
== Computational class ==
I have reasonable suspicion that this is Turing-complete, because this is very similar to an infinite abacus, which is Turing-complete.
== Examples ==
===Truth Machine===
Not yet programmed, sorry. Replace this with a truth machine.
===Cat program===
The following furnishes a perpetually repeating cat program:
 lmidgomd
===Hello, World!===
 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiomiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiomiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioomiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiomiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiomiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiomiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiomiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiomiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiomiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiomiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiomiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiio
by User:Yayimhere
==Implementation==
The following implementation in Common Lisp assumes that the d instruction jumps back to the nearest preceding l token:
 (deftype octet ()
 "Defines an unsigned byte value in the range [0, 255]."
 '(unsigned-byte 8))
 
 (deftype hash-table-of (&optional (key-type T) (value-type T))
 "Defines a hash table whose keys conform to the KEY-TYPE and whose
 values adhere to the VALUE-TYPE."
 (let ((predicate (gensym)))
 (declare (type symbol predicate))
 (setf (symbol-function predicate)
 #'(lambda (candidate)
 (declare (type T candidate) (ignorable candidate))
 (and (hash-table-p candidate)
 (loop for key of-type T being the hash-keys in candidate
 using (hash-value value)
 always (and (typep key key-type)
 (typep value value-type))))))
 `(satisfies ,predicate)))
 
 (deftype list-of (&optional (element-type T))
 "Defines a list whose elements comply with the ELEMENT-TYPE."
 (let ((predicate (gensym)))
 (declare (type symbol predicate))
 (setf (symbol-function predicate)
 #'(lambda (candidate)
 (declare (type T candidate) (ignorable candidate))
 (and (listp candidate)
 (loop for element of-type T in candidate
 always (typep element element-type)))))
 `(satisfies ,predicate)))
 
 (defun build-skip-table (code)
 "Creates and returns a skip table for the piece of Mildfuck CODE."
 (declare (type string code))
 (let ((skip-table (make-hash-table :test #'eql))
 (skip-targets NIL))
 (declare (type (hash-table-of fixnum fixnum) skip-table))
 (declare (type (list-of fixnum) skip-targets))
 (loop for token of-type character across code
 and position of-type fixnum from 0 by 1
 if (char= token #\l) do
 (push position skip-targets)
 else if (char= token #\d) do
 (if skip-targets
 (setf (gethash position skip-table) (first skip-targets))
 (error "No skip target exists for the \"d\" instruction ~
 at position ~d." position))
 end)
 (the (hash-table-of fixnum fixnum) skip-table)))
 
 (defun interpret-Mildfuck (code)
 "Interprets the piece of Mildfuck CODE and returns no value."
 (declare (type string code))
 (let ((ip 0)
 (skip-table (build-skip-table code))
 (memory (make-hash-table :test #'eql))
 (cell-pointer 0)
 (pointer-direction :right))
 (declare (type fixnum ip)
 (type (hash-table-of fixnum fixnum) skip-table)
 (type (hash-table-of integer octet) memory)
 (type integer cell-pointer)
 (type (member :left :right) pointer-direction))
 (flet ((current-cell ()
 "Returns the current cell value."
 (the octet (gethash cell-pointer memory 0)))
 ((setf current-cell) (new-value)
 "Stores the NEW-VALUE in the current cell, wrapping on
 necessity in the valid byte range, and returns no value."
 (declare (type integer new-value))
 (setf (gethash cell-pointer memory 0) (mod new-value 256))
 (values)))
 (loop while (< ip (length code)) do
 (case (char code ip)
 (#\m (case pointer-direction
 (:right (incf cell-pointer))
 (:left (decf cell-pointer))
 (otherwise (error "Invalid pointer direction: ~s."
 pointer-direction))))
 (#\i (when (< (current-cell) 255)
 (incf (current-cell))))
 (#\l NIL)
 (#\d (setf pointer-direction
 (case pointer-direction
 (:right :left)
 (:left :right)
 (otherwise (error "Invalid pointer direction: ~s."
 pointer-direction))))
 (if (zerop (current-cell))
 (setf ip (gethash ip skip-table))
 (decf (current-cell))))
 (#\g (format T "~&>> ")
 (finish-output)
 (setf (current-cell) (char-code (read-char)))
 (clear-input))
 (#\o (write-char (code-char (current-cell))))
 (otherwise NIL))
 (incf ip))))
 (values))
Category:2024 Category:Cell-based Category:Unusable for programming Category:Implemented