feat: 基本类型全类型比较支持
This commit is contained in:
parent
9d21eeace9
commit
a69cbb868a
@ -145,7 +145,7 @@ public record ExpressionBuilder(IRContext ctx) {
|
|||||||
if (ComparisonUtils.isComparisonOperator(op)) {
|
if (ComparisonUtils.isComparisonOperator(op)) {
|
||||||
return InstructionFactory.binOp(
|
return InstructionFactory.binOp(
|
||||||
ctx,
|
ctx,
|
||||||
ComparisonUtils.cmpOp(op, bin.left(), bin.right()),
|
ComparisonUtils.cmpOp(ctx.getScope().getVarTypes(), op, bin.left(), bin.right()),
|
||||||
left, right);
|
left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +171,7 @@ public record ExpressionBuilder(IRContext ctx) {
|
|||||||
if (ComparisonUtils.isComparisonOperator(op)) {
|
if (ComparisonUtils.isComparisonOperator(op)) {
|
||||||
InstructionFactory.binOpInto(
|
InstructionFactory.binOpInto(
|
||||||
ctx,
|
ctx,
|
||||||
ComparisonUtils.cmpOp(op, bin.left(), bin.right()),
|
ComparisonUtils.cmpOp(ctx.getScope().getVarTypes(), op, bin.left(), bin.right()),
|
||||||
a, b, dest);
|
a, b, dest);
|
||||||
} else {
|
} else {
|
||||||
IROpCode code = ExpressionUtils.resolveOpCode(op, bin.left(), bin.right());
|
IROpCode code = ExpressionUtils.resolveOpCode(op, bin.left(), bin.right());
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import java.util.Map;
|
|||||||
* <ul>
|
* <ul>
|
||||||
* <li>维护在当前作用域中已声明变量的寄存器分配信息;</li>
|
* <li>维护在当前作用域中已声明变量的寄存器分配信息;</li>
|
||||||
* <li>支持将已有虚拟寄存器与变量名重新绑定;</li>
|
* <li>支持将已有虚拟寄存器与变量名重新绑定;</li>
|
||||||
* <li>根据变量名查找对应的虚拟寄存器实例。</li>
|
* <li>根据变量名查找对应的虚拟寄存器实例或类型。</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
final class IRBuilderScope {
|
final class IRBuilderScope {
|
||||||
@ -104,4 +104,12 @@ final class IRBuilderScope {
|
|||||||
String lookupType(String name) {
|
String lookupType(String name) {
|
||||||
return varTypes.get(name);
|
return varTypes.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 变量->类型的映射 的不可变副本
|
||||||
|
* @return 变量->类型的映射 的不可变副本
|
||||||
|
*/
|
||||||
|
Map<String, String> getVarTypes() {
|
||||||
|
return Map.copyOf(varTypes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -218,7 +218,7 @@ public class StatementBuilder {
|
|||||||
IRVirtualRegister b = expr.build(right);
|
IRVirtualRegister b = expr.build(right);
|
||||||
|
|
||||||
// 使用适配后位宽正确的比较指令
|
// 使用适配后位宽正确的比较指令
|
||||||
IROpCode cmp = ComparisonUtils.cmpOp(operator, left, right);
|
IROpCode cmp = ComparisonUtils.cmpOp(ctx.getScope().getVarTypes(), operator, left, right);
|
||||||
IROpCode falseOp = IROpCodeUtils.invert(cmp);
|
IROpCode falseOp = IROpCodeUtils.invert(cmp);
|
||||||
|
|
||||||
InstructionFactory.cmpJump(ctx, falseOp, a, b, falseLabel);
|
InstructionFactory.cmpJump(ctx, falseOp, a, b, falseLabel);
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package org.jcnc.snow.compiler.ir.utils;
|
|||||||
|
|
||||||
import org.jcnc.snow.compiler.ir.core.IROpCode;
|
import org.jcnc.snow.compiler.ir.core.IROpCode;
|
||||||
import org.jcnc.snow.compiler.ir.core.IROpCodeMappings;
|
import org.jcnc.snow.compiler.ir.core.IROpCodeMappings;
|
||||||
|
import org.jcnc.snow.compiler.parser.ast.IdentifierNode;
|
||||||
import org.jcnc.snow.compiler.parser.ast.NumberLiteralNode;
|
import org.jcnc.snow.compiler.parser.ast.NumberLiteralNode;
|
||||||
import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode;
|
import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode;
|
||||||
import org.jcnc.snow.compiler.parser.ast.base.NodeContext;
|
import org.jcnc.snow.compiler.parser.ast.base.NodeContext;
|
||||||
@ -25,26 +26,108 @@ public final class ComparisonUtils {
|
|||||||
return IROpCodeMappings.CMP_I32.containsKey(op);
|
return IROpCodeMappings.CMP_I32.containsKey(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>类型宽度优先级</b>:D > F > L > I > S > B
|
||||||
|
* <ul>
|
||||||
|
* <li>D(double):6</li>
|
||||||
|
* <li>F(float):5</li>
|
||||||
|
* <li>L(long):4</li>
|
||||||
|
* <li>I(int):3</li>
|
||||||
|
* <li>S(short):2</li>
|
||||||
|
* <li>B(byte):1</li>
|
||||||
|
* <li>未识别类型:0</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param p 类型标记字符
|
||||||
|
* @return 优先级数值(越大类型越宽)
|
||||||
|
*/
|
||||||
|
private static int rank(char p) {
|
||||||
|
return switch (p) {
|
||||||
|
case 'D' -> 6;
|
||||||
|
case 'F' -> 5;
|
||||||
|
case 'L' -> 4;
|
||||||
|
case 'I' -> 3;
|
||||||
|
case 'S' -> 2;
|
||||||
|
case 'B' -> 1;
|
||||||
|
default -> 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回更“宽”的公共类型(即优先级高的类型)。
|
||||||
|
*
|
||||||
|
* @param a 类型标记字符 1
|
||||||
|
* @param b 类型标记字符 2
|
||||||
|
* @return 宽度更高的类型标记字符
|
||||||
|
*/
|
||||||
|
public static char promote(char a, char b) {
|
||||||
|
return rank(a) >= rank(b) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回符合操作数位宽的比较 IROpCode。
|
* 返回符合操作数位宽的比较 IROpCode。
|
||||||
*
|
*
|
||||||
|
* @param variables 变量->类型的映射
|
||||||
* @param op 比较符号(==, !=, <, >, <=, >=)
|
* @param op 比较符号(==, !=, <, >, <=, >=)
|
||||||
* @param left 左操作数 AST
|
* @param left 左操作数 AST
|
||||||
* @param right 右操作数 AST
|
* @param right 右操作数 AST
|
||||||
*/
|
*/
|
||||||
public static IROpCode cmpOp(String op, ExpressionNode left, ExpressionNode right) {
|
public static IROpCode cmpOp(Map<String, String> variables, String op, ExpressionNode left, ExpressionNode right) {
|
||||||
boolean useLong = isLongLiteral(left) || isLongLiteral(right);
|
char typeLeft = analysisType(variables, left);
|
||||||
Map<String, IROpCode> table = useLong ? IROpCodeMappings.CMP_L64
|
char typeRight = analysisType(variables, right);
|
||||||
: IROpCodeMappings.CMP_I32;
|
char type = promote(typeLeft, typeRight);
|
||||||
|
|
||||||
|
Map<String, IROpCode> table = switch (type) {
|
||||||
|
case 'B' -> IROpCodeMappings.CMP_B8;
|
||||||
|
case 'S' -> IROpCodeMappings.CMP_S16;
|
||||||
|
case 'I' -> IROpCodeMappings.CMP_I32;
|
||||||
|
case 'L' -> IROpCodeMappings.CMP_L64;
|
||||||
|
case 'F' -> IROpCodeMappings.CMP_F32;
|
||||||
|
case 'D' -> IROpCodeMappings.CMP_D64;
|
||||||
|
default -> throw new IllegalStateException("Unexpected value: " + type);
|
||||||
|
};
|
||||||
|
|
||||||
return table.get(op);
|
return table.get(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------ 内部工具 ------------ */
|
/* ------------ 内部工具 ------------ */
|
||||||
|
|
||||||
private static boolean isLongLiteral(ExpressionNode node) {
|
private static char analysisType(Map<String, String> variables, ExpressionNode node) {
|
||||||
if (node instanceof NumberLiteralNode(String value, NodeContext _)) {
|
if (node instanceof NumberLiteralNode(String value, NodeContext _)) {
|
||||||
return value.endsWith("L") || value.endsWith("l");
|
char suffix = Character.toUpperCase(value.charAt(value.length() - 1));
|
||||||
|
if ("BSILFD".indexOf(suffix) != -1) {
|
||||||
|
return suffix;
|
||||||
}
|
}
|
||||||
return false; // 变量暂不处理(后续可扩展符号表查询)
|
if (value.indexOf('.') != -1) {
|
||||||
|
return 'D';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'I'; // 默认为 'I'
|
||||||
|
}
|
||||||
|
if (node instanceof IdentifierNode(String name, NodeContext _)) {
|
||||||
|
final String type = variables.get(name);
|
||||||
|
switch (type) {
|
||||||
|
case "byte" -> {
|
||||||
|
return 'B';
|
||||||
|
}
|
||||||
|
case "short" -> {
|
||||||
|
return 'S';
|
||||||
|
}
|
||||||
|
case "int" -> {
|
||||||
|
return 'I';
|
||||||
|
}
|
||||||
|
case "long" -> {
|
||||||
|
return 'L';
|
||||||
|
}
|
||||||
|
case "float" -> {
|
||||||
|
return 'F';
|
||||||
|
}
|
||||||
|
case "double" -> {
|
||||||
|
return 'D';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'I'; // 默认为 'I'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -120,8 +120,8 @@ public final class ExpressionUtils {
|
|||||||
/**
|
/**
|
||||||
* 推荐调用:根据左右表达式类型自动选择 int / long 比较指令。
|
* 推荐调用:根据左右表达式类型自动选择 int / long 比较指令。
|
||||||
*/
|
*/
|
||||||
public static IROpCode cmpOp(String op, ExpressionNode left, ExpressionNode right) {
|
public static IROpCode cmpOp(Map<String, String> variables, String op, ExpressionNode left, ExpressionNode right) {
|
||||||
return ComparisonUtils.cmpOp(op, left, right);
|
return ComparisonUtils.cmpOp(variables, op, left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ──────────────── 类型推断 & 算术操作码匹配 ──────────────── */
|
/* ──────────────── 类型推断 & 算术操作码匹配 ──────────────── */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user