feat: 支持结构体字段赋值
- 增加对 this.<field> 结构体字段赋值的支持 - 优化赋值语句处理逻辑,优先考虑局部/参数变量- 修复字段写入后的常量绑定问题 - 优化变量声明和初始化流程
This commit is contained in:
parent
cff45a9d17
commit
513aeba2bc
@ -84,8 +84,58 @@ public class StatementBuilder {
|
|||||||
expr.build(exp);
|
expr.build(exp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===== 赋值语句 =====
|
||||||
if (stmt instanceof AssignmentNode(String var, ExpressionNode rhs, NodeContext _)) {
|
if (stmt instanceof AssignmentNode(String var, ExpressionNode rhs, NodeContext _)) {
|
||||||
|
// 1) 优先当作“已存在的局部/参数变量”赋值(保持原有行为)
|
||||||
final String type = ctx.getScope().lookupType(var);
|
final String type = ctx.getScope().lookupType(var);
|
||||||
|
IRVirtualRegister localReg = ctx.getScope().lookup(var);
|
||||||
|
if (localReg != null) {
|
||||||
|
ctx.setVarType(type);
|
||||||
|
expr.buildInto(rhs, localReg);
|
||||||
|
|
||||||
|
// 赋值时尝试记录/清除常量
|
||||||
|
try {
|
||||||
|
Object constVal = tryFoldConst(rhs);
|
||||||
|
if (constVal != null) ctx.getScope().setConstValue(var, constVal);
|
||||||
|
else ctx.getScope().clearConstValue(var);
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
|
ctx.clearVarType();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) 若不是局部变量:尝试将“裸标识符”视为 this.<field> 的结构体字段赋值
|
||||||
|
IRVirtualRegister thisReg = ctx.getScope().lookup("this");
|
||||||
|
String thisType = ctx.getScope().lookupType("this");
|
||||||
|
if (thisReg != null && thisType != null) {
|
||||||
|
java.util.Map<String, Integer> layout = ctx.getScope().getStructLayout(thisType);
|
||||||
|
if (layout == null) {
|
||||||
|
// 兼容 "Module.Struct" 与简单名 "Struct"
|
||||||
|
int dot = thisType.lastIndexOf('.');
|
||||||
|
if (dot >= 0 && dot + 1 < thisType.length()) {
|
||||||
|
layout = ctx.getScope().getStructLayout(thisType.substring(dot + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Integer idx = (layout != null) ? layout.get(var) : null;
|
||||||
|
|
||||||
|
if (idx != null) {
|
||||||
|
// 生成右值
|
||||||
|
IRVirtualRegister valReg = expr.build(rhs);
|
||||||
|
// 字段槽位下标常量
|
||||||
|
IRVirtualRegister idxReg = InstructionFactory.loadConst(ctx, idx);
|
||||||
|
// 用 __setindex_r 写入字段(与构造写入/读取对齐)
|
||||||
|
java.util.List<org.jcnc.snow.compiler.ir.core.IRValue> argv =
|
||||||
|
java.util.List.of(thisReg, idxReg, valReg);
|
||||||
|
ctx.addInstruction(new org.jcnc.snow.compiler.ir.instruction.CallInstruction(
|
||||||
|
null, "__setindex_r", argv));
|
||||||
|
|
||||||
|
// 字段写入后清理该标识符的常量绑定(避免误当作本地常量)
|
||||||
|
try { ctx.getScope().clearConstValue(var); } catch (Throwable ignored) {}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) 否则退回为“声明/绑定一个新的局部变量并赋值”(与原逻辑一致)
|
||||||
ctx.setVarType(type);
|
ctx.setVarType(type);
|
||||||
IRVirtualRegister target = getOrDeclareRegister(var, type);
|
IRVirtualRegister target = getOrDeclareRegister(var, type);
|
||||||
expr.buildInto(rhs, target);
|
expr.buildInto(rhs, target);
|
||||||
@ -97,8 +147,7 @@ public class StatementBuilder {
|
|||||||
ctx.getScope().setConstValue(var, constVal);
|
ctx.getScope().setConstValue(var, constVal);
|
||||||
else
|
else
|
||||||
ctx.getScope().clearConstValue(var);
|
ctx.getScope().clearConstValue(var);
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {}
|
||||||
}
|
|
||||||
|
|
||||||
ctx.clearVarType();
|
ctx.clearVarType();
|
||||||
return;
|
return;
|
||||||
@ -163,11 +212,9 @@ public class StatementBuilder {
|
|||||||
ctx.setVarType(decl.getType());
|
ctx.setVarType(decl.getType());
|
||||||
|
|
||||||
// 2. 为当前声明的变量分配一个全新的虚拟寄存器
|
// 2. 为当前声明的变量分配一个全新的虚拟寄存器
|
||||||
// 这样可以保证该变量和初始值表达式中的变量物理上独立,不会发生别名/串扰
|
|
||||||
IRVirtualRegister dest = ctx.newRegister();
|
IRVirtualRegister dest = ctx.newRegister();
|
||||||
|
|
||||||
// 3. 将初始值表达式的计算结果写入新分配的寄存器
|
// 3. 将初始值表达式的计算结果写入新分配的寄存器
|
||||||
// 即使初始值是某个已存在变量(如 outer_i),这里是值的拷贝
|
|
||||||
expr.buildInto(decl.getInitializer().get(), dest);
|
expr.buildInto(decl.getInitializer().get(), dest);
|
||||||
|
|
||||||
// 声明赋初值时登记常量
|
// 声明赋初值时登记常量
|
||||||
@ -177,8 +224,7 @@ public class StatementBuilder {
|
|||||||
ctx.getScope().setConstValue(decl.getName(), constVal);
|
ctx.getScope().setConstValue(decl.getName(), constVal);
|
||||||
else
|
else
|
||||||
ctx.getScope().clearConstValue(decl.getName());
|
ctx.getScope().clearConstValue(decl.getName());
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {}
|
||||||
}
|
|
||||||
|
|
||||||
ctx.clearVarType();
|
ctx.clearVarType();
|
||||||
ctx.getScope().declare(decl.getName(), decl.getType(), dest);
|
ctx.getScope().declare(decl.getName(), decl.getType(), dest);
|
||||||
@ -188,18 +234,18 @@ public class StatementBuilder {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stmt instanceof ReturnNode ret) {
|
if (stmt instanceof ReturnNode ret) {
|
||||||
// return 语句
|
// return 语句
|
||||||
if (ret.getExpression().isPresent()) {
|
if (ret.getExpression().isPresent()) {
|
||||||
// return 带返回值
|
|
||||||
IRVirtualRegister r = expr.build(ret.getExpression().get());
|
IRVirtualRegister r = expr.build(ret.getExpression().get());
|
||||||
InstructionFactory.ret(ctx, r);
|
InstructionFactory.ret(ctx, r);
|
||||||
} else {
|
} else {
|
||||||
// return 无返回值
|
|
||||||
InstructionFactory.retVoid(ctx);
|
InstructionFactory.retVoid(ctx);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stmt instanceof BreakNode) {
|
if (stmt instanceof BreakNode) {
|
||||||
// break 语句:跳转到当前最近一层循环的结束标签
|
// break 语句:跳转到当前最近一层循环的结束标签
|
||||||
if (breakTargets.isEmpty()) {
|
if (breakTargets.isEmpty()) {
|
||||||
@ -208,6 +254,7 @@ public class StatementBuilder {
|
|||||||
InstructionFactory.jmp(ctx, breakTargets.peek());
|
InstructionFactory.jmp(ctx, breakTargets.peek());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stmt instanceof ContinueNode) {
|
if (stmt instanceof ContinueNode) {
|
||||||
// continue 语句:跳转到当前最近一层循环的 step 起始标签
|
// continue 语句:跳转到当前最近一层循环的 step 起始标签
|
||||||
if (continueTargets.isEmpty()) {
|
if (continueTargets.isEmpty()) {
|
||||||
@ -216,10 +263,12 @@ public class StatementBuilder {
|
|||||||
InstructionFactory.jmp(ctx, continueTargets.peek());
|
InstructionFactory.jmp(ctx, continueTargets.peek());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 不支持的语句类型
|
// 不支持的语句类型
|
||||||
throw new IllegalStateException("Unsupported statement: " + stmt.getClass().getSimpleName() + ": " + stmt);
|
throw new IllegalStateException("Unsupported statement: " + stmt.getClass().getSimpleName() + ": " + stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取变量名对应的寄存器,如果尚未声明则新声明一个并返回。
|
* 获取变量名对应的寄存器,如果尚未声明则新声明一个并返回。
|
||||||
*
|
*
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user