修复IDE建议
This commit is contained in:
parent
d6cfa02e79
commit
9ff16dd3a9
@ -20,7 +20,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ExpressionBuilder 将 AST 中的 ExpressionNode 转换为 IR 指令,并返回结果的虚拟寄存器。
|
* ExpressionBuilder 将 AST 中的 ExpressionNode 转换为 IR 指令,并返回结果的虚拟寄存器。
|
||||||
*
|
* <p>
|
||||||
* 支持以下表达式类型:
|
* 支持以下表达式类型:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>NumberLiteralNode —— 常量字面量,生成 LoadConstInstruction;</li>
|
* <li>NumberLiteralNode —— 常量字面量,生成 LoadConstInstruction;</li>
|
||||||
@ -72,8 +72,7 @@ public class ExpressionBuilder {
|
|||||||
*/
|
*/
|
||||||
public IRVirtualRegister build(ExpressionNode expr) {
|
public IRVirtualRegister build(ExpressionNode expr) {
|
||||||
// 1. 常量字面量处理
|
// 1. 常量字面量处理
|
||||||
if (expr instanceof NumberLiteralNode ln) {
|
if (expr instanceof NumberLiteralNode(String value)) {
|
||||||
String value = ln.value();
|
|
||||||
char suffix = value.isEmpty() ? '\0' : Character.toLowerCase(value.charAt(value.length() - 1));
|
char suffix = value.isEmpty() ? '\0' : Character.toLowerCase(value.charAt(value.length() - 1));
|
||||||
String digits = (suffix == 'b' || suffix == 's' || suffix == 'l' || suffix == 'f' || suffix == 'd')
|
String digits = (suffix == 'b' || suffix == 's' || suffix == 'l' || suffix == 'f' || suffix == 'd')
|
||||||
? value.substring(0, value.length() - 1)
|
? value.substring(0, value.length() - 1)
|
||||||
@ -112,33 +111,30 @@ public class ExpressionBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. 变量标识符处理
|
// 2. 变量标识符处理
|
||||||
if (expr instanceof IdentifierNode id) {
|
if (expr instanceof IdentifierNode(String name)) {
|
||||||
IRVirtualRegister reg = ctx.getScope().lookup(id.name());
|
IRVirtualRegister reg = ctx.getScope().lookup(name);
|
||||||
if (reg == null) {
|
if (reg == null) {
|
||||||
throw new IllegalStateException("未定义标识符: " + id.name());
|
throw new IllegalStateException("未定义标识符: " + name);
|
||||||
}
|
}
|
||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 二元表达式处理
|
// 3. 二元表达式处理
|
||||||
if (expr instanceof BinaryExpressionNode bin) {
|
if (expr instanceof BinaryExpressionNode(ExpressionNode left, String operator, ExpressionNode right)) {
|
||||||
ExpressionNode left = bin.left();
|
|
||||||
ExpressionNode right = bin.right();
|
|
||||||
String op = bin.operator();
|
|
||||||
IRVirtualRegister lreg = build(left);
|
IRVirtualRegister lreg = build(left);
|
||||||
IRVirtualRegister rreg = build(right);
|
IRVirtualRegister rreg = build(right);
|
||||||
|
|
||||||
char suf = resolveSuffix(left, right);
|
char suf = resolveSuffix(left, right);
|
||||||
IROpCode code = switch (suf) {
|
IROpCode code = switch (suf) {
|
||||||
case 'b' -> OP_I8.get(op);
|
case 'b' -> OP_I8.get(operator);
|
||||||
case 's' -> OP_I16.get(op);
|
case 's' -> OP_I16.get(operator);
|
||||||
case 'l' -> OP_L64.get(op);
|
case 'l' -> OP_L64.get(operator);
|
||||||
case 'f' -> OP_F32.get(op);
|
case 'f' -> OP_F32.get(operator);
|
||||||
case 'd' -> OP_D64.get(op);
|
case 'd' -> OP_D64.get(operator);
|
||||||
default -> OP_I32.get(op);
|
default -> OP_I32.get(operator);
|
||||||
};
|
};
|
||||||
if (code == null) {
|
if (code == null) {
|
||||||
throw new IllegalStateException("不支持的运算符: " + op);
|
throw new IllegalStateException("不支持的运算符: " + operator);
|
||||||
}
|
}
|
||||||
IRVirtualRegister dest = ctx.newRegister();
|
IRVirtualRegister dest = ctx.newRegister();
|
||||||
ctx.addInstruction(new BinaryOperationInstruction(code, dest, lreg, rreg));
|
ctx.addInstruction(new BinaryOperationInstruction(code, dest, lreg, rreg));
|
||||||
@ -146,22 +142,21 @@ public class ExpressionBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 4. 函数调用表达式处理
|
// 4. 函数调用表达式处理
|
||||||
if (expr instanceof CallExpressionNode call) {
|
if (expr instanceof CallExpressionNode(ExpressionNode callee, List<ExpressionNode> arguments)) {
|
||||||
// 构造实参寄存器列表,使用 IRValue 类型
|
// 构造实参寄存器列表,使用 IRValue 类型
|
||||||
List<IRValue> args = new ArrayList<>();
|
List<IRValue> args = new ArrayList<>();
|
||||||
for (ExpressionNode argNode : call.arguments()) {
|
for (ExpressionNode argNode : arguments) {
|
||||||
args.add(build(argNode));
|
args.add(build(argNode));
|
||||||
}
|
}
|
||||||
// 解析 callee
|
// 解析 callee
|
||||||
String fullName;
|
String fullName;
|
||||||
ExpressionNode callee = call.callee();
|
if (callee instanceof MemberExpressionNode(ExpressionNode object, String member)
|
||||||
if (callee instanceof MemberExpressionNode men
|
&& object instanceof IdentifierNode(String name)) {
|
||||||
&& men.object() instanceof IdentifierNode objId) {
|
|
||||||
// 模块静态调用
|
// 模块静态调用
|
||||||
fullName = objId.name() + "." + men.member();
|
fullName = name + "." + member;
|
||||||
} else if (callee instanceof IdentifierNode id2) {
|
} else if (callee instanceof IdentifierNode(String name)) {
|
||||||
// 同模块调用
|
// 同模块调用
|
||||||
fullName = id2.name();
|
fullName = name;
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"不支持的调用目标: " + callee.getClass().getSimpleName()
|
"不支持的调用目标: " + callee.getClass().getSimpleName()
|
||||||
@ -181,11 +176,11 @@ public class ExpressionBuilder {
|
|||||||
* 决定二元运算类型后缀,基于两侧 NumberLiteralNode 的后缀。
|
* 决定二元运算类型后缀,基于两侧 NumberLiteralNode 的后缀。
|
||||||
*/
|
*/
|
||||||
private char resolveSuffix(ExpressionNode left, ExpressionNode right) {
|
private char resolveSuffix(ExpressionNode left, ExpressionNode right) {
|
||||||
char l = (left instanceof NumberLiteralNode ln)
|
char l = (left instanceof NumberLiteralNode(String value))
|
||||||
? Character.toLowerCase(ln.value().charAt(ln.value().length() - 1))
|
? Character.toLowerCase(value.charAt(value.length() - 1))
|
||||||
: '\0';
|
: '\0';
|
||||||
char r = (right instanceof NumberLiteralNode rn)
|
char r = (right instanceof NumberLiteralNode(String value))
|
||||||
? Character.toLowerCase(rn.value().charAt(rn.value().length() - 1))
|
? Character.toLowerCase(value.charAt(value.length() - 1))
|
||||||
: '\0';
|
: '\0';
|
||||||
if (l == 'd' || r == 'd') return 'd';
|
if (l == 'd' || r == 'd') return 'd';
|
||||||
if (l == 'f' || r == 'f') return 'f';
|
if (l == 'f' || r == 'f') return 'f';
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
|
|||||||
import org.jcnc.snow.compiler.ir.core.IRValue;
|
import org.jcnc.snow.compiler.ir.core.IRValue;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,7 +20,7 @@ public class CallInstruction extends IRInstruction {
|
|||||||
public CallInstruction(IRVirtualRegister dest, String functionName, List<IRValue> args) {
|
public CallInstruction(IRVirtualRegister dest, String functionName, List<IRValue> args) {
|
||||||
this.dest = dest;
|
this.dest = dest;
|
||||||
this.functionName = functionName;
|
this.functionName = functionName;
|
||||||
this.arguments = Collections.unmodifiableList(new ArrayList<>(args));
|
this.arguments = List.copyOf(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 顶层的函数定义解析器。
|
* 顶层的函数定义解析器。
|
||||||
*
|
* <p>
|
||||||
* 通过 FlexibleSectionParser 按区块顺序解析函数的各个部分:
|
* 通过 FlexibleSectionParser 按区块顺序解析函数的各个部分:
|
||||||
* 函数头(名称)、参数列表、返回类型、函数体,并最终生成 FunctionNode。
|
* 函数头(名称)、参数列表、返回类型、函数体,并最终生成 FunctionNode。
|
||||||
* 支持在参数或返回类型声明中出现注释,自动跳过注释和空行而不干扰语法解析。
|
* 支持在参数或返回类型声明中出现注释,自动跳过注释和空行而不干扰语法解析。
|
||||||
|
|||||||
@ -10,10 +10,10 @@ import java.util.function.Predicate;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 通用的解析器,用于解析结构化的内容部分,完全解耦合关键字和语法。
|
* 通用的解析器,用于解析结构化的内容部分,完全解耦合关键字和语法。
|
||||||
*
|
* <p>
|
||||||
* FlexibleSectionParser 提供了一个灵活的机制来解析可变的语法块。每个语法块的解析逻辑通过外部提供,
|
* FlexibleSectionParser 提供了一个灵活的机制来解析可变的语法块。每个语法块的解析逻辑通过外部提供,
|
||||||
* 该类仅负责按顺序解析不同的区块,直到遇到结束标记,同时能够跳过并收集注释供后续使用。
|
* 该类仅负责按顺序解析不同的区块,直到遇到结束标记,同时能够跳过并收集注释供后续使用。
|
||||||
*
|
* <p>
|
||||||
* 使用此类可以解析如函数定义中的多个部分(如参数、返回类型、函数体等),而无需在解析器中硬编码这些结构,
|
* 使用此类可以解析如函数定义中的多个部分(如参数、返回类型、函数体等),而无需在解析器中硬编码这些结构,
|
||||||
* 并且保留注释信息以便 IDE 或工具链进行注释跳转、重构等操作。
|
* 并且保留注释信息以便 IDE 或工具链进行注释跳转、重构等操作。
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import org.jcnc.snow.vm.utils.LoggingUtils;
|
|||||||
import org.jcnc.snow.vm.engine.VMMode;
|
import org.jcnc.snow.vm.engine.VMMode;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@code LocalVariableStore} represents a simple dynamically-sized
|
* The {@code LocalVariableStore} represents a simple dynamically-sized
|
||||||
@ -107,11 +108,9 @@ public class LocalVariableStore {
|
|||||||
|
|
||||||
/** Mode-specific UI hook (unchanged). */
|
/** Mode-specific UI hook (unchanged). */
|
||||||
private void handleMode() {
|
private void handleMode() {
|
||||||
switch (vmMode) {
|
/* no-op */
|
||||||
case DEBUG ->
|
if (Objects.requireNonNull(vmMode) == VMMode.DEBUG) {
|
||||||
LocalVariableStoreSwing.display(this, "Local Variable Table");
|
LocalVariableStoreSwing.display(this, "Local Variable Table");
|
||||||
case RUN -> { /* no-op */ }
|
|
||||||
default -> { /* no-op */ }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user