...
Jump to navigation
Jump to search
... is an esolang created by randomIdiot. There are only 3 Symbols:
- .
- :
- Spaces
The code is seperated in 2-Symbol-Blocks. Here is what they mean:
| Combination | Action |
|---|---|
| .: | Increase Cell Value |
| :. | Decrease Cell Value |
| .. | Change Cell Action |
| :: | Execute Cell |
| .SPACE | Increase Pointer |
| SPACE. | Decrease Pointer |
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.
Actions
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.
Compiler
Coming soon
Examples
Cat program
A one-time cat program assumes the following form:
..::..::
Implementations
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 byte-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))))))))))