LiteVM
duangsuse |高二|算法底层蒟弱|函数式菜鸡# LiteVM 轻量级 JVM Lite 语言兼容虚拟机
## 基本法 | Basic Rules
我们来整理一下,顺便彻底解释所有指令语义和 _stack-based_ 化指令(只使用堆栈传参)
- LV 拥有 `call-stack`(带有 `ret_addr` 和 lazy 的 `locals HashMap`、`catch ArrayMap` )、`stack`(LinkedList<Object>) 和 `global table`(Hashtable)、`function table`、`label table`、`file`、`line`、`pc`、`expect_fun`、`expect_label`
- LV 是 __基于堆栈__ 的虚拟机,LV 只有全局表要求线程安全
- LV 支持自己的 `exception` 系统
- LV 支持 `block`,会在创建 `block` 时自动打包 `block` 的所有符号本地变量引用
- LV 使用可扩展的 __指令系统__,支持指令插件
- LV 支持的字面量有 `boolean/null/number ( byte, short, int, long, float, double, BigInteger, BigDecimal )/char/string/symbol/range`
- LV 支持 __注释__ 和 __动态链接__(允许在需要的时候创建新数组来容纳更多指令并注册函数符号表)、调试信息 `(file name, line number)`
- LV 暂时使用 __代码文本表示__
- LV 支持 __循环和分支逻辑、子过程调用、赋值运算__
- [] 能索引 `数组、Map、List、Object(getXXXX property or field)、subclass、static member`
- []= 能新建索引 `数组、Map、List、Object(setXXXX property or field)、static member`
- overriding for `+ - << [] []=`
- overriding Java methods
- method_missing support
### 词法 | Lexical Rules
`;` 到行末尾是注释,除非是在字符串出现这个
`true` 是真 `false` 是假
`null` 是空
支持 `0x 0b 0o` 数字(Hex 数位字符只支持小写),自动删除下划线,类型依次以 `B S I L F D N P` 结尾,默认类型为 `I`
`'c'` 单字符的 __single-quoted string__ 为 `char`
`"str" 'str'` 非单字符的为 `string`,其中 `""` 会处理 escape `\b\t\n\r\"\\`
`ssss` 是 `symbol`
`0..9` 是 `range`,不过这不是在词法扫描的时候创建的...
` \t\f\r\13\v\u000C` 是空格
`\n` 是换行符
### 语法 | Syntax
单纯的汇编指令式,一行为一条指令,可能是 `symbol` 或 `Object`,如果是 `Object`,向堆栈上压入这个对象,如果是 `symbol` 则尝试执行 _OpCode_
## 指令列表
- nop
啥都不做
### 压入参数
- (任何非 symbol 类型的词条)
向堆栈上压入一个对象
- pushnull
向堆栈上压入 null
- pushtrue
向堆栈上压入 true
- pushfalse
向堆栈上压入 false
- pushlv
向堆栈上压入当前 LV 虚拟机引用
- newary
弹出栈顶的值,转换为 Integer,创建指定大小的新的 Array<Object> 对象并压入堆栈
- newrange
弹出栈顶的两个值,转换为 Integer,创建 range `v2..v1` 对象并压入堆栈
- newrangestep
弹出栈顶的三个值,转换为 Integer,创建 range `v3..v2` (step v1) 对象并压入堆栈
- newsymbol
弹出栈顶的值,检查其是否是 String 的实例,如果不是,抛出内部错误,否则创建新 Symbol 对象并压入堆栈
- newblock
弹出栈顶的值,检查其是否是 Range 的实例,如果不是,抛出内部错误,否则创建新 Block 对象并压入堆栈
### 流程控制
- jump
- branchif
- branchunless
- throw
- catch
- label
- goto
### FFI
- new
- send
### 作用域
- scope
初始化当前调用栈帧的本地表
- leave
将当前调用栈帧的本地表引用置为 `null`
- sget
弹出一个 String 参数 v0,将本地变量或 `null` 入栈
- sput
弹出一个 String 参数 v0,弹出一个参数 v1,设置本地变量 `v0 = v1`
- get
- put
### 子过程
- fun
弹出一个 String 参数 v0,在下一个 IP 处添加函数符号 v0
- call
弹出一个 String 参数 funame,然后调用指定函数,如果没有找到,则设置 `expect_fun`
- ret
弹出调用栈帧并重置 `pc` 到 `ret_addr`
- yield
弹出一个 Block,调用它
### 特殊操作
- index
- newindex
- file
- line
- len
- tostring
- hashcode
- dprint
### 数学运算
- or
- in?
- and
- op<
- op>
- op<=
- op>=
- eq
- noteq
- fulleq
- shl
- add
- sub
- mul
- div
- mod
- pwr
- cast
- not
- inc
- dec
### 堆栈机标配指令
- swap
- pop
- dup