diff --git a/.gitignore b/.gitignore
index db30932fda5748c0db3fa329c334e61c562cf9b4..278f4e458d09b5b2b03fb6922f0926769a5577b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,6 @@
 *.tar.gz
 target
 *.log
-test/lib/sylib.ll
\ No newline at end of file
+test/lib/sylib.ll
+.VSCodeCounter
+*.pri.*
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index b789f52daca5d2b189ed15cfa00760b812fef0b4..d91d524d00f0104eb7bd28c47a311c1942c333cb 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -5,4 +5,5 @@
   "java.project.sourcePaths": [
     "src/main/java"
   ],
+  "java.format.comments.enabled": false
 }
\ No newline at end of file
diff --git a/docs/bugs.md b/docs/bugs.md
index c1f9ec7a664ca6afd7807fd157e601ca8d2204aa..db0fb84a2204f9ea3b8f0a0edbefc9c824bde338 100644
--- a/docs/bugs.md
+++ b/docs/bugs.md
@@ -3,7 +3,7 @@
 
 src\main\java\dst\AstDeclVisitor.java 在访问visitConstDef时使用的依然是DeclType.VAR,改为了DeclType.CONST。然后出现了下面的bug。
 
-exp 展开成变量时,走的是`PrimaryExp → '(' Exp ')' | LVal | Numbe`,因此即使不是赋值语句也会展开为LVal。如果在语义检查中认为LVal不能引用const变量则会出现问题。
+exp 展开成变量时,走的是`PrimaryExp → '(' Exp ')' | LVal | Number`,因此即使不是赋值语句也会展开为LVal。如果在语义检查中认为LVal不能引用const变量则会出现问题。
 
 ### 坑点
 
diff --git a/script/build.sh b/script/build.sh
index d994cd4bd8fe2364aa973d51d99ae67782187548..fce6d7d71cc552dd5baa67fcbeb3354f428aa95f 100755
--- a/script/build.sh
+++ b/script/build.sh
@@ -1,3 +1,9 @@
+#
+# 此脚本用于构建和打包 compiler.jar
+#
+# 用法:
+# ./script/build.sh 
+#
 BASEDIR=$(realpath $(dirname "$0")/..)
 echo "BASEDIR: $BASEDIR"
 ANTLR_LIB=$BASEDIR/lib/antlr4-4.8-1-complete.jar
diff --git a/script/functional_test.sh b/script/functional_test.sh
index d10e8b50dd64d11a0f7df19bec5f955b0c018b09..bd3594634504eb4f48c31cab487c2e5181e2bc02 100644
--- a/script/functional_test.sh
+++ b/script/functional_test.sh
@@ -1,3 +1,11 @@
+#
+# 此脚本执行所有测试
+#
+# 用法:
+# ./script/functional_test.sh
+#
+
+
 BASEDIR=$(realpath $(dirname "$0")/..)
 RED='\033[0;34m'
 NC='\033[0m' # No Color
diff --git a/script/functional_test_one.sh b/script/functional_test_one.sh
index 0fc5630fea6bbddb48cae46c0404abbb9bc3b188..2252f7b3144b36c9dbc57a1c24115a43c63d5ef1 100644
--- a/script/functional_test_one.sh
+++ b/script/functional_test_one.sh
@@ -1,8 +1,15 @@
+#
+# 此脚本执行一个测试
+#
+# 用法:
+# ./script/functional_test_one.sh SOUCE_FILE OUTPUT_FILE
+#
+
 BASEDIR=$(realpath $(dirname "$0")/..)
 RED='\033[0;34m'
 NC='\033[0m' # No Color
 
-function runone {
+function run_one {
     java -DlogLevel=trace \
         -jar $BASEDIR/target/compiler.jar \
             -S -o $2 \
@@ -19,7 +26,7 @@ set -e; # error exit
 file=$BASEDIR/test/functional/${1}
 name=$(basename $file)
 printf "${RED}--- Compile IR ${file} ---${NC}\n"
-runone $file $BASEDIR/target/test/functional/${name}.ll
+run_one $file $BASEDIR/target/test/functional/${name}.ll
 clang $BASEDIR/test/lib/sylib.ll $BASEDIR/target/test/functional/${name}.ll -o $BASEDIR/target/test/functional/${name}.elf
 printf "${RED}--- Testing IR ${file} ---${NC}\n"
 if [ ! -f $BASEDIR/test/functional/${name%.*}.in ]; then
@@ -28,7 +35,7 @@ else
     python3 $BASEDIR/script/functional_checker.py ir $BASEDIR/target/test/functional/${name}.elf $BASEDIR/test/functional/${name%.*}.out $BASEDIR/test/functional/${name%.*}.in
 fi
 printf "${RED}--- Compile ASM ${file} ---${NC}\n"
-runone $file $BASEDIR/target/test/functional/${name}.S
+run_one $file $BASEDIR/target/test/functional/${name}.S
 arm-linux-gnueabihf-gcc-10 -march=armv7-a -static $BASEDIR/target/test/functional/${name}.S $BASEDIR/test/lib/libsysy.a -o $BASEDIR/target/test/functional/${name}.arm.elf
 printf "${RED}--- Testing ASM ${file} ---${NC}\n"
 if [ ! -f $BASEDIR/test/functional/${name%.*}.in ]; then
diff --git a/script/gen.sh b/script/gen.sh
index 6568900733c56d651be8cd21ba692924e1ed99e3..413146c68daa3d925197003fecf15feffeca8f49 100755
--- a/script/gen.sh
+++ b/script/gen.sh
@@ -1,3 +1,10 @@
+#
+# 此脚本从 g4 文件利用 antlr 生成 lexer 和 parser
+#
+# 用法:
+# ./script/gen.sh
+#
+
 BASEDIR=$(realpath $(dirname "$0")/..)
 echo "BASEDIR: $BASEDIR"
 RED='\033[0;34m'
diff --git a/script/qemu_debug.sh b/script/qemu_debug.sh
index 8b23b5ca44b7162bb386a947b0ccbe5c28d6a86a..8be2fde896cb2b649430c446ec30d678b0d0efdb 100644
--- a/script/qemu_debug.sh
+++ b/script/qemu_debug.sh
@@ -1,2 +1,10 @@
+#
+# 此脚本运行 arm 虚拟机
+#
+# 用法:
+# ./script/functional_test_one.sh FILE
+#
+# -g 参数指定调试端口
+
 #!/bin/bash
 qemu-arm -L /usr/arm-linux-gnueabihf/ -g 12345 $1
\ No newline at end of file
diff --git a/src/main/java/dst/ds/Decl.java b/src/main/java/dst/ds/Decl.java
index 7a978eac09bc51491450b58bd7b38d4f0de61439..e5bd11245998cfd0a6b2964b8bdb5228b04d00ad 100644
--- a/src/main/java/dst/ds/Decl.java
+++ b/src/main/java/dst/ds/Decl.java
@@ -21,7 +21,13 @@ public class Decl extends BlockStatement {
     public List<Expr> dims; // 语义分析后转为List<Integer>存放到Type.dims中
     // public List<Integer> evaledDims;
 
-    // 函数参数为数组省略签名,因为语义分析的时候才填入Type,所以这里也需要一个成员
+    /**
+     * isDimensionOmitted 说明此 Decl,作为一个函数的**参数**,是一个数组,但是没有给出维度信息。
+     * 比如这样的参数:`int arr[]`。那么此处就会 true
+     * 
+     * 默认情况下这里是 false, 也即给了维度表达式,那么一定不是一个函数参数
+     * 函数参数为数组省略签名,因为语义分析的时候才填入Type,所以这里也需要一个成员
+     */
     public boolean isDimensionOmitted = false;
 
     // Right hand side
diff --git a/src/main/java/dst/ds/LValExpr.java b/src/main/java/dst/ds/LValExpr.java
index 01f2d51c8726c9ccf8c34eea9983b1cba1f6ad5b..1cc9fb2e273165a85177146ee7dc169d467f3a3b 100644
--- a/src/main/java/dst/ds/LValExpr.java
+++ b/src/main/java/dst/ds/LValExpr.java
@@ -9,7 +9,10 @@ import ir.ds.Scope;
 
 public class LValExpr extends Expr {
     public String id;
-    public boolean isArray; // 是否有方括号表达式
+    /**
+     * 是否有方括号表达式(即是否是访问数组)
+     */
+    public boolean isArray;
     public List<Expr> indices;
 
     public DeclSymbol declSymbol;
diff --git a/src/main/java/ssa/FakeSSAGenerator.java b/src/main/java/ssa/FakeSSAGenerator.java
index 78e4a0bfd7fa2c3d6a0deb8049ec62f166d94070..4f7d2f54ab59e304ea203bf5edeb1e493e3d1583 100644
--- a/src/main/java/ssa/FakeSSAGenerator.java
+++ b/src/main/java/ssa/FakeSSAGenerator.java
@@ -72,8 +72,13 @@ public class FakeSSAGenerator {
     }
 
     private void visitBuiltinDstFunc(FakeSSAGeneratorContext ctx, dst.ds.Func dstFunc) {
+        // params
         var pvs = new ArrayList<ParamValue>();
-        dstFunc.params.forEach(decl -> {pvs.add(new ParamValue(decl.id, convertDstType(decl.type)));});
+        dstFunc.params.forEach(decl -> {
+            pvs.add(new ParamValue(decl.id, convertDstType(decl.type)));
+        });
+
+        // create ssa func
         Func func = new Func(dstFunc.id, dstFunc.retType, pvs);
         if (dstFunc.isVariadic != null) {
             func.setIsVariadic(dstFunc.isVariadic);
@@ -83,6 +88,12 @@ public class FakeSSAGenerator {
         ctx.funcMap.put(dstFunc, val);
     }
 
+    /**
+     * 用于将 dst Type 转换为 SSA Type
+     * 
+     * @param type
+     * @return
+     */
     private Type convertDstType(dst.ds.Type type) {
         if (type.basicType == BasicType.STRING_LITERAL) {
             // string literal应该不可能是array
@@ -138,7 +149,7 @@ public class FakeSSAGenerator {
             int currentSize = type.dims.get(0);
             // 语义检查后应该initVal的层次结构和type的dims匹配
             assert initVal.values.size() == currentSize;
-            for (int i=0;i<currentSize;i++) {
+            for (int i = 0; i < currentSize; i++) {
                 var v = convertArrayEvaledValue(type.subArrType(), initVal.values.get(i));
                 result.add(v);
             }
@@ -146,10 +157,13 @@ public class FakeSSAGenerator {
         }
     }
 
+    /**
+     * Dst EvaluatedValue 转化为 SSA 常数(组)
+     */
     private static ConstantValue convertEvaledValue(EvaluatedValue evaledVal) {
         if (evaledVal.basicType == BasicType.STRING_LITERAL) { // String转i8数组
             List<ConstantValue> chars = new ArrayList<>();
-            for (byte c: evaledVal.stringValue.getBytes()) {
+            for (byte c : evaledVal.stringValue.getBytes()) {
                 chars.add(ConstantValue.ofChar(c));
             }
             chars.add(ConstantValue.ofChar(0));
@@ -161,13 +175,18 @@ public class FakeSSAGenerator {
             case INT:
                 return ConstantValue.ofInt(evaledVal.intValue);
             default:
-                throw new RuntimeException("Unknown basicType "+evaledVal.basicType.toString());
+                throw new RuntimeException("Unknown basicType " + evaledVal.basicType.toString());
         }
     }
 
     private void visitDstFunc(FakeSSAGeneratorContext ctx, dst.ds.Func dstFunc) {
+        // params
         var pvs = new ArrayList<ParamValue>();
-        dstFunc.params.forEach(decl -> {pvs.add(new ParamValue(decl.id, convertDstType(decl.type)));});
+        dstFunc.params.forEach(decl -> {
+            pvs.add(new ParamValue(decl.id, convertDstType(decl.type)));
+        });
+
+        // create func object
         Func func = new Func(dstFunc.id, dstFunc.retType, pvs);
         if (dstFunc.isVariadic != null) {
             func.setIsVariadic(dstFunc.isVariadic);
@@ -177,18 +196,16 @@ public class FakeSSAGenerator {
         ctx.funcMap.put(dstFunc, val);
         ctx.currentFunc = func;
 
-        // 入口基本块
+        // entry basic block for func
         func.bbs = new LinkedList<>();
         BasicBlock ent = new BasicBlock("entry");
         func.bbs.add(ent);
         ctx.current = ent;
 
-        // 函数参数
-        // dstFunc.params.forEach(param -> visitFuncParamDecl(ctx, ));
-        // dstFunc.params.forEach(param -> {
-        for (int i=0;i<dstFunc.params.size();i++) {
+        // create insts for params and add to current bb
+        for (int i = 0; i < dstFunc.params.size(); i++) {
             var param = dstFunc.params.get(i);
-            var ref = pvs.get(i);
+            ParamValue ref = pvs.get(i);
             ref.name = param.id;
             if (param.isArray()) {
                 // array参数不需要创建alloca指令
@@ -196,22 +213,25 @@ public class FakeSSAGenerator {
             } else {
                 var alloc = new AllocaInst.Builder(ent).addType(convertDstType(param.type)).build();
                 alloc.name = ctx.nameLocal(param.id);
-                ctx.addToCurrent(alloc);
+                ctx.addToCurrentBB(alloc);
                 ctx.varMap.put(param, alloc);
                 var inst = new StoreInst.Builder(ent).addOperand(ref, alloc).build();
-                ctx.addToCurrent(inst);
+                ctx.addToCurrentBB(inst);
             }
         }
-        // });
 
-        
-        dstFunc.body.statements.forEach(bs -> {visitDstStmt(ctx, func, bs);});
+        // 生成函数体的 insts
+        dstFunc.body.statements.forEach(bs -> {
+            visitDstStmt(ctx, func, bs);
+        });
         // 指令生成是线性模型,比如int f(){if(){..} else {...}}我也需要在末尾加上一个基本块,保证是和if else同级的,
         // 如果最后一个基本块最后不是返回指令,加上返回指令。
         var current = ctx.current;
-        // 如果基本块没有用TerminatorInst结尾,加入RetInst
-        if (current.insts.size() == 0 || !(current.insts.get(current.insts.size()-1) instanceof TerminatorInst)) {
-            var b  = new RetInst.Builder(current);
+
+        // 如果基本块没有用 TerminatorInst 结尾,加入 RetInst
+        if (current.insts.size() == 0 || !(current.insts.get(current.insts.size() - 1) instanceof TerminatorInst)) {
+            var b = new RetInst.Builder(current);
+            // 自动生成返回值
             if (func.retType == FuncType.VOID) {
                 b.addType(Type.Void);
             } else if (func.retType == FuncType.INT) {
@@ -226,18 +246,19 @@ public class FakeSSAGenerator {
             current.insts.add(b.build());
         }
         // 如果基本块以非RetInst结尾,报错。
-        if (!(current.insts.get(current.insts.size()-1) instanceof RetInst)) {
+        if (!(current.insts.get(current.insts.size() - 1) instanceof RetInst)) {
             throw new RuntimeException("Function " + dstFunc.id + ": generated code not end with return.");
         }
     }
 
+    // 生成表达式的 SSA IR
     private void visitDstStmt(FakeSSAGeneratorContext ctx, Func curFunc, BlockStatement stmt_) {
         if (stmt_ instanceof AssignStatement) {
             var stmt = (AssignStatement) stmt_;
-             // 在assign左边的LVal一般直接是值
+            // 在assign左边的LVal一般直接是值
             var left = visitLValExpr(ctx, curFunc, stmt.left, true); // 获取代表的地址
             var right = visitDstExpr(ctx, curFunc, stmt.expr);
-            ctx.addToCurrent(new StoreInst.Builder(ctx.current).addOperand(right, left).build());
+            ctx.addToCurrentBB(new StoreInst.Builder(ctx.current).addOperand(right, left).build());
             return;
         }
 
@@ -249,14 +270,14 @@ public class FakeSSAGenerator {
 
         if (stmt_ instanceof BreakStatement) {
             var stmt = (BreakStatement) stmt_;
-            var inst = ctx.addToCurrent(new JumpInst(ctx.current, ctx.breakMap.get(stmt.loop)));
+            var inst = ctx.addToCurrentBB(new JumpInst(ctx.current, ctx.breakMap.get(stmt.loop)));
             inst.comments = "break";
             return;
         }
 
         if (stmt_ instanceof ContinueStatement) {
             var stmt = (ContinueStatement) stmt_;
-            var inst = ctx.addToCurrent(new JumpInst(ctx.current, ctx.continueMap.get(stmt.loop)));
+            var inst = ctx.addToCurrentBB(new JumpInst(ctx.current, ctx.continueMap.get(stmt.loop)));
             inst.comments = "continue";
             return;
         }
@@ -275,27 +296,28 @@ public class FakeSSAGenerator {
 
         if (stmt_ instanceof IfElseStatement) {
             var stmt = (IfElseStatement) stmt_;
-            int ind = ctx.getBBInd();
-            var trueBlock = new BasicBlock("if_true_"+ind);
-            var exitBlock = new BasicBlock("if_end_"+ind);
+            int ind = ctx.nextBBIdx();
+            var trueBlock = new BasicBlock("if_true_" + ind);
+            var exitBlock = new BasicBlock("if_end_" + ind);
             var falseBlock = exitBlock;
             if (stmt.elseBlock != null) {
-                falseBlock = new BasicBlock("if_false_"+ind);
+                falseBlock = new BasicBlock("if_false_" + ind);
             }
             // var cond = this.visitDstExpr(ctx, curFunc, stmt.condition);
-            // ctx.addToCurrent(new BranchInst(ctx.current, cond, trueBlock.getValue(), falseBlock.getValue()));
+            // ctx.addToCurrent(new BranchInst(ctx.current, cond, trueBlock.getValue(),
+            // falseBlock.getValue()));
             visitCondExprs(ctx, curFunc, stmt.condition.expr, trueBlock.getValue(), falseBlock.getValue());
 
             // 在true block生成指令
             ctx.current = trueBlock;
             curFunc.bbs.add(trueBlock);
             this.visitDstStmt(ctx, curFunc, stmt.thenBlock);
-            ctx.addToCurrent(new JumpInst(ctx.current, exitBlock.getValue()));
+            ctx.addToCurrentBB(new JumpInst(ctx.current, exitBlock.getValue()));
             if (stmt.elseBlock != null) {
                 ctx.current = falseBlock;
                 curFunc.bbs.add(falseBlock);
                 this.visitDstStmt(ctx, curFunc, stmt.elseBlock);
-                ctx.addToCurrent(new JumpInst(ctx.current, exitBlock.getValue()));
+                ctx.addToCurrentBB(new JumpInst(ctx.current, exitBlock.getValue()));
             }
             ctx.current = exitBlock;
             curFunc.bbs.add(exitBlock);
@@ -303,27 +325,43 @@ public class FakeSSAGenerator {
         }
 
         if (stmt_ instanceof LoopStatement) {
-            var stmt = (LoopStatement) stmt_;
+            /*
+             * <while_entry>  <--\
+             * while (cond) {     |
+             * <while_body>       |
+             *     block---------/
+             * }
+             * <while_end>:
+             */
+            var loopStmt = (LoopStatement) stmt_;
             // 由于要跳转到expr计算的前面,这里要分割一个基本块
-            int ind = ctx.getBBInd();
-            var entBlock = new BasicBlock("while_entry_"+ind);
-            ctx.addToCurrent(new JumpInst(ctx.current, entBlock.getValue()));
-            ctx.current = entBlock;
-            curFunc.bbs.add(entBlock);
-            var bodyBlock = new BasicBlock("while_body_"+ind);
-            var exitBlock = new BasicBlock("while_end_"+ind);
+            int bbid = ctx.nextBBIdx();
+            var entBlock = new BasicBlock("while_entry_" + bbid);
+            {
+                ctx.addToCurrentBB(new JumpInst(ctx.current, entBlock.getValue()));
+                ctx.current = entBlock;
+                curFunc.bbs.add(entBlock);
+            }
+            var bodyBlock = new BasicBlock("while_body_" + bbid);
+            var exitBlock = new BasicBlock("while_end_" + bbid);
             // var cond = this.visitDstExpr(ctx, curFunc, stmt.condition);
-            // ctx.addToCurrent(new BranchInst(ctx.current, cond, bodyBlock.getValue(), exitBlock.getValue()));
-            visitCondExprs(ctx, curFunc, stmt.condition.expr, bodyBlock.getValue(), exitBlock.getValue());
+            // cx.addToCurrent(new BranchInst(ctx.current, cond, bodyBlock.getValue(),
+            // exitBlock.getValue()));
 
-            // set continue and brek map;
-            ctx.breakMap.put(stmt, exitBlock.getValue());
-            ctx.continueMap.put(stmt, entBlock.getValue());
+            // 生成循环条件指令并关联条件跳转目标
+            visitCondExprs(ctx, curFunc, loopStmt.condition.expr, bodyBlock.getValue(), exitBlock.getValue());
+
+            // 设置本循环语句的 continue 和 break 语句的跳转目标
+            ctx.breakMap.put(loopStmt, exitBlock.getValue());
+            ctx.continueMap.put(loopStmt, entBlock.getValue());
 
             ctx.current = bodyBlock;
             curFunc.bbs.add(bodyBlock);
-            this.visitDstStmt(ctx, curFunc, stmt.bodyBlock);
-            ctx.addToCurrent(new JumpInst(ctx.current, entBlock.getValue()));
+
+            // 生成循环体的指令
+            this.visitDstStmt(ctx, curFunc, loopStmt.bodyBlock);
+            // 循环体末尾跳转到 <while_entry>
+            ctx.addToCurrentBB(new JumpInst(ctx.current, entBlock.getValue()));
 
             ctx.current = exitBlock;
             curFunc.bbs.add(exitBlock);
@@ -335,14 +373,23 @@ public class FakeSSAGenerator {
             var val = visitDstExpr(ctx, curFunc, stmt.retval);
             var b = new RetInst.Builder(ctx.current);
             b.addType(curFunc.getRetType());
+            // 若有返回值
             if (curFunc.retType != FuncType.VOID) {
                 b.addOperand(val);
             }
-            ctx.addToCurrent(b.build());
+            ctx.addToCurrentBB(b.build());
             return;
         }
     }
 
+    /**
+     * 处理各种各样类型的表达式 SSA 生成
+     * 
+     * @param ctx
+     * @param curFunc
+     * @param expr_
+     * @return
+     */
     private Value visitDstExpr(FakeSSAGeneratorContext ctx, Func curFunc, Expr expr_) {
         if (expr_ instanceof CastExpr) {
             var expr = (CastExpr) expr_;
@@ -355,7 +402,7 @@ public class FakeSSAGenerator {
             }
             var cast = new CastInst.Builder(ctx.current, val).addOp(op).build();
             cast.comments = expr.reason;
-            ctx.addToCurrent(cast);
+            ctx.addToCurrentBB(cast);
             return cast;
         }
 
@@ -367,13 +414,17 @@ public class FakeSSAGenerator {
             if (expr.op.isBoolean()) {
                 if (!l.type.equals(r.type)) { // 检查两边类型,一边i1一边非i1时,需要cast到i1。
                     if (l.type.equals(Type.Boolean)) {
-                        r = ctx.addToCurrent(new BinopInst(ctx.current, BinaryOp.LOG_NEQ, ConstantValue.getDefault(r.type), r));
+                        r = ctx.addToCurrentBB(
+                                new BinopInst(ctx.current, BinaryOp.LOG_NEQ, ConstantValue.getDefault(r.type), r));
                     } else if (r.type.equals(Type.Boolean)) {
-                        l = ctx.addToCurrent(new BinopInst(ctx.current, BinaryOp.LOG_NEQ, ConstantValue.getDefault(l.type), l));
-                    } else {throw new RuntimeException("Wrong type for BinaryExpr "+expr.op.toString());}
+                        l = ctx.addToCurrentBB(
+                                new BinopInst(ctx.current, BinaryOp.LOG_NEQ, ConstantValue.getDefault(l.type), l));
+                    } else {
+                        throw new RuntimeException("Wrong type for BinaryExpr " + expr.op.toString());
+                    }
                 }
             }
-            var ret = ctx.addToCurrent(new BinopInst(ctx.current, expr.op, l, r));
+            var ret = ctx.addToCurrentBB(new BinopInst(ctx.current, expr.op, l, r));
             return ret;
         }
 
@@ -382,18 +433,18 @@ public class FakeSSAGenerator {
             var fv = (FuncValue) ctx.funcMap.get(expr.funcSymbol.func);
             var cb = new CallInst.Builder(ctx.current, fv);
             if (expr.args != null) {
-                for(int i=0;i<expr.args.length;i++) {
+                for (int i = 0; i < expr.args.length; i++) {
                     // 考虑数组传一部分的情况?
                     var val = visitDstExpr(ctx, curFunc, expr.args[i]);
                     // Float需要提升到Double再传入vararg?
                     if ((i >= expr.funcSymbol.func.params.size()) && val.type.equals(Type.Float)) {
                         assert expr.funcSymbol.func.isVariadic;
-                        val = ctx.addToCurrent(new CastInst.Builder(ctx.current, val).f2d().build());
+                        val = ctx.addToCurrentBB(new CastInst.Builder(ctx.current, val).f2d().build());
                     }
                     cb.addArg(val);
                 }
             }
-            return ctx.addToCurrent(cb.build());
+            return ctx.addToCurrentBB(cb.build());
         }
 
         if (expr_ instanceof LiteralExpr) {
@@ -401,11 +452,11 @@ public class FakeSSAGenerator {
             var constant = convertEvaledValue(expr.value);
             if (expr.value.basicType == BasicType.STRING_LITERAL) {
                 // 字符串放到全局变量里,然后返回i8*
-                var gv = new GlobalVariable(".str."+ctx.getStrInd(), constant.type.clone());
+                var gv = new GlobalVariable(".str." + ctx.nextStrIdx(), constant.type.clone());
                 gv.init = constant;
                 ctx.module.globs.add(gv);
                 // LLVM 是用 get element ptr 获取起始i8* 地址,我这里直接bitcast应该也行
-                return ctx.addToCurrent(new CastInst.Builder(ctx.current, gv).strBitCast(gv.type).build());
+                return ctx.addToCurrentBB(new CastInst.Builder(ctx.current, gv).strBitCast(gv.type).build());
             }
             return constant;
         }
@@ -422,15 +473,17 @@ public class FakeSSAGenerator {
                 return visitDstExpr(ctx, curFunc, expr.expr);
             } else if (expr.op == UnaryOp.NEG) {
                 var val = visitDstExpr(ctx, curFunc, expr.expr);
-                return ctx.addToCurrent(new BinopInst(ctx.current, BinaryOp.SUB, ConstantValue.getDefault(val.type), val));
+                return ctx.addToCurrentBB(
+                        new BinopInst(ctx.current, BinaryOp.SUB, ConstantValue.getDefault(val.type), val));
             } else if (expr.op == UnaryOp.NOT) {
                 var val = visitDstExpr(ctx, curFunc, expr.expr);
-                return ctx.addToCurrent(new BinopInst(ctx.current, BinaryOp.LOG_EQ, ConstantValue.getDefault(val.type), val));
-            }  else {
+                return ctx.addToCurrentBB(
+                        new BinopInst(ctx.current, BinaryOp.LOG_EQ, ConstantValue.getDefault(val.type), val));
+            } else {
                 throw new RuntimeException("Unknown UnaryOp type.");
             }
         }
-        
+
         if (expr_ instanceof NonShortLogicExpr) { // 说明要cast到i1类型了
             var expr = (NonShortLogicExpr) expr_;
             var val = visitDstExpr(ctx, curFunc, expr.expr);
@@ -438,7 +491,8 @@ public class FakeSSAGenerator {
                 return val; // 是逻辑表达式
             }
             // cast val to i1; (x) -> (x ne 0)
-            return ctx.addToCurrent(new BinopInst(ctx.current, BinaryOp.LOG_NEQ, ConstantValue.getDefault(val.type), val));
+            return ctx.addToCurrentBB(
+                    new BinopInst(ctx.current, BinaryOp.LOG_NEQ, ConstantValue.getDefault(val.type), val));
         }
 
         if (expr_ instanceof LogicExpr) {
@@ -454,6 +508,15 @@ public class FakeSSAGenerator {
 
     /**
      * 处理LVal中取数组下标的情况
+     * 
+     * 由于存在语义规则
+     * primaryExpr
+     * : '(' expr ')' #primaryExprQuote
+     * | lVal #primaryExprLVal
+     * | number #primaryExprNumber
+     * ;
+     * 会导致 LVal 不一定真的是左值,有可能只是一个能作为左值但不是左值的表达式。因此 toAssign 参数表明是否真的是左值(真的被赋值)
+     * 
      * @param ctx
      * @param curFunc
      * @param expr
@@ -461,40 +524,44 @@ public class FakeSSAGenerator {
      * @return
      */
     private Value visitLValExpr(FakeSSAGeneratorContext ctx, Func curFunc, LValExpr expr, boolean toAssign) {
+        // 取出 expr 对应的符号
         Value val;
         if (expr.declSymbol.decl.isGlobal) {
             val = ctx.globVarMap.get(expr.declSymbol.decl);
-        } else  {
+        } else {
             val = ctx.varMap.get(expr.declSymbol.decl);
         }
 
-        if (!expr.isArray) { // 不需要处理数组访问
+        // 如果没有数组访问表达式(方括号,下标访问)
+        if (!expr.isArray) {
+            // 进一步判断是否数组类型
             if (expr.declSymbol.decl.isArray()) { // 没有取下标,但是是数组
                 // 数组要么是alloca,要么是全局变量,要么是函数参数,这两种情况都直接是地址
-                assert toAssign == false;
-                // 忘记数组第一维
+                assert toAssign == false;// 也就是说,数组名称不可能直接被赋值
+                // 如果给了维度信息,忘记数组第一维
                 if (!(expr.declSymbol.decl.isDimensionOmitted)) {
                     assert !(val instanceof ParamValue);
                     var gep = new GetElementPtr(ctx.current, val);
                     gep.comments = "forget first dim";
-                    ctx.addToCurrent(gep);
+                    ctx.addToCurrentBB(gep);
                     gep.addIndex(ConstantValue.ofInt(0));
                     return gep;
                 }
                 assert val instanceof ParamValue;
                 return val;
             } else { // 不需要处理数组访问也不是数组
+
                 if (expr.declSymbol.decl.isConst()) { // 最简单情况,直接找到ConstantValue返回
                     assert toAssign == false;
                     return val;
-                } else {
-                    if (toAssign) {
-                        return val;
-                    } else {
-                        // 生成load语句
-                        return ctx.addToCurrent(new LoadInst(ctx.current, val));
-                    }
                 }
+                // 赋值语句,直接返回 decl
+                if (toAssign) {
+                    return val;
+                }
+                // 非 toAssign,则是访问右值,因此生成 load 语句
+                return ctx.addToCurrentBB(new LoadInst(ctx.current, val));
+
             }
         } else { // 是数组,同时也有取下标运算
             // 担心常量数组可能传函数参数,所以就当普通数组处理了。
@@ -504,13 +571,13 @@ public class FakeSSAGenerator {
                 var val_ = visitDstExpr(ctx, curFunc, exp);
                 gep.addIndex(val_);
             });
-            ctx.addToCurrent(gep);
+            ctx.addToCurrentBB(gep);
             if (gep.type.isArray()) { // index没有取到底
                 assert toAssign == false;
                 // 一般是函数调用出现,因此要再省略一维下标
                 var gep2 = new GetElementPtr(ctx.current, gep);
                 gep2.comments = "forget one dim";
-                ctx.addToCurrent(gep2);
+                ctx.addToCurrentBB(gep2);
                 // 非ParamValue自动加一个0
                 gep2.addIndex(ConstantValue.ofInt(0));
                 return gep2;
@@ -519,9 +586,9 @@ public class FakeSSAGenerator {
                 if (toAssign) {
                     return gep;
                 } else {
-                    return ctx.addToCurrent(new LoadInst(ctx.current, gep));
+                    return ctx.addToCurrentBB(new LoadInst(ctx.current, gep));
                 }
-            }            
+            }
         }
     }
 
@@ -534,91 +601,103 @@ public class FakeSSAGenerator {
             return;
         }
         // 生成alloca语句,即使是array也能一个指令解决
-        var alloc = new AllocaInst.Builder(ctx.current).addType(convertDstType(decl.type)).build();
-        ctx.addToCurrent(alloc);
-        alloc.name = ctx.nameLocal(decl.id);
-        ctx.varMap.put(decl, alloc);
+        var alloca = new AllocaInst.Builder(ctx.current).addType(convertDstType(decl.type)).build();
+        ctx.addToCurrentBB(alloca);
+        alloca.name = ctx.nameLocal(decl.id);
+        ctx.varMap.put(decl, alloca);
+
         // 处理非Const普通变量的初始值,可能是复杂表达式。
         // 语义分析没有计算evaledVal
-        if(decl.initVal != null) {
+        if (decl.initVal != null) {
             if (!decl.type.isArray) {
-                var cv = visitDstExpr(ctx, curFunc, decl.initVal.value);
-                var inst = new StoreInst.Builder(ctx.current).addOperand(cv, alloc).build();
-                ctx.addToCurrent(inst);
+                var val = visitDstExpr(ctx, curFunc, decl.initVal.value);
+                var inst = new StoreInst.Builder(ctx.current).addOperand(val, alloca).build();
+                ctx.addToCurrentBB(inst);
             } else {
                 // TODO array memset to 0 and getelementptr and set content.
-                setArrayInitialVal(ctx, curFunc, alloc, decl.initVal, decl.type.dims);
+                setArrayInitialVal(ctx, curFunc, alloca, decl.initVal, decl.type.dims);
             }
         }
     }
 
     /**
+     * 处理条件跳转表达式。
      * 递归处理and和or的短路求值
+     * 
      * @param ctx
      * @param curFunc
      * @param inLogic expr in LogicExpr (normally `stmt.condition.expr`)
-     * @param t
-     * @param f
+     * @param trueBlock 条件为真时跳转到的 bb
+     * @param falseBlock
      */
-    private void visitCondExprs(FakeSSAGeneratorContext ctx, ssa.ds.Func curFunc, Expr inLogic, BasicBlockValue t, BasicBlockValue f) {
-        if (inLogic instanceof BinaryExpr && ((BinaryExpr)inLogic).op.isShortCircuit()) { // logic and/or
+    private void visitCondExprs(FakeSSAGeneratorContext ctx, ssa.ds.Func curFunc, Expr inLogic, BasicBlockValue trueBlock,
+            BasicBlockValue falseBlock) {
+        // 如果是可以短路求值的二元表达式
+        if (inLogic instanceof BinaryExpr && ((BinaryExpr) inLogic).op.isShortCircuit()) { // logic and/or
             BinaryExpr expr = (BinaryExpr) inLogic;
             // 如果是and,true跳转到右边,false跳转到f。
             // 如果是or,true跳转到t,false跳转到右边。
             // 继续在右边递归生成。
-            int ind = ctx.getBBInd();
+            int bbid = ctx.nextBBIdx();
             BasicBlock next;
             if (expr.op == BinaryOp.LOG_AND) {
-                next = new BasicBlock("and_right_"+ind);
-                visitCondExprs(ctx, curFunc, expr.left, next.getValue(), f);
+                next = new BasicBlock("and_right_" + bbid);
+                visitCondExprs(ctx, curFunc, expr.left, next.getValue(), falseBlock);
             } else {
                 assert expr.op == BinaryOp.LOG_OR;
-                next = new BasicBlock("or_right_"+ind);
-                visitCondExprs(ctx, curFunc, expr.left, t, next.getValue());
+                next = new BasicBlock("or_right_" + bbid);
+                visitCondExprs(ctx, curFunc, expr.left, trueBlock, next.getValue());
             }
             ctx.current = next;
             curFunc.bbs.add(next);
-            visitCondExprs(ctx, curFunc, expr.right, t, f);
-        } else { // 正常生成,通过NonShortLogicExpr已经确保是i1类型
+            visitCondExprs(ctx, curFunc, expr.right, trueBlock, falseBlock);
+        } else { // 正常生成,通过 NonShortLogicExpr 已经确保是 i1 类型
             var cond = this.visitDstExpr(ctx, curFunc, inLogic);
-            ctx.addToCurrent(new BranchInst(ctx.current, cond, t, f));
+            ctx.addToCurrentBB(new BranchInst(ctx.current, cond, trueBlock, falseBlock));
         }
     }
 
-    void setArrayInitialVal(FakeSSAGeneratorContext ctx, ssa.ds.Func curFunc, Value ptr, InitValue initValue, List<Integer> dims) {
+    void setArrayInitialVal(FakeSSAGeneratorContext ctx, ssa.ds.Func curFunc, Value ptr, InitValue initValue,
+            List<Integer> dims) {
         if (initValue.isAllZero) { // 为了第一次调用时检查。
             return;
         }
 
         assert initValue.isArray;
+        // 处理多维度
         if (dims.size() > 1) {
             int currentSize = dims.get(0);
             dims = dims.subList(1, dims.size());
-            for (int i=0;i<currentSize;i++) {
+            for (int i = 0; i < currentSize; i++) {
                 var iv = initValue.values.get(i);
                 if (!iv.isAllZero) {
                     // 生成Gep
                     var ptr_ = new GetElementPtr(ctx.current, ptr);
                     ptr_.addIndex(ConstantValue.ofInt(i));
-                    ctx.addToCurrent(ptr_);
+                    ctx.addToCurrentBB(ptr_);
                     // 递归调用
                     setArrayInitialVal(ctx, curFunc, ptr_, iv, dims);
                 }
             }
         } else {
-            int currentSize = dims.get(0);
-            for (int i=0;i<currentSize;i++) {
-                var iv = initValue.values.get(i);
-                assert !iv.isArray;
-                // 如果iv不是默认值则生成gep和store? TODO
-                if (iv.value instanceof LiteralExpr && ((LiteralExpr)(iv.value)).value.isDefault()) {
+            int dim = dims.get(0);
+            // 逐个维度进行初始化
+            for (int i = 0; i < dim; i++) {
+                var initval = initValue.values.get(i);
+                assert !initval.isArray;
+                // 如果iv不是默认值则生成gep和store?
+                if (initval.value instanceof LiteralExpr && ((LiteralExpr) (initval.value)).value.isDefault()) {
+                    // TODO
                 } else {
+                    // 计算地址
                     var ptr_ = new GetElementPtr(ctx.current, ptr);
                     ptr_.addIndex(ConstantValue.ofInt(i));
-                    ctx.addToCurrent(ptr_);
-                    var val = visitDstExpr(ctx, curFunc, iv.value);
+                    ctx.addToCurrentBB(ptr_);
+                    // 根据初始化值表达式生成初始化指令
+                    var val = visitDstExpr(ctx, curFunc, initval.value);
+                    // 然后把初始化的结果写入到 gep 指令算出的地址那里
                     var inst = new StoreInst.Builder(ctx.current).addOperand(val, ptr_).build();
-                    ctx.addToCurrent(inst);
+                    ctx.addToCurrentBB(inst);
                 }
             }
         }
diff --git a/src/main/java/ssa/FakeSSAGeneratorContext.java b/src/main/java/ssa/FakeSSAGeneratorContext.java
index 443bae39ae2fc45492f91216d00a7aa43f78fa23..a194486d4da807dac68354bd37b7f5f013f12ffd 100644
--- a/src/main/java/ssa/FakeSSAGeneratorContext.java
+++ b/src/main/java/ssa/FakeSSAGeneratorContext.java
@@ -14,14 +14,18 @@ import ssa.ds.Value;
 
 public class FakeSSAGeneratorContext {
     public Module module;
+
     // 由于引用关系已经被语义分析填好了,所以不需要区分作用域。不同函数肯定是不同的Decl
     // 等效于Func和Decl中多了一个Value成员。
     // map from dst to created ssa value  (key compared by instance)
+
+    // 从 dst decl 到 alloca 指令的映射,或者常量到 ConstantValue 的映射等等
     public Map<dst.ds.Decl, Value> varMap;
-    public Map<dst.ds.Func, Value> funcMap;
+    public Map<dst.ds.Func, Value> funcMap; // including builtin funcs
     // 全局变量由于直接取的是地址,所以单独分开
     public Map<dst.ds.Decl, Value> globVarMap;
-    // 等效于LoopStatement多了一个Value成员,保存break和Continue需要的BasicBlockValue
+    // 等效于 LoopStatement 多了一个 Value 成员,保存 break 和 Continue 需要的 BasicBlockValue
+    // 通过此表查询某个 LoopStatement break 或 continue 后跳到哪儿
     public Map<LoopStatement, BasicBlockValue> breakMap;
     public Map<LoopStatement, BasicBlockValue> continueMap;
 
@@ -37,11 +41,13 @@ public class FakeSSAGeneratorContext {
         breakMap = new HashMap<>();
         continueMap = new HashMap<>();
     }
-
-    public Instruction addToCurrent(Instruction i) {
+    /**
+     * 将指令追加到当前上下文的基本块
+     */
+    public Instruction addToCurrentBB(Instruction i) {
         if (i instanceof TerminatorInst && current.hasTerminator()) {
             // 只能生成到一个新的空基本块了
-            var newBB = new BasicBlock("tmp_"+getBBInd());
+            var newBB = new BasicBlock("tmp_"+nextBBIdx());
             currentFunc.bbs.add(newBB);
             newBB.insts.add(i);
             current = newBB;
@@ -51,26 +57,31 @@ public class FakeSSAGeneratorContext {
         }
     }
 
+    /**
+     * 以下函数生成新的数字编号
+     */
+
     int strInd = 0;
-    public int getStrInd() {
+    public int nextStrIdx() {
         return strInd++;
     }
 
     int BBInd = 0;
-    public int getBBInd() {
+    public int nextBBIdx() {
         return BBInd++;
     }
 
     int varInd = 0;
-    public int getVarInd() {
+    public int nextVarIdx() {
         return varInd++;
     }
 
+    // 根据标识符 id 生成一个名字,以一个不冲突的数字为后缀
     public String nameLocal(String id) {
         if (id.length() > 10) {
             id = id.substring(0,10);
         }
-        return id+"_"+getVarInd();
+        return id+"_"+nextVarIdx();
     }
 
 }
diff --git a/src/main/java/ssa/NumValueNamer.java b/src/main/java/ssa/NumValueNamer.java
index 6e45b5142f9adf2498951e974c17f3a39cb47957..6874857766b2e5f85abe7767bcb6b60b0e24df8f 100644
--- a/src/main/java/ssa/NumValueNamer.java
+++ b/src/main/java/ssa/NumValueNamer.java
@@ -8,8 +8,12 @@ import ssa.ds.Module;
 import ssa.ds.Type;
 import ssa.ds.Value;
 
-// basicBlock的label还是生成的时候去命名,在ctx里放个index防止重名
-// 全局变量和函数参数也应当在生成时命名。语法里好像函数参数的名字不能省略。
+/**
+ * NumValueNamer 包含一个计数器状态变量,用于给所有的 Value 提供一个唯一的临时名称 
+ * 
+ * basicBlock的label还是生成的时候去命名,在ctx里放个index防止重名
+ * 全局变量和函数参数也应当在生成时命名。语法里好像函数参数的名字不能省略。
+ */
 public class NumValueNamer {
     long count = 0;
 
diff --git a/src/main/java/ssa/ds/AllocaInst.java b/src/main/java/ssa/ds/AllocaInst.java
index 5db34c44b0804a6da1e06ba4ad97f80de71359ec..0ffeaa8c84f2bafdec85f898d769138042cdcab6 100644
--- a/src/main/java/ssa/ds/AllocaInst.java
+++ b/src/main/java/ssa/ds/AllocaInst.java
@@ -1,5 +1,7 @@
 package ssa.ds;
-
+/**
+ * Alloca 指令用于在栈中分配内存
+ */
 public class AllocaInst extends Instruction {
     public Type ty;
     public long numElement = 1;
diff --git a/src/main/java/ssa/ds/BasicBlock.java b/src/main/java/ssa/ds/BasicBlock.java
index 5e863d5cab7c9615fb4a47c942028f72649c715d..805e7c4cc38606f908a9c148b1732b3e38c00322 100644
--- a/src/main/java/ssa/ds/BasicBlock.java
+++ b/src/main/java/ssa/ds/BasicBlock.java
@@ -19,6 +19,10 @@ public class BasicBlock {
         return val;
     }
 
+    /**
+     * 判断基本块是否应该终止。例如最后一个指令是 TerminatorInst
+     * @return 如果应该终止,返回 true,否则返回 false
+     */
     public boolean hasTerminator() {
         if (insts.size() == 0 || !(insts.get(insts.size()-1) instanceof TerminatorInst)) {
             return false;
@@ -26,6 +30,11 @@ public class BasicBlock {
         return true;
     }
 
+    /**
+     * 将一个指令插入到基本块末尾的终结指令**前**。
+     * @param i
+     * @return
+     */
     public Instruction addBeforeTerminator(Instruction i) {
         if (insts.size() == 0 || !(insts.get(insts.size()-1) instanceof TerminatorInst)) {
             insts.add(i);
@@ -35,6 +44,11 @@ public class BasicBlock {
         return i;
     }
 
+    /**
+     * 将一个指令插入到基本块末尾的跳转指令前(即不包括 ret)
+     * @param i
+     * @return
+     */
     public Instruction addBeforeJump(Instruction i) {
         if (insts.size() == 0 || !(insts.get(insts.size()-1) instanceof TerminatorInst)) {
             insts.add(i);
@@ -46,7 +60,9 @@ public class BasicBlock {
         return i;
     }
 
-    // 根据BasicBlockValue被使用的情况获取。
+    /**
+     * 根据 BasicBlockValue 被使用的情况,获取所有前驱基本块,以列表形式返回。
+     */
     public List<BasicBlock> pred() {
         var val = getValue();
         ArrayList<BasicBlock> ret = new ArrayList<>();
@@ -60,7 +76,10 @@ public class BasicBlock {
         return ret;
     }
 
-    // 获取最后跳转指令的目标
+    /**
+     * 根据本块末尾的跳转指令,查询能够跳转到的后继节点
+     * @return
+     */
     public List<BasicBlock> succ() {
         assert insts.size() != 0 && insts.get(insts.size()-1) instanceof TerminatorInst;
         TerminatorInst t = (TerminatorInst)insts.get(insts.size()-1);
diff --git a/src/main/java/ssa/ds/Func.java b/src/main/java/ssa/ds/Func.java
index 5940b883391d918ee883ef1f30d64e029a6d83d0..e2bf1be63246b53ed41dbaf61d5be25019c6058b 100644
--- a/src/main/java/ssa/ds/Func.java
+++ b/src/main/java/ssa/ds/Func.java
@@ -10,7 +10,7 @@ public class Func {
     public String name;
     public List<BasicBlock> bbs;
     public FuncValue val; // used by CallInst
-    public boolean isVariadic = false;
+    public boolean isVariadic = false; // 是否有可变参数
     public FuncType retType;
     public List<ParamValue> argType;
 
diff --git a/src/main/java/ssa/ds/GetElementPtr.java b/src/main/java/ssa/ds/GetElementPtr.java
index 48050b18c12953b5e97b2080214c2e37c1f246c9..69f575a48edf97373dfedd7a5547b5e16fcf4b35 100644
--- a/src/main/java/ssa/ds/GetElementPtr.java
+++ b/src/main/java/ssa/ds/GetElementPtr.java
@@ -1,13 +1,35 @@
 package ssa.ds;
 
-// https://llvm.org/docs/LangRef.html#getelementptr-instruction
-// https://llvm.org/docs/GetElementPtr.html
+/*
+ * 基本语法:
+ *      <result> = getelementptr <ty>, <ty>* <ptrval>, {<ty> <index>}*,
+ * 
+ * 其中第一个 <ty>  表示第一个索引所指向的类型
+ * 第二个 <ty>     表示后面的指针基址 <ptrval> 的类型,
+ * <ty> <index>   表示一组索引的类型和值。
+ * 要注意索引的类型和 索引指向的基本类型 是不一样的,索引的类型一般为 i32 或 i64 
+ * **而 索引指向的基本类型 确定的是增加索引值时指针的偏移量。**
+ * 
+ * 例子:
+ * %1 = getelementptr [5 x [4 x i32]], [5 x [4 x i32]]* @a, i32 0, i32 2  
+ * %1 类型为 [4 x i32]*,可以理解为 C 语言中指向长度为 4 的一维数组基址的指针
+ * 
+ * https://llvm.org/docs/LangRef.html#getelementptr-instruction
+ * https://llvm.org/docs/GetElementPtr.html
+ * https://buaa-se-compiling.github.io/miniSysY-tutorial/lab7/help.html
+ */
+/**
+ * GEP 指令:用于计算地址(无副作用,不会读写数据)。计算结果的接收者是 %name
+ * 第一个参数:用于计算基准类型
+ * 第二个参数是一个或一向量的指针,作为基地址
+ * 其余的参数是索引
+ */
 public class GetElementPtr extends Instruction {
     public Type base;
 
-    public GetElementPtr(BasicBlock p, Value ptr) {
+    public GetElementPtr(BasicBlock parent_bb, Value ptr) {
         assert ptr.type.isPointer;
-        parent = p;
+        parent = parent_bb;
         oprands.add(new Use(this, ptr));
         // 非参数时第一维是0 (是参数时必然省略第一维)
         if (!(ptr instanceof ParamValue)) {
@@ -29,12 +51,15 @@ public class GetElementPtr extends Instruction {
     }
 
     static String format = "%s = getelementptr %s, %s* %s";
+
     // getelementptr <ty>, <ty>* <ptrval>{, <ty> <idx>}*
     @Override
     public String toString() {
-        var s = String.format(format, toValueString(), base.toString(), base.toString(), oprands.get(0).value.toValueString());
+        var s = String.format(format, toValueString(), base.toString(), base.toString(),
+                oprands.get(0).value.toValueString());
         var b = new StringBuilder(s);
-        oprands.subList(1, oprands.size()).forEach(use -> b.append(", ").append(use.value.type.toString()).append(" ").append(use.value.toValueString()));
+        oprands.subList(1, oprands.size()).forEach(
+                use -> b.append(", ").append(use.value.type.toString()).append(" ").append(use.value.toValueString()));
         if (comments != null) {
             b.append("     ; ").append(comments);
         }
diff --git a/src/main/java/ssa/ds/ParamValue.java b/src/main/java/ssa/ds/ParamValue.java
index 2d99fb3ff2727dc7d9e710347b4951b1e2342b21..3e081673187d35d12c5f970eb9faf4106d5c1353 100644
--- a/src/main/java/ssa/ds/ParamValue.java
+++ b/src/main/java/ssa/ds/ParamValue.java
@@ -1,5 +1,8 @@
 package ssa.ds;
 
+/**
+ * 函数参数
+ */
 public class ParamValue extends Value {
 
     public ParamValue(String name, Type t) {
diff --git a/src/main/java/ssa/ds/RetInst.java b/src/main/java/ssa/ds/RetInst.java
index 2c73bd1992a6d4357d5be1ef8fbb18558b63fec8..2e26f3eff3811cf5b16fbe090cb3cdd7f66eb1f2 100644
--- a/src/main/java/ssa/ds/RetInst.java
+++ b/src/main/java/ssa/ds/RetInst.java
@@ -26,6 +26,7 @@ public class RetInst extends TerminatorInst {
             return this;
         }
 
+        // 设置返回值
         public Builder addOperand(Value v) {
             inst.oprands.add(new Use(inst, v));
             return this;
diff --git a/src/main/java/ssa/ds/StoreInst.java b/src/main/java/ssa/ds/StoreInst.java
index a8fddab349d60af30c9191cd057ddfdebb7a4fd9..140896e04414bacc7ed564abe59bc47664c31446 100644
--- a/src/main/java/ssa/ds/StoreInst.java
+++ b/src/main/java/ssa/ds/StoreInst.java
@@ -2,6 +2,16 @@ package ssa.ds;
 
 import ds.Global;
 
+/**
+ * Store 指令向 alloca 申请到的栈内存中写入数据
+ * 
+ * %i = alloca i32
+ * store i32 0, i32* %i
+ * 
+ * store 指令两个参数:
+ * 1. 要 store 的值
+ * 2. 要 store 到的地址
+ */
 public class StoreInst extends Instruction {
 
     public StoreInst() {
@@ -15,7 +25,12 @@ public class StoreInst extends Instruction {
             inst = new StoreInst();
             inst.parent = parent;
         }
-
+        /**
+         * 设置 Store 指令的参数
+         * @param val 要 store 什么值
+         * @param ptr 要 store 到哪儿
+         * @return
+         */
         public Builder addOperand(Value val, Value ptr) {
             inst.oprands.add(new Use(inst, val));
             inst.oprands.add(new Use(inst, ptr));
@@ -31,11 +46,13 @@ public class StoreInst extends Instruction {
     }
 
     public static boolean checkType(Type val, Type ptr) {
+        // 必须 store 到地址
         if (!ptr.isPointer){
             return false;
         }
         Type ty = ptr.clone();
         ty.isPointer = false;
+        // 地址解引用后必须是 val 的同类型
         return ty.equals(val);
     }
 
diff --git a/src/main/java/ssa/ds/TerminatorInst.java b/src/main/java/ssa/ds/TerminatorInst.java
index 5be2e3e4ddc1d231be2c6bf56fb85165e17d2f34..187a4356c93ed6fc5b48cd6d09f46b4f9b74dcd6 100644
--- a/src/main/java/ssa/ds/TerminatorInst.java
+++ b/src/main/java/ssa/ds/TerminatorInst.java
@@ -3,7 +3,7 @@ package ssa.ds;
 import java.util.List;
 import java.util.stream.Collectors;
 
-// 终止基本块的指令,包括Branch、Jump、Return
+// 终止基本块的指令,包括 Branch、Jump、Return
 public abstract class TerminatorInst extends Instruction {
     List<BasicBlock> getSuccessors() {
         return oprands.stream().map(u -> {return ((BasicBlockValue) u.value).b;}).collect(Collectors.toList());
diff --git a/src/main/java/ssa/ds/Type.java b/src/main/java/ssa/ds/Type.java
index ef5a58d6e1c9fa03e0e7ebe752fbbecdb8c8d216..194fc35413a3d6b6e45683019b9388fb8861f2b7 100644
--- a/src/main/java/ssa/ds/Type.java
+++ b/src/main/java/ssa/ds/Type.java
@@ -5,9 +5,9 @@ import java.util.List;
 
 // 根据dims区分是否是array类型。
 public class Type implements Cloneable {
-    public PrimitiveTypeTag baseType;
-    public List<Integer> dims;
-    public boolean isPointer;
+    public PrimitiveTypeTag baseType; // 最基础类型
+    public List<Integer> dims; // 数组维度
+    public boolean isPointer; // if true, first dim is omited
 
     // 常用类型
     public static Type Void = new Type(PrimitiveTypeTag.VOID, null, false);