TritBitJump

From Esolang
Jump to navigation Jump to search

TritBitJump is a language which is based on BitBitJump but is also nontrivially different from that and from other WordWordJump languages. It circumvents the fixed address size problem in an unorthodox way which involves analyzing the bits in the machine as though they were trits, and is therefore more likely to be Turing complete.

Basics

The basics are actually much more similar to BitBitJump than the name might imply.

Like BitBitJump, the abstract machine operates on an infinite array of memory which consists of bits (not trits). Each bit has its own address, and addresses start from 0 like in BitBitJump.

However, unlike BitBitJump, bits are grouped into addresses in a very specific way. Instead of each bit being a number in a word, groups of two bits are used to determine both the word and the space between words. This is where the "trit" in TritBitJump comes in.

TritBitJump is also little-endian because because that makes it easier to jump to an arbitrary point if you don't actually know how long the number is. The combination 00 is 0, 10 is 1, 01 is 2, and 11 indicates the space between addresses.

Three consecutive addresses in memory (A, B, C) constitute an instruction - copy the bit at address A to the bit at address B, then jump to the bit at address C and figure out the next instructions starting at that bit. If both the bit at C and the next bit are 1, then those bits are ignored. The machine looks at the two bits after those until it finds a pair of bits which aren't both 1, and that is the next address.

For example, see the following program:

1011011100110111001111101101011

The first instruction is analyzed as:

10 (11) 01 (11) 00 (11) ...

which is, in base 3:

1 2 0

Once the first instruction is done, it puts the bit at location 2 into location 1, resulting in:

1001011100110111001111101101011 / 100101 (11) 00 (11) 01 (11)...

This instruction is, in base 3 (little-endian) / base 10 (normal i.e. big-endian):

122 0 2 / 2 25 5

Bit 25 was 1 and now it's 0, so now it's:

1001011100110111001111101001011

and the next instructions are:

...(11) 100110 (11) 1001 (11) (11) (11) 010010 (11) | 121 12 201 | 16 7 11
1001011000110111001111101001011
10 (11) 1001 (11) (11) 010010 (11) | 1 12 201 | 1 7 11
1001011000110111001111101001011 (no change)
10 (11) 1001 (11) (11) 010010 (11) | 1 12 201 | 1 7 11

You may have noticed that 1 7 11 already showed up and it didn't change anything. Therefore, the code is now in an infinite loop. Overall, this code wasn't meant to do anything, but it did show how TritBitJump works and it set up a method for conveying TritBitJump commands.

Assembly

BitBitJump has a lot of good features and it has explanations which make the language less arcane, but the problem is that a lot of these decisions can't easily be extended to TritBitJump, or if they are extended there, they will make the language less powerful. For example, numbers in TritBitJump can have trailing zeroes on either end or be separated by multiple instances of 11. This makes ? much harder to implement or imagine. Additionally, TritBitJump has no way of indicating negative numbers, so it can't take input or halt like that either.

Therefore, I will write everything from here on out in the following way:

  • Numbers will be written in base 3, little-endian, then a single slash, then base 10, big endian.
  • A single instance of 11 will correspond to a space between numbers
  • If there is more than one 11 between numbers, it will be represented like "(# of 11s in base 10)" surrounded by spaces, so 00111100 will be "0 (2) 0".
  • Comments will be indicated by //.

So what was previously:

10110111001101110011111011100111001100

would be represented like:

1 2 0 / 1 2 0
2 0 (2) 1 / 2 0 (2) 1
12 0 0 / 7 0 0 // this is a comment

Additionally, in simple programs, there won't be any complicated argument shifting... sort of.

Printing Characters / Hello World!

For this exercise, "output" will occur at position 0, the letters will be in ASCII characters written little-endian, and the output field will be ended by at least one 11.

As of right now, it prints "H".

(50) // makes sure there is enough space, 50 11s is 100 bits

// H = 00010010 little-endian
21201 0 00211 / 104 0 126 // it takes the 0 from the 3rd bit of "21201" since "2" is "01" and jumps to the point right after "126"
21201 1 10221 / 104 1 154 // it does the same thing, basically
21201 2 20202 / 104 2 182
21201 11 00022 / 104 4 212 // because one trit / two bits are added, the jumping is spaced out in terms of 30 bits
21201 21 22222 / 104 5 242  
21201 12 110101 / 104 7 274 // now the jumping is spaced out in terms of 32 bits

// e = 10100110 little endian
21201 001 201201 / 104 9 308 // now the jumping is spaced out in terms of 34 bits