From 412e81e6617569ac940e786aee6b9df81a1b5d81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9E=BF=E7=9B=B8=E8=8D=A3?= Date: Thu, 27 Jun 2024 17:25:22 +0800 Subject: [PATCH] fix(*): fix some bugs 1. fix the bugs of Makefile 2. update sfn 3. commit the specification of stvc-tac please refer to the work log for details --- CMakeLists.txt | 2 +- Makefile | 4 + README.md | 10 +- demos/demo.stvc | Bin 8839 -> 8877 bytes demos/demo1.stvc | Bin 12744 -> 12792 bytes demos/demo2.stvc | Bin 11073 -> 13163 bytes "doc/STVC-TAC\350\247\204\350\214\203.md" | 224 ++++++++++++++++++ .../20240626.md" | 34 +++ ...00\345\217\221\346\226\207\346\241\243.md" | 3 +- src/Stamon.hpp | 2 +- src/bin-include/math.st | 4 +- src/bin-include/stdio.st | 4 +- src/bin-include/string.st | 2 +- src/bin-include/system.st | 10 +- src/sfn/SFN.cpp | 28 +-- src/vm/AstRunner.cpp | 4 +- 16 files changed, 301 insertions(+), 30 deletions(-) create mode 100644 "doc/STVC-TAC\350\247\204\350\214\203.md" create mode 100644 "doc/\345\267\245\344\275\234\346\227\245\345\277\227/20240626.md" diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f52a8f..b9d9c0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0.0) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -project(Stamon VERSION 2.4.5) +project(Stamon VERSION 2.4.6) set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) diff --git a/Makefile b/Makefile index 4158d35..57bd99b 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,7 @@ debug: bin/stamon.exe release: # 自定义生成可执行文件名(默认为stamon.exe) + xcopy src\bin-include bin\include /s /e /y /i $(COMPILER) src/Main.cpp \ -o bin/stamon.exe \ -O2 \ @@ -60,6 +61,8 @@ release: $(UPX) -9 bin/stamon.exe release_win: + + xcopy src\bin-include bin\include /s /e /y /i $(COMPILER) src/Main.cpp \ -o bin/stamon.exe \ -O2 \ @@ -79,6 +82,7 @@ release_win: release_linux: # 编译Linux版本 + cp -r -T src/bin-include bin/include $(COMPILER) src/Main.cpp \ -o bin/stamon \ -O2 \ diff --git a/README.md b/README.md index ce7e56c..c6edcfd 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,10 @@ + # Stamon2 ![stamon logo](logo/logo.svg) @@ -23,10 +30,11 @@ ## 开发者 * Climber-Rong [Github主页](https://github.com/CLimber-Rong) [Gitee主页](https://gitee.com/QuXiangrong) +* copi143 [Github主页](https://github.com/copi143) ## 致谢 * TheFlySong [Github主页](https://github.com/TheFlySong) * XIAOYI12 [Github主页](https://github.com/XIAOYI1212) * min0911_ [Github主页](https://github.com/min0911Y) -* copi143 [Github主页](https://github.com/copi143) \ No newline at end of file +* 冻橘 [Github主页](https://github.com/MikanAffine) \ No newline at end of file diff --git a/demos/demo.stvc b/demos/demo.stvc index 539a16d14a67ae3512f5ffb645b4c4ce888e87c0..9d379c63f028b09d79690f0a30ecf159e368ffe6 100644 GIT binary patch delta 467 zcmZp7UF*uR`Zkjr0|SHBM2<7{tUv~HaY+$~W+^BwDF!hZxj-aqW*$)BKaj;$EHDPIM`}(^zCw9^QBH~?*Z=?j|H)rFCa^hyu|at92XU3jbC@_b z^N2oSn!G|nW%6EGo5=wZ5sWgE4+^Vqz913F$S6B`BUA9?S}7SuxyiGn)CJ{$h6@5Q z2*?1j?BoZ0`i%0E8zt>0A7ExtWd_SYMkSCXlOM1MOkNzk}7EI#?8i~*wxNY7$VSw=xstZEA73>ekGjz1|Ez$mDW dp(s&Qe6pj0!DKrnmCaKXRx&bbPG%JI005osYncE5 delta 409 zcmZ4M+V0A+`ZiMt0|SHRM2<7{Oh5)RE0AF10x?jH3K<5SJaSsJODYBsCYr=K%3pQY$h`Ks-*6 zVZ0uxIXU?X<@vltIVp-<|NsC0cWv$Z4V&8-8-yqC$ARq(6 zljFGc8RaG~kg=bfE-fG_4-{hqNdf^#9;6;bD@>jsZ9iFEMq~1KX#+-u$rq&6C;Q7R z5L5!np{SoE>&~bQl3tuI%P6RVE8is-Z1$Rbuu!8*xOBp9m JR{(iZ6#y0;TcQ8} diff --git a/demos/demo1.stvc b/demos/demo1.stvc index 92b94e3a514955a106f0894769bfc7a925d991ed..b75578fd21a83dcb70b970d57ee7836515cac0ec 100644 GIT binary patch delta 708 zcmZutOK1~O6wS@A<0qIQNs}~_U!5i~PG%-CHW4XWEVc`wDRd#&5@Jm?piM}|YF6#8 zih`6=aN{DNI}sPNaP7{8f-YQ$2o^V86ciL%P>k=52ugi$-#wgj?tSmx7Yn-!!sGY$ zvo@Qpye_<4aWUZN7;T=Nt?NdI1KQ7TS7V70eTD{>>+MdXxx}%vQ@^@s$py8jj&jOv zbX)c2B8RlhrN0Q5ai!h7Vfig&`8(Z?QNPB?qWd?tI@fPD3{E=#0C#O{>|)aTjJuZP z(9UEB=4ivikdcWKp!TOrwe5ZJckbXdlGOvk)*5L==1B$?ykRiY?1eGz;Z znxz;Dk+c|Nl_D=^M`97h>jN6a@y34=ZzKL_f^lvZ{BWK7c}}tzfX5ZVM_+=5G2<$s zD4W$;|;iHDi~PaX1sAZ|x>k}+dXKirIxIPzc5zPL^)?lEie3W@2xreF~75;`Vj z*~}$}9N3Z10rDj@QxkY1`7u4x!&)W@Z>mZP)(6kPOx>lNHTi|~2GdS3?GQ?t3hrlT zu^krhDKp3T3A~C4xO3zYsnD~R@l2V3XIR2c)=Roo|1BWl)X^=hDI&_sG(PJB%7Yoo zTkm{V{8WH97e`-}*p`b}$tBpPd$}r}YEzh0Lwh!U3@!B@9k;qiG=;hIY{05kp;4>n USM3Mu`9-fXPbIHWiLq0^0NEb2j{pDw delta 680 zcmZuu&ubGw7|o>F{3sQ>bn~O`Y_hAHY|?Bto0=Yq1PbO*P%wv}JqT%9(ppd>O=#^Y z@#H~Et*?K8;HBb0AxQPuQx$sfE`@>@4_>^*i*deC1kr(S=Dm4uzG2?2HXu@E)$*Gr`(V^s2l2pfd)nC%4zgTb$xnH#6Q zw6{BfTFC4jhrfHVA2zWacd^aK5Sv`U`^j~;v${tc;vP4gTIh3 z3eR6>Q4dG)L37z9^1PJeOg8`PnN7GXNuJ(rqQd0VzouvuA;V?X&{Q`fBbYTzoTxUA z%tdUP*F^{%JIQBo6$5jr8mwd)UsF$6b{N1DYfmU9G&L;L^H@z+(9D!^!WHNje3;1G zKGRJcWcHbj#i>;sq^rYlt?W2+hJDNkM>G3P=nHlYw`>{RR02m+Wn^;-b1|1ou)Q7oZ2zGbvmf!IIiVw;jD{i?&K@TJM*yIzUZeHYV0z) Lg}lh;Ff#ueMvtZu diff --git a/demos/demo2.stvc b/demos/demo2.stvc index 599a5bc97ed6ce0ff94850e7b194a17b2ed44064..dee0aa595b30b64a2c40b63da0bbdf92260c4496 100644 GIT binary patch literal 13163 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 diff --git "a/doc/STVC-TAC\350\247\204\350\214\203.md" "b/doc/STVC-TAC\350\247\204\350\214\203.md" new file mode 100644 index 0000000..076b9cf --- /dev/null +++ "b/doc/STVC-TAC\350\247\204\350\214\203.md" @@ -0,0 +1,224 @@ + +# STVC-TAC规范 + +### 前言 + +##### 什么是STVC-TAC? + +``STVC-TAC``(以下简称``STVC``)是一种以三地址码为基础的平面字节码规范。 + +> ``STVC-TAC``区别于``AST-IR``,前者的字节码是线性且平面的,而后者则是递归且树状的。 + +##### 为什么要设计STVC-TAC? + +比起形似AST的``AST-IR``,``STVC``更容易优化,且执行速度相对更快。 + +### STVC文件结构 + +与AST-IR相似的,AST-IR具有: + +1. 魔数(0xABDB) +2. 常量表 +3. 代码 + +之前似乎未曾说明常量表的格式,故接下来详述。 + +### 常量表格式 + +一个常量表由常量表长度(占4字节)和若干个常量组成,其中常量又由常量类型(占1字节)和常量值组成: + +其中常量值有以下类型: + +* 整数类型:占4字节,即数值 +* 单精度浮点类型:占4字节,即数值 +* 双精度浮点类型:占8字节,即数值 +* 字符串类型:占4+l字节,其中前4字节记录字符串长度(即l,长度按字节计),后l字节为字符串值 +* 标识符类型:占4+l字节,其中前4字节记录标识符长度(即l,长度按字节计),后l字节为标识符名 + +将所有涉及到的数据和标识符存入常量表,这样在字节码代码中,若涉及到某数值或标识符,只需指定一个下标,虚拟机就能通过下标在常量表中查找出对应的数值或标识符。这么做极大的减少了冗余数据的存储,减小了程序体积。 + +**注意:按照规定,常量表的第一条常量必须是一个名为``__init__``的标识符** + +### 代码格式 + +##### 标识符 + +标识符有三个种类:用户标识符,临时标识符和内部标识符。 + +用户标识符一般为用户自定义的标识符,其格式与C标识符格式相同。 + +临时标识符则是表达式计算过程当中会用到的标识符,此类标识符的格式为``.XXX``,其中“XXX”通常为数字。 + +内部标识符则是用于匿名类、匿名函数的声明,此类标识符的格式为``#XXX``,其中“XXX”通常为数字 + +##### 声明函数 + +``` +function identifier: arg1 arg2 arg3 ... +...some codes... +end +``` + +其中identifier为函数名。arg1、arg2、arg3等为函数的参数名。“...some codes...”为函数体代码 + +函数内部不能嵌套声明函数或类。 + +##### 声明类 + +``` +class identifier: member1 member2 member3 ... +...some codes... +end +``` + +其中identifier为类名。member1、member2、member3等为类成员名。“...some codes...”为类初始化赋值代码。 + +在初始化类对象时,会先执行初始化赋值代码,再调用构造函数。 + +类内部不能嵌套声明函数或类。 + +##### 三地址语句 + +1. ``x = y op z`` + +将y和z进行运算(运算符为op)之后的值存入x + +2. ``x = y op`` + +将y进行单目运算(运算符为op)之后的值存入x。如果op为``=``,则不做任何运算,这样做能达成“将y直接赋值于x”的效果 + +##### 流程控制语句 + +1. ``goto addr`` + +无条件跳转至相对addr行指令所在处。若addr<0,向上跳转,否则向下跳转。 + +2. ``if condition => addr`` + +如果condition不为``null``或``0``则跳转至第addr行指令所在处。若addr<0,向上跳转,否则向下跳转。 + +3. ``call result function: arg1 arg2 ...`` + +调用function值。参数为arg1、arg2等标识符或值。返回值存入result当中。 + +4. ``return value`` + +返回value值 + +##### 特别的... + +1. ``new object source arg1 arg2 ...`` + +将source标识符作为类,新建对象,构造参数为arg1、arg2等,新建后的对象值存入object标识符 + +1. ``sfn port arg`` + +设置SFN,port为端口号标识符。arg参数标识符。 + +SFN的介绍见``编译器开发文档.md`` + +1. ``list identifier element1 element2...`` + +将element1、element2...作为元素,组合成数列,并存入identifier标识符中s + +4. ``pushscope`` + +压入一个作用域,用于跳转指令 + +5. ``popscope`` + +弹出一个作用域,用于跳转指令 + +6. ``free identifier`` + +如果identifier所存储的是字面量值(如整型),则释放。该指令和C语言的register关键字类似,**是否释放取决于虚拟机状态。**该指令通常用于释放临时标识符。 + +##### 附表 + +双目运算符有以下种类: + +* add:加 +* sub:减 +* mul:乘 +* div:除 +* mod:取余 +* lsh:左移 +* rsh:右移 +* less:小于 +* lequ:小等于 +* big:大于 +* bequ:大等于 +* equ:判等 +* iequ:判不等 +* band:按位与 +* bxor:按位异或 +* bor:按位或 +* land:逻辑与 +* lor:逻辑或 +* member:取成员 +* index:取下标 + +而单目运算符有以下种类: + +* pos:正 +* neg:负 +* cpl:按位取反 +* not:逻辑非 +* arr:组成为数列 + +##### 示例 + +假设有如下代码: + +``` +class c { + def a = func { + return 114; + }; + func f(x) { + return { 2*x+1, 3*x+2 }; + } +} + + +obj = c.new; + +rst = obj.f(obj.a())[0]; +``` + +那么其对应的STVC应为: + +``` +function #1: +return 114 +end + +function #2: x +.1 = 2 mul x +.2 = .1 add 1 +.3 = 3 mul x +.4 = .3 add 2 +list .5 .2 .4 +return .5 +end + +class c: a f +a = #1 +f = #2 +end + +new obj c + +.1 = obj member a +call .2 .1 +.3 = obj member f +call .4 .3: .2 +.5 = .4 index 0 +rst = .5 +``` \ No newline at end of file diff --git "a/doc/\345\267\245\344\275\234\346\227\245\345\277\227/20240626.md" "b/doc/\345\267\245\344\275\234\346\227\245\345\277\227/20240626.md" new file mode 100644 index 0000000..4306274 --- /dev/null +++ "b/doc/\345\267\245\344\275\234\346\227\245\345\277\227/20240626.md" @@ -0,0 +1,34 @@ + +# 2024/06/24 工作日志 + +本次主要修复了Makefile,更新了SFN,并且编写了平面字节码的规范。 + +### 修复Makefile + +考虑到用户可能在编译前不会提前创建``bin``文件夹,并且新建``bin/include``目录。故在Makefile里编写了相应的实现。 + +### 更新了SFN + +本更新来源于[冻橘](https://github.com/MikanAffine)的提议,感谢! + +本次更新将端口号从整型改为了字符串型。这样调用起来更直观,方便。在后续我也可能重构SFN。 + +**注意:本次更新之后的虚拟机可能会和之前的版本所编译出的程序产生不兼容的问题。** + +### 编写了平面字节码的规范 + +见``STVC-TAC规范.md``。 + +### 接下来要做的事 + +1. 支持编译为平面字节码 +2. 编写词法分析的保存功能 +3. 编写AST的O1优化器 +4. 完善标准库 +5. 编写AST的解释器 \ No newline at end of file diff --git "a/doc/\347\274\226\350\257\221\345\231\250\345\274\200\345\217\221\346\226\207\346\241\243.md" "b/doc/\347\274\226\350\257\221\345\231\250\345\274\200\345\217\221\346\226\207\346\241\243.md" index 5c760fd..653d8d0 100644 --- "a/doc/\347\274\226\350\257\221\345\231\250\345\274\200\345\217\221\346\226\207\346\241\243.md" +++ "b/doc/\347\274\226\350\257\221\345\231\250\345\274\200\345\217\221\346\226\207\346\241\243.md" @@ -99,6 +99,7 @@ SFN中的本地库可以由用户自定义,可扩展性高,不过我认为 SFN类的主要接口有: * ``SFN(STMException* e, vm::ObjectManager* objman)``:构造函数,e为异常类,objman为当前运行时的ObjectManager对象。你可以在构造函数里绑定自己的本地库。详细请参见源码。 -* ``void call(int port, datatype::Variable* arg)``:根据端口号调用本地库。 +~~* ``void call(int port, datatype::Variable* arg)``:根据端口号调用本地库。~~ +* ``void call(String port, datatype::Variable* arg)``:根据端口号调用本地库。 > ——摘自``工作日志/20240512.md`` \ No newline at end of file diff --git a/src/Stamon.hpp b/src/Stamon.hpp index e4e2480..53af6b8 100644 --- a/src/Stamon.hpp +++ b/src/Stamon.hpp @@ -55,7 +55,7 @@ namespace stamon { constexpr int STAMON_VER_X = 2; constexpr int STAMON_VER_Y = 4; - constexpr int STAMON_VER_Z = 5; + constexpr int STAMON_VER_Z = 6; class Stamon { template diff --git a/src/bin-include/math.st b/src/bin-include/math.st index 87413b5..b273bdc 100644 --- a/src/bin-include/math.st +++ b/src/bin-include/math.st @@ -35,14 +35,14 @@ func range_ab(a, b) { } func int(s) { - def port = 2; + def port = "int"; def arg = s; sfn port, arg; return arg; } func len(n) { - def port = 4; + def port = "len"; def arg = n; sfn port, arg; return arg; diff --git a/src/bin-include/stdio.st b/src/bin-include/stdio.st index 2294010..7fe01a9 100644 --- a/src/bin-include/stdio.st +++ b/src/bin-include/stdio.st @@ -5,7 +5,7 @@ import math; import string; func puts(s) { - def port = 0; + def port = "puts"; sfn port, s; } @@ -20,7 +20,7 @@ func println(n) { func input() { - def port = 5; + def port = "input"; def arg; sfn port, arg; diff --git a/src/bin-include/string.st b/src/bin-include/string.st index bc75a90..4ca015e 100644 --- a/src/bin-include/string.st +++ b/src/bin-include/string.st @@ -1,7 +1,7 @@ import stddef; func str(s) { - def port = 3; + def port = "str"; def arg = s; sfn port, arg; return arg; diff --git a/src/bin-include/system.st b/src/bin-include/system.st index 1936a8e..0e7d4ad 100644 --- a/src/bin-include/system.st +++ b/src/bin-include/system.st @@ -8,12 +8,12 @@ System = class { def version; func __init__(self) { - self.version = "2.4.5"; //当前版本号 + self.version = "2.4.6"; //当前版本号 } func typeof(self, v) { //返回类型 - def port = 6; + def port = "typeof"; def arg = v; sfn port, arg; return arg; @@ -21,20 +21,20 @@ System = class { func throw(self, s) { //抛出异常,同时让虚拟机退出 - def port = 7; + def port = "throw"; def arg = str(s); sfn port, arg; } func system(self, s) { - def port = 8; + def port = "system"; def arg = str(s); sfn port, arg; return arg; } func exit(self, n) { - def port = 9; + def port = "exit"; def arg = int(n); sfn port, arg; } diff --git a/src/sfn/SFN.cpp b/src/sfn/SFN.cpp index 8e61fcf..7a28e9a 100644 --- a/src/sfn/SFN.cpp +++ b/src/sfn/SFN.cpp @@ -16,6 +16,7 @@ #include"ObjectManager.cpp" #include"DataType.hpp" #include"Exception.hpp" +#include"StringMap.hpp" #define SFN_PARA_LIST \ stamon::sfn::SFN& sfn,\ @@ -48,8 +49,7 @@ void sfn_exit(SFN_PARA_LIST); namespace stamon { namespace sfn { class SFN { - void (*sfn_functions[STAMON_SFN_FUNCTIONS_MAX]) - (SFN_PARA_LIST) = { NULL }; + StringMap sfn_functions; //定义一个函数指针数组 public: STMException* ex; @@ -64,19 +64,19 @@ namespace stamon { manager = objman; //在这里将库函数按接口号填入 - sfn_functions[0] = sfn_puts; - sfn_functions[1] = sfn_printNum; - sfn_functions[2] = sfn_int; - sfn_functions[3] = sfn_str; - sfn_functions[4] = sfn_len; - sfn_functions[5] = sfn_input; - sfn_functions[6] = sfn_typeof; - sfn_functions[7] = sfn_throw; - sfn_functions[8] = sfn_system; - sfn_functions[9] = sfn_exit; + sfn_functions.put(String((char*)"puts"), sfn_puts); + sfn_functions.put(String((char*)"printNum"), sfn_printNum); + sfn_functions.put(String((char*)"int"), sfn_int); + sfn_functions.put(String((char*)"str"), sfn_str); + sfn_functions.put(String((char*)"len"), sfn_len); + sfn_functions.put(String((char*)"input"), sfn_input); + sfn_functions.put(String((char*)"typeof"), sfn_typeof); + sfn_functions.put(String((char*)"throw"), sfn_throw); + sfn_functions.put(String((char*)"system"), sfn_system); + sfn_functions.put(String((char*)"exit"), sfn_exit); } - void call(int port, datatype::Variable* arg) { - sfn_functions[port](*this, arg, manager); + void call(String port, datatype::Variable* arg) { + sfn_functions.get(port)(*this, arg, manager); CATCH { THROW_S( String((char*)"SFN Error: ") diff --git a/src/vm/AstRunner.cpp b/src/vm/AstRunner.cpp index 97212b6..36e7518 100644 --- a/src/vm/AstRunner.cpp +++ b/src/vm/AstRunner.cpp @@ -811,11 +811,11 @@ namespace stamon::vm { Variable* arg_var = manager->GetVariable(arg); CE - CDT(port_var->data, datatype::IntegerType) + CDT(port_var->data, datatype::StringType) sfn.call( ( - (datatype::IntegerType*)port_var->data + (datatype::StringType*)port_var->data ) ->getVal(), arg_var