Polygon虚拟机
Polygon虚拟机(PVM)是用于自编编程语言Polygon的虚拟机。 PVM是一个基于寄存器的虚拟机,所以这意味着它使用寄存器执行各种操作。很疯狂,我知道!这是我的个人项目之一,我计划继续开发它。
简介
PVM可以与文件一起工作,并通过它的专用REPL(读-评-打印循环)。PVM对扩展名为.plasm 的文件进行操作,其语法如下:
// examples/for_loop.plasm
load $0 1
load $1 5
load $2 16
load $3 36
gtq $0 $1
jeq $3
out $0
inc $0
jneq $2
out $0
hlt
乍一看,有许多事情正在发生。但我会在下一节中解释。 首先,Plasm编译器接受这些指令,并检查每一条指令是否有错误。 如果没有,它将这些指令转换为字节码,例如:
// This is a load instruction representation in bytecode
load $0 100
^^^^ ^^ ^^^
02 00 00 64
PVM总共可以处理23条指令(目前)。PVM仍然处于开发阶段,所以还有更多的指令会出现。让我们来看看每条指令,看看它们的参数是什么,以及它们做什么。
指令
正如我之前所说,PVM可以处理23条指令。 下面是所有可用指令的列表:
hlt load move add sub mul div jmp jmpf
jmpb out eq neq gt lt gtq ltq jeq jneq
free alloc inc dec
PVM在寄存器的帮助下进行操作。总共有32个寄存器,可以称为$<register_number> 。寄存器的枚举从0开始,因此,例如,如果我们想访问第15个寄存器,我们将把它称为$14 。按照这个逻辑,我们最后的第32个寄存器将是$31 。现在,让我们来看看每个指令。
hlt 代表停顿:它告诉PVM停止程序的执行。
load <register> <integer_literal> 将一个指定的整数字放在指定的寄存器中。
move <from_register> <to_register> 将一个值从一个指定的寄存器移到另一个寄存器,同时将原寄存器的值设为0。
add <target> <register_1> <register_2> 将两个寄存器的值相加,并将结果放入目标寄存器。
sub <target> <register_1> <register_2> 从2个寄存器中减去数值,并将结果放在目标寄存器中。
mul <target> <register_1> <register_2> 2个寄存器的值相乘,将结果放在目标寄存器中。
div <target> <register_1> <register_2> 2个寄存器的值相除,将结果放在目标寄存器中,并将余数存储在内存中。
jmp <target> 从另一个点继续执行。
jmpf <target> 与jmp相同,但不能向后跳转。
jmpb <target> 与jmp相同,但不能进一步jmp。
out <target> 打印寄存器中的值。
eq <register_1> <register_2> 检查两个值是否相等。
neq <register_1> <register_2> 检查两个值是否相等,如果两个值不相等。
gt <register_1> <register_2> 检查value_1是否大于value_2。
lt <register_1> <register_2> 检查value_1是否小于value_2。
gtq <register_1> <register_2> 检查value_1是否大于或等于value_2。
ltq <register_1> <register_2> 检查value_1是否小于或等于value_2。
jeq <target> 检查之前的平等指令是否为真(1)并执行jmp指令。
jneq <target> 检查之前的平等指令是否为假(0),并执行一条jmp指令。
free <target> 将目标寄存器的值设为0。
alloc <register> 从堆上的寄存器中分配字节数。
inc <register> 将存储在寄存器中的值增加1。
dec <register> 将寄存器中的值减去1。
警告!
这是一个个人项目,由一个人维护。请不要在生产环境中使用这个项目,直到它达到稳定版本。