Skip to content

Commit f668ed2

Browse files
committed
refactor(include): refactor dependency libraries
1. update some documents 2. refactor dependency libraries please refer to the work log for details
1 parent 39f5bf6 commit f668ed2

25 files changed

+621
-517
lines changed

demos/demo.stvc

0 Bytes
Binary file not shown.

demos/demo1.stvc

0 Bytes
Binary file not shown.

demos/demo2.stvc

0 Bytes
Binary file not shown.

doc/STVC-TAC中间代码规范.md

Lines changed: 85 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# STVC-TAC中间代码规范
1+
# STVC-TAC中间代码规范(第二版)
22

33
### 前言
44

@@ -43,14 +43,29 @@ STVC文件由以下部分组成:
4343

4444
标识符有三个种类:用户标识符,临时标识符和内部标识符。
4545

46-
用户标识符一般为用户自定义的标识符,其格式与C标识符格式相同。
46+
**用户标识符**一般为用户自定义的标识符,其格式与C标识符格式相同。
4747

48-
临时标识符则是表达式计算过程当中会用到的标识符,此类标识符的格式为``.XXX``,其中“XXX”为数字。
48+
**临时标识符**则是表达式计算过程当中会用到的标识符,此类标识符的格式为``.XXX``,其中“XXX”为数字。
4949

50-
内部标识符则是用于匿名类、匿名函数的声明,此类标识符的格式为``#XXX``,其中“XXX”为数字。
50+
**内部标识符**则是用于匿名类、匿名函数的声明,此类标识符的格式为``#XXX``,其中“XXX”为数字。
5151

5252
因此编译器在编译时应先指明标识符的类型,再指明标识符的编号。
5353

54+
##### SFN
55+
56+
SFN,全称*Stamon For Native*,是Stamon调用外部库的一个机制。调用SFN时,需要指定一个端口并提供参数,不同的端口对应不同的外部功能。
57+
58+
##### 容器
59+
60+
“容器”的概念与“成员”的概念恰好相反。
61+
62+
如果一个对象 *O* 拥有一个成员 *m*,那么规定 *O**m* 的容器。
63+
64+
初始化一个类对象时,通常需要初始化类方法。
65+
而初始化类方法时,通常需要为其指定容器。这样用户在调用类方法时,Stamon会自动将容器传入“self”参数,从而实现类方法调用其他类成员。
66+
67+
类方法和全局函数在数据类型上是相同的。唯一不同之处在于:类方法拥有容器,而全局函数不具有容器。
68+
5469
##### 运算语句
5570

5671
1. ``x = ASSIGN y``
@@ -67,76 +82,96 @@ STVC文件由以下部分组成:
6782

6883
上述的ASSIGN、UNARY和BINARY均为助记符,虚拟机可以通过助记符直接判断运算类型。助记符应当在二进制文件中表现出来。
6984

85+
4. ``x[index] = y``
86+
87+
将x的第index个元素赋值为y。
88+
89+
5. ``x = y[index]``
90+
91+
将x赋值为y的第index个元素。
92+
93+
6. ``x.member = y``
94+
95+
将x的member成员赋值为y。
96+
97+
7. ``x = y.member``
98+
99+
将x赋值为y的member成员。
100+
70101
##### 流程控制语句
71102

72103
1. ``goto addr``
73104

74105
无条件跳转至相对addr行指令所在处。若addr<0,向上跳转,否则向下跳转。
75106

76-
2. ``if condition => addr``
107+
2. ``if condition addr``
77108

78109
如果condition不为``null````0``则跳转至相对addr行指令所在处。若addr<0,向上跳转,否则向下跳转。
79110

80-
3. ``call result function: arg1 arg2 ...``
111+
3. ``call result function arg1 arg2 ...``
81112

82113
调用function值。参数为arg1、arg2等标识符或值。返回值存入result当中。
83114

84115
4. ``return value``
85116

86117
返回value值。
87118

88-
5. ``try addr``
89-
90-
监测该以下addr(addr必须是正数)行的代码是否有抛出异常,如果出现异常,就直接跳转到``try``指令以下addr行(即跳过try代码块),因此try代码块在包含本应包含的代码的同时,也要在结尾加上``goto catch代码块大小``,以此跳过catch块;在try代码块后需要紧跟着catch代码块。
91-
92119

93120
值得注意的是:
94121
* 入口代码不需要在结尾返回
95122
* 跳转的指令偏差应该是能接受的(如一个函数有五条指令,显然不能往下跳转六条指令)
96123

97-
##### 特别的...
124+
##### 内存操作语句
98125

99126
1. ``new object source arg1 arg2 ...``
100127

101-
将source标识符作为类,新建对象,构造参数为arg1、arg2等,新建后的对象值存入object标识符
128+
将source标识符作为类,新建对象,构造参数为arg1、arg2等,新建后的对象值存入object标识符
102129

103-
2. ``member dst src mber``
130+
2. ``list identifier element1 element2...``
104131

105-
将src中的mber成员取出,存入dst
132+
将element1、element2...作为元素,组合成数列,并存入identifier标识符中
106133

107-
3. ``sfn port arg``
134+
3. ``array identifier length``
108135

109-
设置SFN,port为端口号标识符。arg参数标识符
136+
将identifier赋值为一个长度为length的空数列
110137

111-
SFN的介绍见``编译器开发文档.md``
138+
4. ``free identifier``
112139

113-
4. ``list identifier element1 element2...``
140+
如果identifier所存储的是字面量值(如整型),则释放。该指令和C语言的register关键字类似,**是否释放取决于虚拟机状态。**该指令通常用于释放临时标识符。
114141

115-
将element1、element2...作为元素,组合成数列,并存入identifier标识符中
142+
##### 作用域操作语句
116143

117-
5. ``pushscope``
144+
1. ``pushscope``
118145

119-
压入一个作用域,用于跳转指令
146+
压入一个作用域,用于跳转指令
120147

121-
6. ``popscope``
148+
2. ``popscope``
122149

123-
弹出一个作用域,用于跳转指令
150+
弹出一个作用域,用于跳转指令
124151

125-
7. ``free identifier``
152+
3. ``def identifier``
126153

127-
如果identifier所存储的是字面量值(如整型),则释放。该指令和C语言的register关键字类似,**是否释放取决于虚拟机状态。**该指令通常用于释放临时标识符。
154+
在当前作用域定义一个名为identifier的变量。
155+
156+
##### 异常处理语句
157+
158+
1. ``pushcatch addr``
128159

129-
8. ``throw identifier``
160+
进入一个新的try-catch块时,需要调用该指令,addr为catch块的地址。
130161

131-
将identifier标识符所存储的值作为异常内容,进行抛出。
162+
2. ``popcatch``
132163

133-
9. ``getexception identifier``
164+
退出一个try-catch块时,需要调用该指令。
165+
166+
3. ``getexception identifier``
134167

135168
将当前异常内容存入identifier。
136169

137-
10. ``resetexceptionflag``
170+
##### 外部库调用语句
171+
172+
1. ``sfn port arg``
138173

139-
重置异常标记(即标记为无异常状态)
174+
调用SFN的port端口,参数为arg
140175

141176
### 代码声明
142177

@@ -145,29 +180,28 @@ SFN的介绍见``编译器开发文档.md``
145180
##### 声明函数
146181

147182
```
148-
function identifier: arg1 arg2 arg3 ...
183+
function identifier arg1 arg2 ...
149184
...some codes...
150185
end
151186
```
152187

153-
其中identifier为函数名。arg1、arg2、arg3等为函数的参数名。“...some codes...”为函数体代码
188+
其中identifier为函数名。arg1、arg2等为函数的参数名。“...some codes...”为函数体代码
154189

155190
函数内部不能嵌套声明函数或类(因此需要在函数外部,用内部标识符定义函数或类,在运行时赋值)。
156191

157192
##### 声明类
158193

159194
```
160-
class identifier: member1 member2 member3 ...
195+
class identifier member1 member2 * member3...
161196
...some codes...
162-
method member1 member2 ...
163197
end
164198
```
165199

166200
其中identifier为类名。member1、member2、member3等为类成员名。“...some codes...”为类初始化赋值代码(并不是构造函数)。
167201

168-
method语句包含了若干个标识符,表示此标识符为方法
202+
如果类成员名的左侧带有“*”,则代表此成员是类方法
169203

170-
在初始化类对象时,会先执行初始化赋值代码,根据method语句为方法指定容器,再调用构造函数。
204+
在初始化类对象时,会先执行初始化赋值代码,接着为类方法指定容器,再调用构造函数。
171205

172206
类内部不能嵌套声明函数或类(因此需要在在外部用内部标识符定义函数或类,在初始化时赋值)。
173207

@@ -177,53 +211,30 @@ method语句包含了若干个标识符,表示此标识符为方法。
177211

178212
### 附表
179213

180-
所有基本语句有以下几种
214+
所有语句有以下几种
181215

182216
* ``x = ASSIGN y``
183217
* ``x = UNARY op y``
184218
* ``x = BINARY y op z``
219+
* ``x[index] = y``
220+
* ``x = y[index]``
221+
* ``x.member = y``
222+
* ``x = y.member``
185223
* ``goto addr``
186224
* ``if condition => addr``
187-
* ``call result function: arg1 arg2 ...``
225+
* ``call result function arg1 arg2 ...``
188226
* ``return value``
189-
* ``try addr``
190227
* ``new object source arg1 arg2 ...``
191-
* ``member dst src mber``
192-
* ``sfn port arg``
193228
* ``list identifier element1 element2...``
229+
* ``array identifier length``
230+
* ``free identifier``
194231
* ``pushscope``
195232
* ``popscope``
196-
* ``free identifier``
233+
* ``def identifier``
234+
* ``pushcatch addr``
235+
* ``popcatch``
197236
* ``getexception identifier``
198-
* ``resetexceptionflag``
199-
200-
201-
双目运算符有以下种类:
202-
203-
* add:加
204-
* sub:减
205-
* mul:乘
206-
* div:除
207-
* mod:取余
208-
* lsh:左移
209-
* rsh:右移
210-
* less:小于
211-
* lequ:小等于
212-
* big:大于
213-
* bequ:大等于
214-
* equ:判等
215-
* iequ:判不等
216-
* band:按位与
217-
* bxor:按位异或
218-
* bor:按位或
219-
* land:逻辑与
220-
* lor:逻辑或
221-
* index:取下标
222-
223-
而单目运算符有以下种类:
224-
225-
* pos:正
226-
* neg:负
227-
* cpl:按位取反
228-
* not:逻辑非
229-
* arr:组成为数列
237+
* ``sfn port arg``
238+
* ``function identifier arg1 arg2 ...``
239+
* ``class identifier member1 member2 * member3...``
240+
* ``end``
Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
# STVC-TAC二进制编码规范(第一版
1+
# STVC-TAC二进制编码规范(第二版
22

33
### 前言
44

5-
在阅读本规范前,我们强烈建议先阅读``STVC-TAC中间代码规范.md``
5+
在阅读本规范前,我们**强烈建议**先阅读``STVC-TAC中间代码规范.md``
66

77
由于``STVC-TAC中间代码规范.md``并没有对具体编码细节进行阐述,因此编写此文档进行补充。
88

9-
此文档仅作规范,并非唯一解决方案,开发者也可以制定自己的编码格式(但我们强烈建议制定的规范符合``STVC-TAC中间代码规范``
9+
此文档仅作规范,并非唯一解决方案,开发者也可以制定自己的编码格式(但我们强烈建议制定的规范符合``STVC-TAC中间代码规范``
1010

1111
### 常量表
1212

@@ -17,33 +17,47 @@
1717
* 整数类型:占4字节,即数值
1818
* 单精度浮点类型:占4字节,即数值
1919
* 双精度浮点类型:占8字节,即数值
20-
* 字符串类型:占4+l字节,其中前4字节记录字符串长度(即l,长度按字节计),后l字节为字符串值
21-
* 标识符类型:占4+l字节,其中前4字节记录标识符长度(即l,长度按字节计),后l字节为标识符名
20+
* 字符串类型:占4+len字节,其中前4字节记录字符串长度(即l,长度按字节计),后len字节为字符串值
21+
* 标识符类型:占4+len字节,其中前4字节记录标识符长度(即len,长度按字节计),后len字节为标识符名
2222

23+
一个常量表下标默认为4字节。
2324

2425
### 语句
2526

26-
语句的操作码占一字节,操作数不定长。
27-
28-
以下为所有的基本语句,其中第一条语句对应的操作码为``0x01``,第二条对应``0x02``,以此类推。
29-
30-
注意:常量表下标默认为4字节。
31-
32-
* ``x = ASSIGN y``:操作数为x和y的常量表下标
33-
* ``x = UNARY op y``:操作数为x和y的常量表下标
34-
* ``x = BINARY y op z``:操作数为x和y和z的常量表下标
35-
* ``goto addr``:操作数为4字节的数值,代表跳转地址
36-
* ``if condition => addr``:操作数为condition的常量表下标和4字节的数值(跳转地址)
37-
* ``call result function: arg1 arg2 ...``:操作数为result的常量表下标,和4字节的数值(参数个数)以及所有参数的常量表下标
38-
* ``return value``:操作数为value的常量表下标
39-
* ``try addr``:操作数为4字节的数值,代表跳转地址
40-
* ``new object source arg1 arg2 ...``:操作数为object的常量表下标,和4字节的数值(构造参数个数)以及所有参数的常量表下标
41-
* ``member dst src mber``:操作数为dst和src和mber的常量表下标
42-
* ``sfn port arg``:操作数为port和arg的常量表下标
43-
* ``list identifier element1 element2...``:操作数为identifier的常量表下标,和4字节的数值(元素个数)以及所有元素的常量表下标
44-
* ``pushscope``:无操作数
45-
* ``popscope``:无操作数
46-
* ``free identifier``:操作数为identifier的常量表下标
47-
* ``getexception identifier``:操作数为identifier的常量表下标
48-
* ``resetexceptionflag``:无操作数
49-
27+
其中第一条语句对应的操作码为``0x01``,第二条对应``0x02``,以此类推。
28+
29+
这里需要特别说明一下,二进制布局的表示形式,操作数的二进制布局会用如下格式表示
30+
31+
``OPND1(size) OPND2(size) ...``
32+
33+
即每一个操作数的名字后面跟着这个操作数的长度。
34+
35+
在了解了二进制布局的格式之后,我们来看看每条中间代码语句对应的二进制布局
36+
37+
|中间代码|对应的操作数二进制布局|补充解释|
38+
|``x = ASSIGN y``|``x(4) y(4)``|x和y都是常量表下标|
39+
|:-|:-|:-|
40+
|``x = UNARY op y``|``x(4) op(4) y(4)``|x和y是常量表下标,op是一个整数|
41+
|``x = BINARY y op z``|``x(4) op(4) y(4) z(4)``|x和y和z是常量表下标,op是一个整数|
42+
|``x[index] = y``|``x(4) index(4) y(4)``|x和y和index都是常量表下标|
43+
|``x = y[index]``|``x(4) index(4) y(4)``|x和y和index都是常量表下标|
44+
|``x.member = y``|``x(4) member(4) y(4)``|x和y和member都是常量表下标|
45+
|``x = y.member``|``x(4) member(4) y(4)``|x和y和member都是常量表下标|
46+
|``goto addr``|``addr(4)``|addr代表跳转地址,是一个整数|
47+
|``if condition => addr``|``condition(4) addr(4)``|condition是一个常量表下标,addr是一个整数|
48+
|``call result function arg1 arg2 ...``|``result(4) function(4) arglen(4) arg1(4) arg2(4) ...``|result、function、arg1、arg2等是常量表下标,arglen是一个整数,代表参数的个数|
49+
|``return value``|``value(4)``|value是一个常量表下标|
50+
|``new object source arg1 arg2 ...``|``object(4) source(4) arglen(4) arg1(4) arg2(4) ...``|object、source、arg1、arg2等都是常量表下标,arglen是一个整数,代表参数的个数|
51+
|``list identifier element1 element2...``|``identifier(4) arglen(4) element1(4) element2(4) ...``|identifier、element1、element2等都是常量表下标,arglen是一个整数,代表参数的个数|
52+
|``array identifier length``|``identifier(4) length(4)``|identifier和length都是常量表下标|
53+
|``free identifier``|``identifier(4)``|identifier是一个常量表下标|
54+
|``pushscope``|``nothing(0)``|没有任何操作数|
55+
|``popscope``|``nothing(0)``|没有任何操作数|
56+
|``def identifier``|``identifier(4)``|identifier是一个常量表下标|
57+
|``pushcatch addr``|``addr(4)``|addr是一个整数|
58+
|``popcatch``|``nothing(0)``|没有任何操作数|
59+
|``getexception identifier``|``identifier(4)``|identifier是一个常量表下标|
60+
|``sfn port arg``|``port(4) arg(4)``|port和arg都是常量表下标|
61+
|``function identifier arg1 arg2...``|``identifier(4) arglen(4) arg1(4) arg2(4) ...``|identifier、arg1、arg2等都是常量表下标,arglen是一个整数,代表参数的个数|
62+
|``class identifier member1 member2 * member3...``|``identifier(4) member1_methodflag(1) member1(4) member2_methodflag(1) member2(4) member3_methodflag(1) member3(4) ...``|identifier、member1、member2、member3等都是常量表下标,member1_methodflag、member2_methodflag、member3_methodflag等都是整数,表示其对应的类成员是否是类方法|
63+
|``end``|``nothing(0)``|没有任何操作数|

doc/代码速览指南.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@
7575

7676
该目录存储虚拟机的实现。
7777

78+
* ``src/action``
79+
80+
该目录用于存储分步行动机制的实现代码(包括一些文件的编解码实现)。
81+
7882
### 源码阅读顺序
7983

8084
我们建议开发者先从基础出发,一步步看到主函数的实现。
@@ -86,6 +90,7 @@
8690
* ``src/compiler``
8791
* ``src/vm``
8892
* ``src/sfn``
93+
* ``src/action``
8994
* ``src/ir``
9095
* ``src``
9196
* ``src/bin-include``

doc/发行版使用指南.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ Stamon目前支持以下指令:
5151
|参数用法|功能|默认值|支持此参数的最低版本|
5252
|-|-|-|-|
5353
|--GC=&lt;boolean&gt;|是否运行GC(垃圾自动回收)|true|2.4.4|
54-
|--MemLimit=&lt;Integer&gt;|设置虚拟机的对象内存限制(按字节计)|默认为16,777,216字节,即16MB|2.4.4|
55-
|--MemPoolCache=&lt;Integer&gt;|设置内存池缓存大小(按字节计)|默认为16,777,216字节,即16MB|2.4.19|
54+
|--MemLimit=&lt;Integer&gt;|设置虚拟机的对象内存限制(按字节计)|默认为16,777,216字节,即16MiB|2.4.4|
55+
|--MemPoolCache=&lt;Integer&gt;|设置内存池缓存大小(按字节计)|默认为16,777,216字节,即16MiB|2.4.19|
5656
|--IgnoreWarning|忽略警告|默认只进行警告|2.4.28|
5757
|--JustWarn|只进行警告|默认只进行警告|2.4.28|
5858
|--FatalWarning|将警告作为致命错误|默认只进行警告|2.4.28|

0 commit comments

Comments
 (0)