Kkipple

From Esolang
Jump to navigation Jump to search

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.

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.

Syntax Description
v>s Push value v onto stack s
s<v Push value v onto stack s
s+v Push the sum (value s + value v) onto stack s
s-v Push the difference (value s - value v) onto stack s
s? If top element of stack s is 0, clear s; otherwise no-op
s* Trigger stack s if s is a special stack; otherwise no-op
(s body) Loop until s is empty

The two operators + and - behave similarly.

The two operators > and < are equivalent, save for the inversion of their arguments.

Unary operators ? and * 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 = [2], then:

  • a>b will result in a = [3] and b = [1, 2]
  • a+b will result in a = [3, 3] and b = []
  • a+a will result in a = [4]
  • a+0 is 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 'A' and 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 = [0] 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 > and <. Whether strings can be used as values for other operators is unspecified.

  • "Hi">s is equivalent to 'i'>s 'H'>s
  • s<"Hi" is equivalent to s<'H' s<'i'

In particular, "Hello">o* will output Hello, whereas o<"Hello" o* will output olleH. This is the only situation where s<v and v>s are not equivalent.

Comments

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.

Special stacks

Some identifiers are reserved for special stacks.

Identifier Description
io 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 ? operator is applied to the empty I/O stack, the ASCII value of a char from input is pushed before testing if the top element is 0.
o A synonym for io.
@ The digits stack. It has two modes: dtn and ntd. While in mode dtn, it behaves like a regular stack. While in mode ntd, v>@ will not push the value v onto stack @, but the ASCII values of the decimal digits of the number v, least significant digit on top. For instance 100>@ will result in @ = ['0', '0', '1']. Behaviour when used as the left operand for + or - is unspecified. At the beginning of execution it is in mode ntd.
& The execute stack. Behaves like a regular stack.
0 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.
C 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: s>C will push a copy of s's top element onto the copy stack, without popping s. Since the copy stack cannot be popped, only the top element can ever be accessed. Initially its top element is the number 0. Trying to clear the copy stack has no effect, but might raise a warning depending on the implementation.

Triggering special stacks

The operator * can be used to trigger special stacks. The effect depends on the stack triggered:

Stack Effect
io Output the content of the I/O stack, top-to-bottom, clearing it in the process. For instance 100>@ (@>o) o* will output 100, and 'i'>o<'H' o* will output Hi. Results in an error if one of the values inside the I/O stack is not a valid ASCII code.
@ Consider the content of the digits stack as a string, convert it into a number, then switch modes. For instance 100>@* results in @ = [100]. If it is empty, no-op; if it is not empty but its content cannot be interpreted as a number, results in an error.
& 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.
0 No-op.
C No-op.

Example programs

Hello, World!

"Hello, World!">o*

Cat program

io? (o* io?)

Truth-machine

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*

Fibonacci sequence

a<0 b<1
(b ' '>o b>C>@ (@>o) o* c+a c+C a<b<c)

Computational class

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.

brainfuck Kkipple
> prev<next
< prev>next
+ next+1
- next-1
. next>C>o*
, 0<next<io
[ body of loop ]
next>C>loop?
(loop>0
  body of loop
  next>C>loop?
)

This proves that Kkipple is Turing-complete, even if restricted to bounded integers.

See also

  • Kipple, the language from which Kkipple is inspired.

External resources