User:BoundedBeans/INTERCAL without labels

From Esolang
Jump to navigation Jump to search

C-INTERCAL and CLC-INTERCAL both have ways of making programs without any line labels, but the methods are very different for each.

CLC-INTERCAL (requires come from gerund extension)

Start the program with:

DO ABSTAIN FROM COMING FROM
DO SWAP STASH REGISTER AND RETRIEVE REGISTER
DO COME FROM SWAPPING
DO ABSTAIN FROM COMING FROM
DO SWAP STASH REGISTER AND RETRIEVE REGISTER

End the program with:

DO SWAP STASH REGISTER AND RETRIEVE REGISTER
DO GIVE UP

SWAP is reserved as a dummy statement that can be completely emulated with CREATE and DESTROY. However, if COMING FROM is reinstated in the program, it will go to the come from instead of the give up. The SWAP will still change the statements, so immediately after the COME FROM, we disable it and then SWAP again to bring it back to normal. This also requires one more ABSTAIN and SWAP at the start of the program to make it start normal on the first round also. The program now will run as long as a REINSTATE COMING FROM succeeds.

We have one big loop, which along with conditionals is enough for arbitrary nesting of loops and conditionals by splitting the code by the boundaries, and skipping everything that shouldn't run. Conditionals can be made as follows:

DO %(expression) ABSTAIN FROM (gerunds)
(block)
DO REINSTATE (gerunds)

The expression should evaluate to #0 if true, or #100 if false. This can be done by forming a single bit into 8 copies by interleaving with itself and selecting with #255 5 times, then selecting with the result on the right and #100 on the left. That bit should be NOT (the condition).

Now you have an if-block. See the common section for details on if-else and nested ifs.

Note that ABSTAINING from REINSTATING will break this entire system, so a REINSTATE (including the one to continue the loop), should have its own percentage expression.

C-INTERCAL

C-INTERCAL is much simpler. Put TRY AGAIN at the end of your program, and ABSTAIN (expression) FROM TRYING AGAIN to end the loop conditionally.

An if block is:

DO ABSTAIN (expression) FROM (gerunds)
(inside)
DO REINSTATE (gerunds)

The expression should be either 1 or 0, as NOT (the condition).

Common

If-else can be emulated with two if blocks, one with the condition, the other with NOT the condition.

Nested if can be emulated with three if blocks, the first as (condition 1), the second as (condition 1 AND condition 2), the third as (condition 1). These correspond to the area inside the outer if before the inner if, the inner if, and the area inside the outer if after the inner if, respectively.

For both if-else and nested ifs, you have to make sure the condition doesn't change while inside. If you really need to change the value, store it in a separate variable and check that in all of the blocks.

More levels of nested ifs and/or multiple nested ifs are more complicated, but they just require splitting the code by the boundaries of each if statement and making the conditions with another AND and condition for each level.

For example:

if (a) {
  v;
  if (b) {
    w;
  }
  x;
  if (c) {
    y;
    if (d) {
      z;
    }
  }
}

is equivalent to

if (a) v;
if (a and b) w;
if (a) x;
if (a and c) y;
if (a and c and d) z;

Nested loops are a bit more complicated, but essentially you have to split the code by the boundaries if loops and conditionals and make the conditions so that the ones that shouldn't run should be skipped. A nested loop should skip everything outside of it while it runs, mapping iterations of itself to iterations of the outermost loop. You also need to store the some position data in a variable to check in order to completely know what to skip. If a single conditional is inside a nested loop, each of the 3 sections should run on separate iterations of the outermost loop.