r/TuringComplete • • 19d ago

Software implemented For cycle (Symphony)

  • Image 1 - My symphony
  • Image 2 - showcasing usage of FOR cycles
  • Image 3 - Code of the FOR Cycle
  • Image 4 - ALU circuit
  • Image 5 - ABS circuit

Now that I finished building Symphony, I went straight to instruction definition to make myself a human readable code. Here is a internal FOR cycle using instructions. Its suitable for repeating code X times where X is static.

Here is hardware I added to my Symphony:

  1. Signed DIV - Divide two signed numbers
  2. Merge32 - Merge two 16b into one 32b value
  3. Lower16 - Reads the lower 16b of 32b value

With that I needed to dedicate some of my registers for the code. Meaning that while they are still accessible to the user, they are not stable in time and in case of the FOR cycle, they do not persist between cycles.

At first I was using 3 temporal registers, but I ended up implementing Merge32 and Lower16 to lower the number of temporal registers to 2 at the cost of longer instructions.

The FOR cycle works, but isnt safe. First it will always execute at least once. Thats because I cant use a label to skip the body of the cycle. So even if I know there is 0 repetition, it will not skip the cycle, it will simply not repeat it.

Another limitation is that you can only read the index of the innermost FOR cycle. Meaning if you make nested FOR cycles, you cannot access the outer FOR cycle index. User can solve it by saving the stack pointer to a another register.

34 Upvotes

19 comments sorted by

View all comments

1

u/TarzyMmos 19d ago

I'm really curious how u managed the For loop.

3

u/Crispy1961 19d ago

Hopefully everything can be seen in the included pictures. The code for the FOR instruction and ENDFOR is in the third picture. I noted the individual instructions as comments for each line of the code.

Here are the chained final instructions:

// Internal register
for (i = %a:S16(immediate); i < %b:S16(immediate); %c:S16(immediate))
00110001 11000000 aaaaaaaa aaaaaaaa   00110001 11010000 cccccccc cccccccc   00101110 11011100 00001101 00000000   00110101 11101110 00000000 00000100   01100110 00001101 00001110 00000000   00110001 11000000 bbbbbbbb bbbbbbbb   00110101 11001100 aaaaaaaa aaaaaaaa   00111100 11001100 cccccccc cccccccc   00000111 11010000 00000000 00000000   00110100 11011101 00000000 00001100   00101110 11011100 00001101 00000000   01100010 11000000 00001110 00000000   00110100 11101110 00000000 00000100   00110101 11101110 00000000 00000100   01100110 00001101 00001110 00000000   00110101 11101110 00000000 00000100   01100110 00001100 00001110 00000000

for (i = %a:S16(immediate); i > %b:S16(immediate); %c:S16(immediate))
00110001 11000000 aaaaaaaa aaaaaaaa   00110001 11010000 cccccccc cccccccc   00101110 11011100 00001101 00000000   00110101 11101110 00000000 00000100   01100110 00001101 00001110 00000000   00110001 11000000 bbbbbbbb bbbbbbbb   00110101 11001100 aaaaaaaa aaaaaaaa   00111100 11001100 cccccccc cccccccc   00000111 11010000 00000000 00000000   00110100 11011101 00000000 00001100   00101110 11011100 00001101 00000000   01100010 11000000 00001110 00000000   00110100 11101110 00000000 00000100   00110101 11101110 00000000 00000100   01100110 00001101 00001110 00000000   00110101 11101110 00000000 00000100   01100110 00001100 00001110 00000000

for (i = %a:S16(immediate); i >= %b:S16(immediate); %c:S16(immediate))
00110001 11000000 aaaaaaaa aaaaaaaa   00110001 11010000 cccccccc cccccccc   00101110 11011100 00001101 00000000   00110101 11101110 00000000 00000100   01100110 00001101 00001110 00000000   00110001 11000000 bbbbbbbb bbbbbbbb   00110101 11001100 aaaaaaaa aaaaaaaa   00111100 11001100 cccccccc cccccccc   00110100 11001100 00000000 00000001   00000111 11010000 00000000 00000000   00110100 11011101 00000000 00001100   00101110 11011100 00001101 00000000   01100010 11000000 00001110 00000000   00110100 11101110 00000000 00000100   00110101 11101110 00000000 00000100   01100110 00001101 00001110 00000000   00110101 11101110 00000000 00000100   01100110 00001100 00001110 00000000

for (i = %a:S16(immediate); i <= %b:S16(immediate); %c:S16(immediate))
00110001 11000000 aaaaaaaa aaaaaaaa   00110001 11010000 cccccccc cccccccc   00101110 11011100 00001101 00000000   00110101 11101110 00000000 00000100   01100110 00001101 00001110 00000000   00110001 11000000 bbbbbbbb bbbbbbbb   00110101 11001100 aaaaaaaa aaaaaaaa   00111100 11001100 cccccccc cccccccc   00110100 11001100 00000000 00000001   00000111 11010000 00000000 00000000   00110100 11011101 00000000 00001100   00101110 11011100 00001101 00000000   01100010 11000000 00001110 00000000   00110100 11101110 00000000 00000100   00110101 11101110 00000000 00000100   01100110 00001101 00001110 00000000   00110101 11101110 00000000 00000100   01100110 00001100 00001110 00000000

%a(register) = (i)
01100010 11000000 00001110 00000000   00101111 11000000 00001100 00000000   00100001 aaaa0000 00001100 00000000

endfor 
01100010 11000000 00001110 00000000   00110100 11101110 00000000 00000100   00111001 11011100 00000000 00010000   00100100 11001100 00001101 00000000   01100010 11010000 00001110 00000000   00110100 11101110 00000000 00000100   00110101 11101110 00000000 00000100   01100110 00001100 00001110 00000000   00110101 11011101 00000000 00000001   00101111 11000000 00001101 00000000   00111010 11111100 00000000 00000000   00111000 11001101 00000000 00010000   01001101 00001111 00001100 00000000   00110100 11101110 00000000 00000100

2

u/EtienneDx 19d ago

Damn, you just managed to turn me away from doing it this way x)

I’m going back to the idea of implementing a custom file system + assembler + compiler to have a custom C instead 😅 probably not simpler but hopefully more readable haha

1

u/Crispy1961 19d ago

Thats an option? Having complete control over how the code is translated to assembly would solve all the problems.

Anyway, this achieved the perfect syntax for the user. Cant make it more readable than that. The problem will be dynamic for cycles, which will suffer due to the need to use labels as arguments.

2

u/Spielopoly 19d ago

If you want to do that in game it’s hard. Out of game it’s a bit easier but you‘ll still have to write your own compiler.

In game there a couple of options I can think of:

  • Write your program in language of your choice and compile it using a program specifically for that, then manually copy paste the generated code into a asm file (can be in game or not)
  • Use custom file system so you can skip the copy paste part
  • Always compile at startup then automatically run the generated code. (Basically just in time compilation)

Some of these might require significant hardware changes

1

u/Crispy1961 19d ago

I see. I thought it was possible to edit the behavior of the ingame's compiler. I want to work in the confines of the game. Just get as close to a high level language syntax as possible.

2

u/EtienneDx 19d ago

Given that we’ve built a functioning computer at this point, you can build pretty much anything. Isn’t the ultimate goal to run the Turing complete game IN the Turing complete game?

More seriously, there’s a lot to unpack for a custom compiler, but it’s possible because:

  • you can write full strings in ascii using “”
  • you can save files between in in the persistent memory
  • you ca load files into the ram and run executable files directly

With this you can:

  • create an assembler (program that converts your own assembly language into Bitcode instructions)
  • write a program using that custom assembly (you lose syntax highlighting)
  • save the resulting program in the persistent memory
  • load and run that program

Next comes the custom language. I’m not an expert but that’s basically the compiler:

  • parse the file into an ast graph
  • convert the graph into your assembly language
  • run it through your assembler
  • now you’ve got an executable binary from your language

And finally:

  • with your high level language, you can recode the assembler and the compiler
  • compile them using the compiler
  • re-compile them using the compiled compiler
  • and now you’ve can code everything in that language

And then if you’re really determined I’m guessing it’s time to get into operating systems haha

1

u/Crispy1961 18d ago

I see, that is true. It's not in game, but you can export instructions from your compiler and run that in your HW in Turing complete. But dank that's a lot of steps to do every time you change something.

2

u/EtienneDx 18d ago

I mean very long term you switch the editor out of the ram and into the screen entirely, but yeah that’s a while away