Iterate

From Esolang
Jump to navigation Jump to search
Not to be confused with ITERATE.

Iterate is a Turing complete programming langugage invented by User:Aadenboy which only uses iterative loops.

Syntax

Loops

Loops are initialized with an asterisk (optionally with a number preceding it surrounded by parentheses), followed by the amount of times it loops, then the loop itself. There are only loops. Outside of a loop, its index is zero.

Code Definition
*#< ... > Loop # times. If it is zero or nothing, don't run. The visit count will still accumulate regardless of whether or not it had looped.
*∞< ... > Loop forever.
(#*)...< ... > A labeled loop for future reference. # must be a number. Different loops can share a single label if they are within separate scopes.
(*)...< ... > The main loop. This must enclose the entire program.

Loop amounts

You are able to provide different loop amounts via referencing other loops, or by a constant. A loop many only use one amount.

Code Definition
Number That many times.
Infinity.
? Receives a number from the user as the loop amount.
n The current index of the parent loop. This equals zero for the main loop's parent.
n# The current index of label #. This equals zero if the label doesn't exist.
n^ The current index of the main loop.
~n How many loops are left until the parent loop's final loop. This equals zero for the main loop's parent.
~n# The above command, but with a label. This equals zero if the label doesn't exist.
~n^ The above command, but with the main loop.
=# How many times a label was visited. Note that this isn't the same as how many times it had looped. Multiple loops can contribute to a single label's visit count. This equals zero if the label doesn't exist.
=^ The above command, but with the main loop. Usually equal to one unless you explicitly reset it.

Commands

These are placed in a loop.

Code Definition
! Immediately break out of the parent loop. Analogous to break.
!# Immediately break out of label # IF you are inside it. This is a no-op if otherwise.
!^ Stop execution.
& Skip to the end of the parent loop. Analogous to continue.
&# Skip to the end of label # IF you are inside it. This is a no-op if otherwise.
&^ Skip to the end of the main loop.
@ Output the current index of the parent loop as a number.
~@ Output the current index of the parent loop as a character.
$# Reset the visit count of label #.
$^ Reset the visit count of the main loop.

Completeness

Iterate is Turing complete. See Iterate/Turing-completeness proof.

Unsolved question: Is Iterate Turing complete without the $# command?

Basic arithmetic

A+B

(*)1<
  *?< (1*)<> > // increment L1
  *?< (1*)<> > // increment L1 again
  (2*)=1<      // output character
    *~n< &2 >  // skip to prevent early prints
    @
    !^         // end early to avoid printing 0 case
  >
  (3*)48<      // print 0 as its ASCII code (48)
    *~n< &3 >  // skip to prevent early prints
    ~@
  >
>

A-B

Note: Results lower than one will not output anything.

(*)1<
  *?< (1*)<> > // L1 = A
  *?<          // decrement L1 by one B times
    $2
    *=1<            // store L1-1 in L2
      *~n< (2*)<> > // ~n acts as L1-1
      !
    >
    $1
    *=2< (1*)<> >   // copy from L2 to L1
  >
  (3*)=1<      // output character
    *~n< &3 >  // skip to prevent early prints
    @
    !^         // end early to avoid printing 0 case
  >
  (4*)48<      // print 0 as its ASCII code (48)
    *~n< &4 >  // skip to prevent early prints
    ~@
  >
>

A*B

(*)1<
  *?< (1*)<> > // store A to L1
  *?< (2*)<> > // store B to L2
  *=1<
    *=2<
      (3*)<>   // visited A*B times as an intrinsic property of nested loops
    >
  >
  (4*)=3<      // output character
    *~n< &4 >  // skip to prevent early prints
    @
    !^         // end early to avoid printing 0 case
  >
  (5*)48<      // print 0 as its ASCII code (48)
    *~n< &5 >  // skip to prevent early prints
    ~@
  >
>

A%B

(*)1<
  *?< (1*)<> >        // L1 = A
  *?< (2*)<> (4*)<> > // L2 = B, L4 = B
  (6*)=1<             // increment L3 to equal L1
    (3*)<>            // L3 = L3 + 1
    $5
    *=4< (5*)<> >     // L5 = L4
    $4
    *=5<           
      *~n< (4*)<> >   // L4 = L5 - 1
      !
    >
    *=4< &6 >         // if L4 == 0 (or when modulus returns 0)...
    $3                // L3 = 0
    *=2< (4*)<> >     // L4 = L2 (reset count)
  >
  (7*)=3<             // print result
    *~n< &7 >         // skip to prevent early prints
    @
    !^                // end early to avoid printing 0 case
  >
  (8*)48<             // print 0 as its ASCII code (48)
    *~n< &8 >         // skip to prevent early prints
    ~@
  >
>

A/B

The same algorithm can be used to calculate floored division.

(*)1<
  *?< (1*)<> >
  *?< (2*)<> (4*)<> >
  (6*)=1<         // a%b algorithm
    (3*)<>
    $5
    *=4< (5*)<> >
    $4
    *=5<           
      *~n< (4*)<> >
      !
    >
    *=4< &6 >
    $3
    *=2< (4*)<> >
    (7*)<>        // count how many times L3 resets for the quotient
  >
  (10*)1<
    (8*)=7<       // print quotient
      *~n< &8 >
      @
      !10
    >
    (9*)48<
      *~n< &9 >
      ~@
    >
  >
  (11*)82<        // "R"
    *~n< &11 >
    ~@
  >
  (12*)=3<        // print remainder
    *~n< &12 >
    @
    !^
  >
  (13*)48<
    *~n< &13 >
    ~@
  >
>

Conditionals

While this code checks if A == B, you can trivially modify it to check for A < B, A > B, and any combination or negation of those cases.

(*)1<
  *?< (1*)<> > // L1 = A
  *?< (2*)<> > // L2 = B
               // L7 will hold if A == B: 1 = true, 0 = false
               // we'll continuously decrement A and B until either reaches 0
               // if either reaches 0 first before the other, they're not equal
               // otherwise they are equal
  (5*)∞<
    (6*)1<        // we check FIRST for the edge case where either A or B starts as 0
      *=1<
        *=2< !6 > // case 1: neither A nor B are 0 -> continue
        !5        // case 2: B reached 0 first     -> A > B
      >
      *=2<
        *=1< !6 > // case 1: neither A nor B are 0 -> continue
        !5        // case 3: A reached 0 first     -> A < B
      >
      (7*)<>      // case 4: both reached 0 at the same time -> A == B
      !5
    >
    $3
    $4
    *=1< (3*)<> >        // L3 = L1
    *=2< (4*)<> >        // L4 = L2
    $1
    $2
    *=3< *~n< (1*)<> > ! > // L1 = L3 - 1
    *=4< *~n< (2*)<> > ! > // L2 = L4 - 1
  >
  *=7< @ !^ > // print 1 if true
  (8*)48<     // print 0 if false
    *~n< &8 >
    ~@
  >
>

Arbitrary memory

Arbitrary memory can be implemented with a single label using arbitrary memory emulation.

Example programs

Truth-machine

(*)1<
  *?<         // if input were to be 0, this wouldn't run
    *∞<       // loop forever
      *1< @ > // loop for index of 1 printed
    >
  >
  (1*)48<     // printing 0 as its ASCII code (48)
    *~n< &1 > // skip to prevent early prints
    ~@
  >
>

Looping counter

(*)∞<
  *n<
    (1*)42<
      *~n< &1 >
      ~@
    >
  >
  (1*)10<
    *~n< &1 >
    ~@
  >
>

Triangular numbers

(*)∞<
  *n<
    *~n<
      (1*)<>
    >
    !
  >
  (4*)1<
    (2*)=1<
      *~n< &2 >
      @
      !4
    >
    (3*)48<
      *~n< &3 >
      ~@
    >
  >
  (5*)10<
    *~n< &5 >
    ~@
  >
>

Interpreter