Kkipple is a close derivative of the stack-based language Kipple. The idea of making a derivative came when User:Koen tried to write an interpreter, then realized it was as far from the specifications as was possible to be. The name is pronounced like stuttering the word "Kipple".
A program in Kkipple is a succession of stack identifiers, numbers, and operators.
Kkipple has six operators to handle stacks, plus two to control the execution flow. Operators take one or two arguments, which can be either stack identifiers or values. Operators are infix, so the right argument of an operator may double as the left argument of the next operator.
||Push value v onto stack s|
||Push value v onto stack s|
||Push the sum (value s + value v) onto stack s|
||Push the difference (value s - value v) onto stack s|
||If top element of stack s is 0, clear s; otherwise no-op|
||Trigger stack s if s is a special stack; otherwise no-op|
||Loop until s is empty|
The two operators
- behave similarly.
The two operators
< are equivalent, save for the inversion of their arguments.
* are applied to all stack identifiers that immediately precede or follow them without being separated by whitespace:
s* t will trigger s only,
s *t will trigger t only, and
s*t will trigger s first, then t.
Values and stack identifiers
A value is either a positive integer number or a stack identifier. In case of a stack identifier, the top value is popped and used as the value. For instance, if a = [1, 3] and b = , then:
a>bwill result in a =  and b = [1, 2]
a+bwill result in a = [3, 3] and b = 
a+awill result in a = 
a+0is a no-op if a is not empty, and otherwise pushes one 0 onto a.
Stack identifiers can be any string containing the characters a-zA-Z@&_ exclusively. Numbers are written in decimal. The string "0" is an exception, as it is both the number 0 and the identifier for the null stack. A number can also be expressed as a single char between single quotes, which is equivalent to the ASCII value of that char: for instance
65 are synonyms.
Whitespace in a program are usually ignored, but are forbidden inside of stack identifiers and numbers; they can thus act as separators.
If a stack is empty, then for all matters its top value is considered to be 0. It is to be noted, however, that the stacks a =  and b =  are not equivalent: for instance
(a) is an infinite loop but
(b) is a no-op.
Double quoted strings
Similar to the "string preprocessor" in the original Kipple interpreter, double quotes can be used in Kkipple to express strings. Strings are meant to be used with operators
<. Whether strings can be used as values for other operators is unspecified.
"Hi">sis equivalent to
s<"Hi"is equivalent to
"Hello">o* will output Hello, whereas
o<"Hello" o* will output olleH. This is the only situation where
v>s are not equivalent.
Any value not next an operator is a no-op; however, some implementations might be slowed down from evaluating them. The proper way to write comments is using the symbol
#: everything to the right of a
# is ignored until the next newline.
Some identifiers are reserved for special stacks.
||The input/output stack. If it is empty, then popping it will return the ASCII value of a char taken from standard input, or the number 0 on end of file. If the |
||A synonym for |
||The digits stack. It has two modes: dtn and ntd. While in mode dtn, it behaves like a regular stack. While in mode ntd, |
||The execute stack. Behaves like a regular stack.|
||The null stack. It is always empty; any value pushed to it is instead destroyed. Since it is always empty, popping the null stack or peeking at its top value always return the number 0; thus the number 0 and the null stack are equivalent when used as values.|
||The copy stack. It is never empty; when it is used as a value, it returns its top element without popping it. When a value is pushed onto it from a stack, the stack is not popped: |
Triggering special stacks
* can be used to trigger special stacks. The effect depends on the stack triggered:
||Output the content of the I/O stack, top-to-bottom, clearing it in the process. For instance |
||Consider the content of the digits stack as a string, convert it into a number, then switch modes. For instance |
||Consider the content of the execute stack as a Kkipple program, and execute it. Results in an error if it is not a valid program, or if it attempts to modify the content of the execute stack. The stack is cleared after having been executed.|
io? (o* io?)
This program is very similar to its Kipple equivalent, but it actually works since Kkipple adds interactive I/O.
io>a-'0' a? (a '1'>o*) '0'>o*
a<0 b<1 (b ' '>o b>C>@ (@>o) o* c+a c+C a<b<c)
Kkipple is Turing-complete; any brainfuck program can be translated into an equivalent Kkipple program as follows, using two stacks prev and next to emulate a left- and right-unbounded tape.
next>C>loop? (loop>0 body of loop next>C>loop? )
This proves that Kkipple is Turing-complete, even if restricted to bounded integers.
- Kipple, the language from which Kkipple is inspired.