diff --git a/.run/Bug2.run.xml b/.run/Bug2.run.xml new file mode 100644 index 0000000..e77abfc --- /dev/null +++ b/.run/Bug2.run.xml @@ -0,0 +1,11 @@ + + + + \ No newline at end of file diff --git a/playground/BugFarm/Bug2/Main.snow b/playground/BugFarm/Bug2/Main.snow new file mode 100644 index 0000000..ca1d0c8 --- /dev/null +++ b/playground/BugFarm/Bug2/Main.snow @@ -0,0 +1,45 @@ +module: Main + import: os + function: main + parameter: + return_type: int + body: + loop: + init: + declare outer_i: int = 1 + cond: + outer_i <= 10 + step: + outer_i = outer_i + 1 + body: + print(outer_i) + + loop: + init: + // 注意这一行使用了外层循环的变量 outer_i + declare inter_j: int = outer_i + cond: + inter_j <= 10 + step: + inter_j = inter_j + 1 + body: + + end body + end loop + + end body + end loop + + return 0 + end body + end function + + function: print + parameter: + declare i1: int + return_type: void + body: + syscall("PRINT",i1) + end body + end function +end module \ No newline at end of file diff --git a/playground/BugFarm/Bug2/OS.snow b/playground/BugFarm/Bug2/OS.snow new file mode 100644 index 0000000..6026d43 --- /dev/null +++ b/playground/BugFarm/Bug2/OS.snow @@ -0,0 +1,11 @@ +module: os + import: os + function: print + parameter: + declare i1: int + return_type: void + body: + syscall("PRINT",i1) + end body + end function +end module \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/compiler/ir/builder/StatementBuilder.java b/src/main/java/org/jcnc/snow/compiler/ir/builder/StatementBuilder.java index 98ab6ce..b735213 100644 --- a/src/main/java/org/jcnc/snow/compiler/ir/builder/StatementBuilder.java +++ b/src/main/java/org/jcnc/snow/compiler/ir/builder/StatementBuilder.java @@ -98,21 +98,30 @@ public class StatementBuilder { return; } if (stmt instanceof DeclarationNode decl) { - // 变量声明,如 int a = 1; + // 变量声明语句(如 int a = 1;) if (decl.getInitializer().isPresent()) { - // 声明同时有初值 + // 如果声明时带有初始值(如 int a = b;) - // 1. 设置声明变量的类型 + // 1. 设置变量类型,便于表达式求值/指令生成时推断类型信息 ctx.setVarType(decl.getType()); - IRVirtualRegister r = expr.build(decl.getInitializer().get()); + // 2. 为当前声明的变量分配一个全新的虚拟寄存器 + // 这样可以保证该变量和初始值表达式中的变量物理上独立,不会发生别名/串扰 + IRVirtualRegister dest = ctx.newRegister(); - // 2. 清除变量声明 + // 3. 将初始值表达式的计算结果写入新分配的寄存器 + // 即使初始值是某个已存在变量(如 outer_i),这里是值的拷贝 + expr.buildInto(decl.getInitializer().get(), dest); + + // 4. 清理类型设置,防止影响后续变量声明 ctx.clearVarType(); - ctx.getScope().declare(decl.getName(), decl.getType(), r); + // 5. 在作用域内将变量名与新分配的寄存器进行绑定 + // 这样后续对该变量的任何操作都只会影响 dest,不会反向影响初值表达式中的源变量 + ctx.getScope().declare(decl.getName(), decl.getType(), dest); } else { - // 仅声明,无初值 + // 仅声明变量,无初值(如 int a;) + // 在作用域内声明并分配新寄存器,但不进行初始化 ctx.getScope().declare(decl.getName(), decl.getType()); } return;