... is an esolang created by randomIdiot. There are only 3 Symbols:
The code is seperated in 2-Symbol-Blocks. Here is what they mean:
|.:||Increase Cell Value|
|:.||Decrease Cell Value|
|..||Change Cell Action|
The Cell-System is like in Brainfuck. You have cells which you can go to (de-/increase pointer) and store values. But in ... you can also store actions. Every cell is an executable program.
There are 2 Actions: Input and output. They work like in Brainfuck. Input saves the input as a number in the current cell. Output prints the current cell value. Standard action saved in a cell is output.
A one-time cat program assumes the following form:
An implementation in Common Lisp shall be presented:
(deftype octet () "Defines an unsigned byte composed of eight bits." '(unsigned-byte 8)) (deftype action () "Enumerates the valid cell actions." '(member :input :output)) (deftype cell () "Defines a cell's (cellValue, cellAction) componency in terms of an octet value and an action keyword." '(cons octet action)) (defun memory-p (candidate) "Determines whether the CANDIDATE is a hash table that maps integer keys to cell values, the former acting a cell indices, the latter as associated (cellValue, cellAction) compounds." (declare (type T candidate)) (and (hash-table-p candidate) (loop for key of-type T being the hash-keys in candidate using (hash-value value) always (and (integerp key) (typep value 'cell))))) (deftype memory () "Defines the program memory as a hash table that maps integer cell indices to integer-action (cellValue, cellAction) tuples." '(satisfies memory-p)) (defun interpret-|...| (code) "Interprets the piece of ... source CODE and returns NIL." (declare (type string code)) (let ((memory (make-hash-table :test #'eql)) (cell-pointer 0)) (declare (type memory memory) (type integer cell-pointer)) (labels ((code-section-equals-p (start expected-string) (declare (type fixnum start) (type string expected-string)) (the boolean (not (null (string= code expected-string :start1 start :end1 (min (+ start 2) (length code))))))) (current-cell () (multiple-value-bind (cell contains-cell-p) (gethash cell-pointer memory) (declare (type (or null cell) cell) (type T contains-cell-p)) (the cell (cond (contains-cell-p cell) (T (setf (gethash cell-pointer memory) (cons 0 :output)) (gethash cell-pointer memory)))))) (current-cell-value () (the octet (car (current-cell)))) ((setf current-cell-value) (new-value) (declare (type integer new-value)) (setf (car (current-cell)) (mod new-value 256)) (values)) (current-cell-action () (the action (cdr (current-cell)))) ((setf current-cell-action) (new-action) (declare (type action new-action)) (setf (cdr (current-cell)) new-action) (values)) (change-action () (setf (current-cell-action) (case (current-cell-action) (:output :input) (:input :output) (otherwise (error "Invalid current action: ~s." (current-cell))))) (values))) (loop for ip of-type fixnum from 0 below (length code) by 2 do (cond ((code-section-equals-p ip ".:") (incf (current-cell-value))) ((code-section-equals-p ip ":.") (decf (current-cell-value))) ((code-section-equals-p ip "..") (change-action)) ((code-section-equals-p ip "::") (case (current-cell-action) (:output (format T "~c" (code-char (current-cell-value)))) (:input (format T "~&>> ") (force-output) (setf (current-cell-value) (char-code (read-char))) (clear-input)) (otherwise (error "Invalid action: ~s." (current-cell-action))))) ((code-section-equals-p ip ". ") (incf cell-pointer)) ((code-section-equals-p ip " .") (decf cell-pointer)) (T (error "Invalid command token: ~s." (subseq code ip (min (+ ip 2) (length code))))))))))