Skip to content

Commit a39806e

Browse files
committed
fix tacgen naming confusion
1 parent 61db51a commit a39806e

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

docs/step2/example.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ def p_unary_expression(p):
130130

131131
这一步就是 `TACGen.transform` 函数(frontend/tacgen/tacgen.py)做的事了, `TACGen.transform` 接受一个AST树输入,输出一个TAC表示,请确保你已经对[Visitor 模式](./visitor.md)有所了解,或者假设你已经知道在遍历 AST 时 accept 函数会对不同类型的 AST Node 调用不同的visit 函数。例如,visit `(children[0]) Return` 时,遇到的子节点是 `(expr) Unary`,那么 `accept` 最终会调用`visitUnary`,你的lint工具应该是没法做到点一下就跳转到对应的位置,所以你需要自己判断我们在遍历某个节点的时候其子节点的类型。
132132

133-
**下面的描述中一定要记得区分accept和直接对于mv.visitXXX的调用,前者是在遍历AST时调用的,后者是在 TACFuncEmitter 类中调用的。并且希望大家一定要对着代码看。**
133+
**下面的描述中一定要记得区分accept和直接对于mv.emitXXX的调用,前者是在遍历AST时调用的,后者是在 TACFuncEmitter 类中调用的。并且希望大家一定要对着代码看。**
134134

135135
```
136136
Program
@@ -154,16 +154,16 @@ def transform(self, program: Program) -> TACProg:
154154
# in step9, you need to use real parameter count
155155
emitter = TACFuncEmitter(FuncLabel(funcName), 0, labelManager)
156156
astFunc.body.accept(self, emitter)
157-
tacFuncs.append(emitter.visitEnd())
157+
tacFuncs.append(emitter.emitEnd())
158158
return TACProg(tacFuncs)
159159
```
160160

161161
现在我们开始正式遍历 AST 树,`transform` 会先遍历每一个函数进行代码翻译,因为我们目前只有一个函数`main`,我们只考虑没有参数的函数,我们需要对函数体进行翻译,函数体首先在一个block中(花括号括起来的部分),因此会先进入 `visitBlock` 函数,`visitBlock` 函数对于在block中的所有子节点调用了`child.accept(self, mv)`,在这个例子中则会调用`Return` 语句对应的visitor,进入`visitReturn`。继续向下,`visitReturn` 又对于 return AST Node 中的 expr 调用了 `stmt.expr.accept(self, mv)` ,又进入了`visitUnary`,同理,`expr.operand.accept(self, mv)`会进入`visitIntLiteral`
162162

163-
到了此处出现了不同,我们发现`visitIntLiteral`中第一次调用了mv的成员函数 `mv.visitLoad(expr.value)` 这里进入了`TACFuncEmitter.visitLoad`
163+
到了此处出现了不同,我们发现`visitIntLiteral`中第一次调用了mv的成员函数 `mv.emitLoad(expr.value)` 这里进入了`TACFuncEmitter.emitLoad`
164164

165165
```python
166-
def visitLoad(self, value: Union[int, str]) -> Temp:
166+
def emitLoad(self, value: Union[int, str]) -> Temp:
167167
temp = self.freshTemp()
168168
self.func.add(LoadImm4(temp, value))
169169
return temp
@@ -204,10 +204,10 @@ def transform(self, prog: TACProg):
204204

205205
我们先忽略`LivenessAnalyzer``Control Flow Graph(CFG)`以及寄存器分配的部分(助教写了一个非常简单暴力的寄存器分配,如果你觉得它不够好,你可以在后面的step换掉它),实际上,我们这里最主要的是指令选择(`selectInstr`),指令选择将中端TAC代码转换为riscv汇编代码,`selectInstr`函数中,我们也采用了visitor模式遍历指令序列, `_T0 = 1` 这句比较直接,我们也能较为容易的想到一个简单的汇编指令对应(`li _T0, 1`),主要讲讲和`_T1 = - _T0``return _T1`翻译过程发生了什么。
206206

207-
先看`visitUnary`函数:
207+
先看`emitUnary`函数:
208208

209209
```python
210-
def visitUnary(self, instr: Unary) -> None:
210+
def emitUnary(self, instr: Unary) -> None:
211211
op = {
212212
TacUnaryOp.NEG: RvUnaryOp.NEG,
213213
# You can add binary operations here.
@@ -218,10 +218,10 @@ def visitUnary(self, instr: Unary) -> None:
218218

219219
**你可以试试,将`RvUnaryOp.NEG`中名字改为`RvUnaryOp.XXX`看看输出的汇编代码会发生什么变化吧。**
220220

221-
再看`visitReturn`函数,我们这里的`return`是一个带返回值函数的`return`
221+
再看`emitReturn`函数,我们这里的`return`是一个带返回值函数的`return`
222222

223223
```python
224-
def visitReturn(self, instr: Return) -> None:
224+
def emitReturn(self, instr: Return) -> None:
225225
if instr.value is not None:
226226
self.seq.append(Riscv.Move(Riscv.A0, instr.value))
227227
else:

0 commit comments

Comments
 (0)