# 2024/01/31 工作日志

### 声明

本项目由STVM改进而来，[STVM地址](https://github.com/CLimber-Rong/stvm)

由于一些原因（详见后记），我不得不先从编译器开始编写。

### 新增history目录

有一些代码，在现阶段可能是废弃的，但是我无法确定将来我会使用到他，我把这些代码整合并放在了history目录里。代码阅读者和用户都不用理会。

### 全面更新依赖库

随着项目的不断开发，依赖库的接口定义也逐渐稳定了下来。

依赖库位于``src/include``中，其中的``template``目录是依赖库的模板（即接口定义），如果你想要移植Stamon，只需要实现``template``目录中定义的接口即可。

为了示范，我将接口用C语言的标准库实现了一遍，并把代码放到``stdc_implemented``中。

如果你所在的平台支持C语言的标准库（具体标准为C89），那么可以直接使用``stdc_implemented``作为依赖库。

### 全面修复以往代码的bug

几乎所有的文件都有了大大小小的改动。

### 开始编写编译器！

词法分析器已经写完了，语法分析器尚且写到了表达式分析的部分。

词法分析器的源码位于``src/compiler/Lexer.cpp``。

``Lexer.cpp``里的代码都被``stamon::c``（``c``指的是compiler）这个命名空间封装了起来。

如果你想要调用``Lexer.cpp``，可以编写以下代码：

```C++
#include"Lexer.cpp"
using namespace stamon::c;
```

**接下来我想讲一讲词法分析器的架构（了解该架构前，你应该要会编译原理）：**

``Token``是基本词法单元类，其成员如下：

* ``Token(int line, int tok_type)``：构造函数，line参数表示该token所在的行号，tok_type表示该token的类型编号（具体请参见``Lexer.cpp``中的``TOKEN_TYPE``）
* ``lineNo``：这是一个整数变量，表示该token所在的行号
* ``type``：返回一个整数，即该token的类型编号

<br>

除``Token``类外，还有``StringToken``、``IdenToken``、``IntToken``、``DoubleToken``。这些都是``Token``的子类，如果一个Token是字面量或者标识符，你需要将其转化成对应的子类才能获取信息。具体请参见``Lexer.cpp``中的相关定义。

<br>

``Lexer``是词法分析器类，其接口如下：

* ``int getLineTok(int line, String text)``：分析一行的token，line是行号，text是文本（不包含换行符）。分析后的token会加入到缓存中。返回解析到的位置，如果返回值是text的长度就说明解析到末尾，即解析成功；否则说明解析失败。
* ``Token* getTok()``：从缓存中读取出（并删除）一个Token。
* ``Token* peek(int index)``：查看第index个Token（但不删除）。

Lexer在分析前，应当先把源码分解成逐行的文本，然后从第一行到最后一行依次调用getLineTok。

具体的用法请参见``Lexer.cpp``和测试样例

### 新增测试用例

新增了词法分析器的测试样例，位于``test_case/lexer/``中。

如果你想要编译运行测试样例，请将测试样例中的``test.cpp``覆盖到``test/test.cpp``当中，然后使用Makefile调试。

### 怎样编译运行测试代码

无论是调试你自己编写的测试代码，抑或是调试测试样例，都至少需要配置好以下工具：

* make（参考版本：GNU Make 3.82.90）
* gcc（参考版本：``gcc (x86_64-posix-seh-rev1, Built by MinGW-Builds project) 13.1.0``或``TDM-GCC 10``等）
* **[可选]** strip（参考版本：GNU strip (GNU Binutils) 2.39）
* **[可选]** upx（参考版本：upx 4.0.2）

**注意：该项目的Makefile是基于win32的，如果你想要移植该项目到别的系统，请尝试修改Makefile。**

**编译该项目时默认依赖库采用``stdc_implemented``，如果你所在的平台不支持C标准库，请自行实现依赖库。**

##### 调试：

你可以在命令行中键入以下指令：

* ``make build``：编译项目，生成一个``test.exe``，即项目可执行文件
* ``make run``：运行项目
* ``make zip``：将项目可执行文件进行压缩 **（该指令需要用到strip和upx）**