!48 fix: 变量声明初始化寄存器别名导致内外层循环相互影响
Merge pull request !48 from Luke/bugfix/declare-init-aliasing-
This commit is contained in:
commit
025ea75f08
11
.run/Bug2.run.xml
Normal file
11
.run/Bug2.run.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Bug2" type="Application" factoryName="Application" folderName="BugFarm">
|
||||||
|
<option name="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
|
||||||
|
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
|
||||||
|
<module name="Snow" />
|
||||||
|
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/BugFarm/Bug2 -o target/Bug2" />
|
||||||
|
<method v="2">
|
||||||
|
<option name="Make" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
45
playground/BugFarm/Bug2/Main.snow
Normal file
45
playground/BugFarm/Bug2/Main.snow
Normal file
@ -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
|
||||||
11
playground/BugFarm/Bug2/OS.snow
Normal file
11
playground/BugFarm/Bug2/OS.snow
Normal file
@ -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
|
||||||
@ -98,21 +98,30 @@ public class StatementBuilder {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (stmt instanceof DeclarationNode decl) {
|
if (stmt instanceof DeclarationNode decl) {
|
||||||
// 变量声明,如 int a = 1;
|
// 变量声明语句(如 int a = 1;)
|
||||||
if (decl.getInitializer().isPresent()) {
|
if (decl.getInitializer().isPresent()) {
|
||||||
// 声明同时有初值
|
// 如果声明时带有初始值(如 int a = b;)
|
||||||
|
|
||||||
// 1. 设置声明变量的类型
|
// 1. 设置变量类型,便于表达式求值/指令生成时推断类型信息
|
||||||
ctx.setVarType(decl.getType());
|
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.clearVarType();
|
||||||
|
|
||||||
ctx.getScope().declare(decl.getName(), decl.getType(), r);
|
// 5. 在作用域内将变量名与新分配的寄存器进行绑定
|
||||||
|
// 这样后续对该变量的任何操作都只会影响 dest,不会反向影响初值表达式中的源变量
|
||||||
|
ctx.getScope().declare(decl.getName(), decl.getType(), dest);
|
||||||
} else {
|
} else {
|
||||||
// 仅声明,无初值
|
// 仅声明变量,无初值(如 int a;)
|
||||||
|
// 在作用域内声明并分配新寄存器,但不进行初始化
|
||||||
ctx.getScope().declare(decl.getName(), decl.getType());
|
ctx.getScope().declare(decl.getName(), decl.getType());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user