一种服务于脚本执行的可二进制化指令语言
SEVM:Script Execution Virtual Machine https://github.com/inmount/SEVM
为了最大化的兼容现有从业者的使用习惯,我将使用类似汇编语言的指令方式定义。
同时,为了简化处理,增加了类似属性值的多样化信息表示。
操作符号说明:
- ; 语句结束符,后面的字符不计入代码
- " 字符串定义符号
- \ 字符串中的转义符,\"为双引号,\r为回车符,\n为换行符
- @ 标签定义
- , 命令参数分隔符
- # 寄存器定义
- $ 临时变量定义
- [] 直接访问虚拟内存
用来导入程序集或是内置函数集。
例如:
import
use "host"; 导入内置函数集
lib "print"; 导入名称为"print"的外部程序集
end import
用来定义初始内存信息。
支持的类型包括:number, string
例如:
data
[1] number 1; 添加一个数字虚拟内存空间
[2] number 2
[3] string "a+b的和是"; 添加一个字符串虚拟内存空间
[4] string "print"
end data
用来定义变量名称及指针。
例如:
define
$0 a 1; 定义一个变量a,指向第6个虚拟内存空间
$1 b 2; 定义一个变量b,指向第7个虚拟内存空间
$2 c 5
$3 str 6
end define
用来定义变量名称及指针。
例如:
func
@1 main; 定义编号为1的函数,外部暴露名称为print
end func
用来定义代码区域
例如:
code
@1
; c=a+b
mov #0, $0; 将变量a中的内容赋值给0号寄存器
add #0, $1
mov $2, #0
; str="a+b的和是"+c
mov #0, 0
new $4; 申请一个临时变量$4,并指向新的虚拟内存空间
list $4; 设置临时变量$4为一个列表
ptrl $4, 0, 3; 临时变量$4列表的第1项指向第3个虚拟内存空间
new $5;
leal #2, $5, 1
ptrl $4, 1, #2; 临时变量$4列表的第2项指向临时变量$5的虚拟内存空间
mov $5, $2
join $3, $4; 将临时变量$4中的所有项目进行连接,再将结果赋值给变量$3
; print(str)
new $6;
list $6;
leal #2, 0, $3
ptr $6, #2
lea #0, $6; 将临时变量$3的地址赋值给0号寄存器
call [0], [4]; 执行print函数
end code
指令格式:Operate [Exp1][,Exp2][,Exp3]
将Exp2指向的内容赋值给Exp1指向的空间中。
例如:
mov #0, 0
更改Exp1变量的指针地址为Exp2的值,如Exp2未指定,则指向一个新的存储空间。
例如:
ptr $1
ptr $1, 1
获取Exp2的指针地址,填充到Exp1的内容中。
例如:
lea #1, $1
获取Exp2数值的整数部分,填充到Exp1的内容中。
例如:
int $1, $2
获取Exp2数值的小数部分,填充到Exp1的内容中。
例如:
frac $1, $2
设定Exp1的内容类型为列表。
例如:
list $1
更改Exp1列表元素的第Exp2项指针地址,为Exp3的值。
例如:
ptrl $1, 1, 10
获取Exp2列表元素的第Exp3项指针地址,填充到Exp1的内容中。
例如:
leal #0, $1, 1
获取Exp2列表的第一个E匹配Exp3的值的索引,填充到Exp1的内容中。
例如:
idx #0, $1, [10]
连接Exp2列表中的所有项目,将结果填充到Exp1的内容中。
例如:
join $2, $1
计算Exp2列表中的项目数量,将结果填充到Exp1的内容中。
例如:
cnt #0, $1
设定Exp1的内容类型为对象。
例如:
obj $1
更改Exp1对象元素的键列表的指针,为Exp2的值。
例如:
ptrk $1, 10
更改Exp1对象元素的值列表的指针,为Exp2的值。
例如:
ptrv $1, 10
获取Exp2对象元素的键列表指针地址,填充到Exp1的内容中。
例如:
leak #0, $1
获取Exp2对象元素的值列表指针地址,填充到Exp1的内容中。
例如:
leav #0, $1
将Exp1的值和Exp2的值执行加法运算,将结果填充到Exp1的内容中。
例如:
add $1, 1
将Exp1的值和Exp2的值执行减法运算,将结果填充到Exp1的内容中。
例如:
sub $1, 1
将Exp1的值和Exp2的值执行乘法运算,将结果填充到Exp1的内容中。
例如:
mul $1, 1
将Exp1的值和Exp2的值执行除法运算,将结果填充到Exp1的内容中。
例如:
div $1, 1
将Exp1的值执行非运算,将结果填充到Exp1的内容中。
例如:
not $1
将Exp1的值和Exp2的值执行与运算,将结果填充到Exp1的内容中。
例如:
and $1, $2
将Exp1的值和Exp2的值执行或运算,将结果填充到Exp1的内容中。
例如:
or $1, $2
将Exp1的值和Exp2的值执行异或运算,将结果填充到Exp1的内容中。
例如:
xor $1, $2
将Exp2的值和Exp3的值执行比较运算,判断两个值是否相等,相等为1,不相等为0,比较结果填充到Exp1的内容中。
例如:
equal #0, $1, $2
将Exp2的值和Exp3的值执行比较运算,判断前值是否大于后值,大于为1,否则为0,比较结果填充到Exp1的内容中。
例如:
large #0, $1, $2
将Exp2的值和Exp3的值执行比较运算,判断前值是否大于后值,大于为1,否则为0,比较结果填充到Exp1的内容中。
例如:
small #0, $1, $2
执行跳转。
例如:
jmp @1
当Exp1的值大于0,则执行Exp2指向的标签跳转
例如:
jmpf #0, @2
从#0寄存器的值中读取参数列表指针,调用对应的函数,返回的内容赋值给前置参数
例如:
mov #0, $2
call $1, [10]
对应Call执行返回。
例如:
ret $1