Countable/brainfuck interpreter

From Esolang
Jump to navigation Jump to search

Back to Countable

brainfuck interpreter in Countable.

0+15 // builder
1+15 // program end location
2+5 // tape length sub one (adjust as needed)
3+0  // program position pointer
4+0  // new program position pointer
5+0  // tape position pointer
6+0  // new tape position pointer
7+0  // decrement flag pointer
8+13 // loop validator pointer (left end)
9+14 // loop validator pointer (right end)
10+0 // new cell value
11+0 // tape pointer
12+0 // tape replicator

// + 43
// - 45
// > 62
// < 60
// . 46
// , 44
// [ 91
// ] 93

a8+1  // initialize both with 1 to prevent edge case
a9+1

∞*1< // escape hatch
  0*1< // read program
    58*1< // use colon for input
      *∞<
        a0@  // get character
        256*1< // switch case
          91*1< 93*1<
            aa0& // go to case (or exit if null)
            256& // skip if none matched
          > // case 93 ']'
            0*1< // exit
              aa8*1<
                256*1< 91*1< // safe guarding
                  aa9& // check if left end == right end
                > >
                a9+1  // right end is lower than left end; loops are balanced thus far
                0&    // skip failure case
              >
              a9+1 // right end is equal to left end; loops are unbalanced
              ∞&   // force exit
            >
            256& // skip next case
          > // case 91 '['
            a8+1  // increase left end
            256& // skip next case
        >
        0+1  // next character
        1+1  // increase length
      >
    >
  >
>
0+1 // final padding

∞*1<
  aa8*1< // check loop balance
    aa9&
    ∞& // unbalanced; program is invalid
  >
  
  // initialization
  3+a0 a3+15 0+1
  4+a0 0+1
  5+a0 0+1
  6+a0 0+1
  7+a0 0+1
  a0*1< *∞<
    a8&
    8+1
  > > 0+1
  a0*1< *∞<
    a9&
    9+1
  > > 0+1
  10+a0 0+1
  11+a0 12+a0
  0+a2 0+1
  
  0*∞<
    11+aa5 // move pointer to cell
    ∞*1<
      43*1< 45*1< 62*1< 60*1< 46*1< 44*1< 91*1< 93*1< // commands
        aaa3& // switch case
        ∞&  // skip
      > // case 93 ']'
        a6+aa5
        a10+aa11
        *aa11< // check if > 0
          4+10 4+a2 // initialize
          7+6 7+a2  // initialize
          a0+aa3 // initialize
          a8+1 a9+1 // prevent edge case
          ∞*1<
            *∞< // seek to start of loop
              1*aa0< // decrement
                *aa7<
                  a4+1
                  1&
                >
                a7+1
              >
              256*1< // switch case
                93*1< 91*1<
                  43*1< 45*1< 62*1< 60*1< 46*1< 44*1< // safety
                    aaa4& // go to case
                  > > > > > >
                  256& // skip if none matched
                > // case 91 '['
                  0*1< // exit
                    aa8*1<
                      256*1< 93*1< // safe guarding
                        aa9& // check if left end == right end
                      > >
                      a9+1  // right end is lower than left end; haven't met end of loop
                      0&    // skip failure case
                    >
                    a9+1 // right end is equal to left end; met end of loop
                    ∞&   // force exit
                  >
                  256& // skip next case
                > // case 93 ']'
                  a8+1  // increase left end
                  256& // skip next case
              >
              0+2 4+2 7+2 // go to next iteration
            >
          >
          0+3 // skip to empty space
          ∞& // break
        >
        a4+aa3 a4+1 // next command otherwise
        ∞& // break
      > // case 91 '['
        a4+aa3
        a6+aa5
        a10+aa11
        *aa11< // check if > 0
          a4+1 // next command
          ∞&   // break
        >
        ∞*1< // seek to end of loop
          a8+1 a9+1 // prevent edge case
          *∞<
            a4+1
            256*1< // switch case
              91*1< 93*1<
                43*1< 45*1< 64*1< 60*1< 46*1< 44*1< // safety
                  aaa4& // go to case
                > > > > > >
                256& // skip if none matched
              > // case 93 ']'
                0*1< // exit
                  aa8*1<
                    256*1< 91*1< // safe guarding
                      aa9& // check if left end == right end
                    > >
                    a9+1  // right end is lower than left end; haven't met end of loop
                    0&    // skip failure case
                  >
                  a9+1 // right end is equal to left end; met end of loop
                  ∞&   // force exit
                >
                256& // skip next case
              > // case 91 '['
                a8+1  // increase left end
                256& // skip next case
            >
          >
        >
        ∞& // break
      > // case 44 ','
        a4+aa3 a4+1
        a6+aa5
        a10@ // get input
        ∞&   // break
      > // case 46 '.'
        a4+aa3 a4+1
        a6+aa5
        a10+aa11
        %aa11 // print
        ∞&    // break
      > // case 60 '<'
        a4+aa3 a4+1
        a10+aa11
        *aa4< // check if > 0
          1*aa4< // decrement
            *aa7<
              a5+1
              1&
            >
            a7+1
          >
          ∞& // break
        >
        a5+a2 // wraparound otherwise
        ∞& // break
      > // case 62 '>'
        a4+aa3 a4+1
        a10+aa11
        a2*1< // check if at end of tape
          0*1< 45*1< 43*1< // safeguarding
            aa5&
          > > >
          a6+aa5 a6+1 // not at end; no wraparound
        >
        
        ∞& // break
      > // case 45 '-'
        a4+aa3 a4+1
        a6+aa5
        *aa11< // check if > 0
          1*aa11< // decrement
            *aa7<
              a10+1
              1&
            >
            a7+1
          >
          ∞& // break
        >
        a10+255 // wraparound otherwise
        ∞& // break
      > // case 43 '+'
        a4+aa3 a4+1
        a6+aa5
        255*1< // check if == 255
          0*1< // safeguarding
            aa11&
          >
          a10+aa11 a10+1 // not 255; no wraparound
        >
    >

    a0+aa4 // set new program position
    a0*1< *∞<
      a3&
      3+1
    > > 0+1
    a0*1< *∞<
      a4&
      4+1
    > > 0+1
    a0+aa6 // set new tape position
    a0*1< *∞<
      a5&
      5+1
    > > 0+1
    a0*1< *∞<
      a6&
      6+1
    > > 0+1
    a0*1< *∞<
      a7&
      7+1
    > > 0+1
    a0*1< *∞<
      a8&
      8+1
    > > 0+1
    a0*1< *∞<
      a9&
      9+1
    > > 0+2
    *a2< // copy tape
      0*1<
        a11*1< // check if current cell is selected for copying behavior
          a12&
          a0+aa12
          0&
        >
        a0+aa10
      >
      12+1
      0+1
    >
    0*1<
      a11*1< // check if current cell is selected for copying behavior
        a12&
        a0+aa12
        0&
      >
      a0+aa10
    >
    12+1
    0+1
    a9*1< *∞<
      a10&
      10+1
    > > 10+1
    a10*1< *∞<
      a11&
      11+1
    > > 11+1
    a11*1< *∞<
      a12&
      12+1
    > >

    a1*1< // check if at end of program
      aa3&
      0& // continue if not
    >
    ∞& // done
  >
>