Kak

From Esolang
Jump to navigation Jump to search

Kak is an esolang made by User:ChuckEsoteric08 which, employing a minimalistic syntax, operates on an infinite tape of bits.

Name

The name of the language means “how” in Russian.

Architecture

A Kak program operates on a tape of infinite length, expanding in an unbounded manner in its dextral direction. The cells, comprising this linear data structure, are enumerated starting with an index of one (1). Each such entity maintains a single bit. A pointer always references the current or active cell, capable of navigating across the storage, and initially empighted in the first cell at index 1.

Syntax

Programs may contain any character; however, only command tokens are executed, while insignificant content acts as a comment.

Commands

The instruction set tallies three members:

Command Description
! Move the pointer to the right and flip the bit at the new location
? Skip the next instruction if the current cell's bit is zero (0)
< Move the pointer to the left if the pointer index is greater than one (1)

A program executes inside of a loop that ends if by the end of the program the active cell's bit is 0, like in Ultimate bf instruction minimalization!.

Computational class

I don't know, but here is translation from Ultimate bf instruction minimalization! to Kak:

UBFIM Kak
< <
( !?

Examples

Hello, world!

The following program produces in its tape the bits of the ASCII character codes defining the text “Hello, World!”. Each character code octet's bits represent from left to right the most significant bit (MSB) to the least significant (LSB). Please note that an adscititious zero-valued bit is adhibited in the desinent memory cell in order to terminate the program.

!!<!!<!!!<!!<!!<!!<!!!!<!!<!!!<!!!<!!!!<!!!!<!!<!!<!!!!<!!!!<!!<!!<!!!!<!!!!!!<!!<!!!<!!!!<!!<!!<!!<!!!<!!<!!<!!<!!<!!<!!!<!!!<!!!!!<!!!!<!!!!!!<!!!!!<!!<!!!<!!<!!!!<!!!!<!!<!!<!!!!<!!<!!!<!!<!!<!!<!!!<!!<!!<!!<!!!<!

Implementations

  • A C++ interpreter by User:Bangyen.
  • An implementation of the Kak programming language in Common Lisp shall be supplied. The interpreter returns the memory as a bit vector at the end of its execution. If a final one-valued bit requires a repetition, the restart is preceded by a printing of the tape, as a precaution in the case of a potential infinite looping.
(defun interpret-Kak (code &aux (ip 0))
  "Interprets the piece of Kak CODE and returns the memory's bits as a
   bit vector. If the program does not terminate, it prints the memory
   ere each new iteration."
  (declare (type string code) (type fixnum ip))
  (let ((memory  (make-hash-table :test #'eql))
        (pointer 1))
    (declare (type hash-table memory) (type (integer 1 *) pointer))
    (setf (gethash 1 memory) 0)
    (flet ((get-memory-bits ()
            "Returns a simple bit vector containing the MEMORY's bits."
            (map 'simple-bit-vector
              #'(lambda (index)
                  (declare (type (integer 1 *)))
                  (the bit (gethash index memory 0)))
              (sort (loop for index being the hash-keys in memory collect index) #'<))))
      (symbol-macrolet ((token       (the character (char code ip)))
                        (done-p      (the T (>= ip (length code))))
                        (active-cell (the bit (gethash pointer memory 0))))
        (loop do
          (cond
            ;; End of program and current cell is 1? => Repeat.
            ((and done-p (= active-cell 1))
              (format T "~&Memory = ~a" (get-memory-bits))
              (setf ip 0))
            ;; End of program and current cell is 0? => Terminate.
            ((and done-p (zerop active-cell))
              (loop-finish))
            ;; Not end of program? => Process CODE.
            (T  (case token
                  (#\! (incf pointer)
                       (setf active-cell (- 1 active-cell)))
                  (#\? (when (zerop active-cell)
                         (incf ip)
                         (loop until (or done-p (find token "!?<" :test #'char=)) do (incf ip))))
                  (#\< (when (> pointer 1)
                         (decf pointer)))
                  (otherwise NIL))
                (incf ip))))
        (get-memory-bits)))))
/*Tape is only 512 elements long, but that is arbitrary.*/
#define TAPELEN 512 //Change TAPELEN to whatever
#include <stdio.h>
void main()
{
    int tape[TAPELEN];
    char code[512];
    int i;
    int endbit = 1;
    int* pointer = tape;
    for(i=0;i<TAPELEN;i++) //Initialize tape
    {
        tape[i] = 0;
    }
    printf("Kak source code: "); //Prompt for code
    scanf("%s",code);
    while(endbit==1) //Run code
    {
        for(i=0;i<=sizeof(code);i++)
        {
            switch(code[i])
            {
                case '!':
                    if(pointer<tape+TAPELEN-1) //So we don't run off the end of the tape
                    {
                        pointer++;
                    }
                    *pointer = (*pointer+1)%2;
                    break;
                case '<':
                    if(pointer!=tape)
                    {
                        pointer--;
                    }
                    break;
                case '?':
                    if(*pointer==0)
                    {
                        i++;
                    }
                    break;
                default: //Unnecessary, but it's here anyways.
                    break;
            }
            if(code[i]==0)
            {
                break;
            }
        }
        endbit = *pointer; //endbit
    }
    printf("\nProgram Terminated\n");
    printf("Pointer: %d\n",pointer-tape);
    printf("Tape contents: ");
    for(i=0;i<TAPELEN;i++) //Print the tape so we can see the results of the program.
    {
        printf("%d",tape[i]);
    }
}

See also

Kak-

Kak--