The PHP Virtual Machine is a basic virtual machine written in PHP that accepts a set of instructions modeled loosely in the style of assembly, then executes them. In this first stage it has a 512 integer "RAM" and accepts 7 unique instructions. It also has to have the program coded directly into the script, as I haven't finished the input side of things yet.
The seven operations you can perform at this point are:
SET(targetAddress,value)
This will set the value of the RAM at targetAddress to the implicitly
supplied value.
ADD(targetAddress,sourceAddress)
This will add the value of the RAM at targetAddress and the
value at sourceAddress, then place the result into
targetAddress
NOP()
The classic "No Operation", does nothing but increment the
instruction pointer and waste a cycle.
STP()
Signals the end of the program. If you do not have a stop then your
program will error out.
PRT(targetAddress)
Print the value found in the RAM at targetAddress.
ASC(targetAddress)
Print the ASCII character represented by the integer value in the
RAM at targetAddress.
BNZ(targetAddress,sourceAddress)
The most complicated instruction, "Branch Not Zero" will check and
see if the value found in RAM at targetAddress is equal to
zero. If not, it will jup the instruction pointer to the value
found in RAM at sourceAddress. This is the core iterative
structure.
Using these basic language structures a simple countdown program can
be implemented in 8 instructions.
0 SET(0,10) 1 SET(1,-1) 2 SET(2,4) 3 SET(3,10) 4 PRT(0,0) 5 ASC(3,0) 6 ADD(0,1) 7 BNZ(0,2) 8 STP(0,0)
Let's walk through this program step by step. To keep track of things, I'll refer to the memory as an array called RAM, like it is in the PHP VM implementation.
Our first instruction is to SET RAM[0] to the value 10.
After executing this the first five RAM values looks like this:
[10][0][0][0][0]
The next three are similar.
SET RAM[1] to -1
SET RAM[2] to 4
SET RAM[3] to 10
After execution RAM looks like this:
[10][-1][4][10][0]
Next I think that it is important to point out at this point what exactly we are holding each value in RAM for.
RAM[0] is our counter, to keep track of where we are in the countdown.
RAM[1] is our decrement variable, we will ADD it to RAM[0] to decrease it's value.
RAM[2] is the index of the instruction we want to jump back to on the instruction array. If you look at the program, you'll see that this corresponds to PRT(0,0).
Now, back to our program. We now hit PRT(0,0), so we print the integer value found at RAM[0], which is 10.
Next up is ASC(3,0), so we print the ASCII value of the integer found at RAM[3]. That is integer is 10, and the ASCII value of 10 is a newline character (\n).
After that is ADD(0,1). This requires us to add the value
found in RAM[0] and RAM[1] together, then store it in
RAM[0].
This is essentialy saying RAM[0] = 10 + (-1)
Our array of RAM looks like this afterwards:
[9][-1][4][10][0]
Now we reach the harder part, BNZ(0,2). What this is saying is "If the value found in RAM[0] is not equal to literal 0, then jump back to the instruction index that is equal to the value found in RAM[2]". Since, at this point RAM[0] is equall to 9, and not zero, we jump to the instruction at the value of RAM[2], which is 4. This is PRT(0,0).
Here we repeat instructions 4 through 7 another 8 times, with the RAM
looking like this in each successive pass:
[8][-1][4][10][0]
[7][-1][4][10][0]
[8][-1][4][10][0]
[5][-1][4][10][0]
[4][-1][4][10][0]
[3][-1][4][10][0]
[2][-1][4][10][0]
[1][-1][4][10][0]
[0][-1][4][10][0]
At this point something new happens, instruction 8, BNZ(0,2)
returns false, and the instruction pointer is allowed to increment
naturally.
This gets us to STP(0,0), which simply ends the program.
I realize I'm not the best instructor, so you'll probably just want to get the source code and play around with it. You'll figure it out soon enough if you haven't got it already. Below is an example run of the program described in this document.
PHP VM - Version 0.01 Loading Instructions Padding RAM Setting Environment Executing 10 9 8 7 6 5 4 3 2 1 Finished - Running Time: 0.00021696 Seconds