Dip

From Esolang
Jump to navigation Jump to search

Dip is a stack-based Turing tarpit created by User:D.

Commands

Command Behavior
0 Push 0.
' Increment TOS.
; Pop TOS. Append it to the bottom of the stack.
( _b_ ) While loop. (See below)

While loop

  • While (pop stack as N) != 0:
  • push N-1
  • run _b_ as dip code

Examples

Predecessor

A plain (0) would pop the stack with a 0 input.

So we'll need to sneak a 0 value under the stack:

0;(;)

Add

This just does a bounded for loop, which increments the 2OS.

(;';)

Multiply

0; 0; (;(;';';;);0;;) ()()

Computational class

Dip is Turing-complete. One way to demonstrate this is to compile The Waterfall Model to it.

We'll compile the following program to Dip:

[[10, 3, 3, 3],
 [ 1, 3, 0, 6],
 [ 2, 0, 6, 3],
 [ 3, 6, 3, 0]]

The waterclocks are named A, B, and C, respectively.

First, initialize the waterclocks:

0''' 0'' 0'

This pushes C B A onto the stack.

Next, we use the following structure to simuate the outer infinite loop:

0' (() ... 0')

... is where we put the individual implementations of the waterclocks.

Compiling individual waterclocks

We use a ( ... ) loop to simulate an individual waterclock. Here, we simulate the second row of the program.

(; 0' 0 ;; [;]

Walkthrough:

(;

This shifts A-1 to the bottom of the stack. (Configuration: A C B)

0' 0

Push the value of the flag (initially 1) and the preserved A counter, respectively. (Configuration: A C B _flg_ _A'_)

;;

Move the flag and the preserved A counter to the bottom.

[;]

Use #_of_counters - 1 ;s to make A float to the top of the stack. (In this case, two ;s.)

For the rest of this implementation, [;] means #_of_counters - 1 ;s.

Inner loop 1: The flag & A' loop

Then, we use a repeat loop to 1) set flag to 0 and increment our preserved A counter, respectively:

(; ()0; '; [;])

Here's a walkthrough of what each part does:

(;

Decrement the value of A, and move it to the bottom of the stack.

()0;

() discards one value on the stack (i.e. decrements it until it's 0, after which the value is popped). Then we push 0, which sets our flag to 0. Last, we shift the value to the bottom of the stack.

';

Increments A', and shift it down.

[;] )

#_of_counters - 1 ;s, to shift A to the top of the stack again.

Inner loop 2: The actual incrementing

This part is a bit trivial. We were left with the configuration

C B A' _flg_

at the end of our previous loop, so we just need to repeat the incrementing process _flg_ times to simulate the full functionality of the zeroing trigger.

Since we're compiling the first waterclock, here's an implementation:

(;''';;'''''';)

Self-evident, so I won't explain it.

End of outer loop

We need to ensure that our outer loop is exitted after the conditional is done, so we do this:

0)

To switch to the next waterclock (after which you can chain another waterclock implementation), use ;.

External Resources