diff --git a/CS143体验报告.md b/CS143体验报告.md index 4ac7efc..78664ad 100644 --- a/CS143体验报告.md +++ b/CS143体验报告.md @@ -261,8 +261,21 @@ PA 2-5 正式写编译器。PA2 写词法分析器,首先读一遍 README 和 - 然后是一个叫原型对象(Prototype Object)的东西:COOL 里面新建对象的方法是使用 `Object.copy()`,因此我们需要生成这些供其复制的东西,也就是 prototype object。生成的时候需要正确设置前面的头部,对于属性,三个基本类型有自己的规定,其余类型的属性随意设置。 - 栈和寄存器约定:方法调用参数放在栈上、从左到右依次压栈,`a0` 寄存器里面放 `self` 对象指针。指定了一组 Scratch registers 供 runtime routine 存放临时数据,因此需要调用者保存;还有堆指针和堆界限两个寄存器,完全由 runtime 控制。其他的都可以用。 - Label:生成的代码需要和 runtime 一起变成最后执行的机器码,因此有一些 label 是指定的,就类似于接口一样的东西。有些 label 是 runtime 提供给我们使用的,也有一些需要我们生成供 runtime 使用。有一句话 `There is no need for code that initializes an object of class Bool if the generated code contains definitions of both Bool objects in the static data area.` 没看懂 -- 执行初始化:需要生成一些代码来调用 main 方法。首先通过 Main prototype 生成一个 Main 类的对象并用 `Main_init` 初始化,该初始化方法依次执行 Main 的基类的初始化最后初始化 Main;然后调用 `Main.main`,在 `a0` 里面放上 `Main` 的指针并设置 `ra`;执行结束后,`Main.main` 返回,这里打印出提示信息并终止执行。 +- 执行初始化:Runtime 预定义了一些代码来调用 main 方法。首先通过 Main prototype 生成一个 Main 类的对象并用 `Main_init` 初始化,该初始化方法依次执行 Main 的基类的初始化最后初始化 Main;然后调用 `Main.main`,在 `a0` 里面放上 `Main` 的指针并设置 `ra`;执行结束后,`Main.main` 返回,这里打印出提示信息并终止执行。不过实际上我们并不需要关心这个问题,只需要知道 `main` 会首先被执行、以及 self object 会被默认放在 `a0` 里面。 -#### 读框架 +#### 一些踩坑 -这次的框架代码非常的多,而且写的很抽象,因此讲一讲。其实最好的方法是自己写个测试代码,然后用参考编译器生成出来看一看具体是啥样子的,光看他的 skeleton 是真的要绕半天。 \ No newline at end of file +测评脚本硬编码了一些东西,因此需要进行一些修改以使其能够正常工作。它会调用绝对路径 `/usr/class/cs143/bin/spim`,这个最好就是复制一份到对应的目录;还有一个问题就是它的 `spim` 好像和下发的不一样(简单逆向了一下),因此它的标准输出中 `spim` 的打印信息有一处和我们的 `spim` 不一样:它的 `handler` 打印的是绝对路径,而我的是相对路径。试了好几种方法都没法改,看字符串表发现是硬编码的,因此只能改测试样例的标准输出。默认运行会导致数据被重新解压覆盖,因此需要先单独解压,然后修改,实际测试的时候用不重新解压数据的参数。具体如下: +```bash +# Assume you are in directory `assignments/PA5/` +sudo mkdir -pv /usr/class/cs143 +sudo cp -r ../../bin /usr/class/cs143 +sudo cp -r ../../lib /usr/class/cs143 +perl pa5-grading.pl -v +find ./grading -type f -exec sed -i 's;/usr/class/cs143/cool;..;g' {} + +perl pa5-grading.pl -r +``` + +#### 实现说明 + +这个里面的细节实在是太多了,如果要写清楚 \ No newline at end of file