docs: 优化 ComparisonUtils 的代码注释
This commit is contained in:
parent
82069629dd
commit
81ca858cc1
@ -10,36 +10,46 @@ import org.jcnc.snow.compiler.parser.ast.base.NodeContext;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 比较运算辅助工具:
|
||||
* 根据左右操作数类型(目前通过字面量后缀 <code>L/l</code> 判定)选择
|
||||
* 正确的 IR 比较指令,保证 int/long 均能正常运行。
|
||||
* 工具类,用于比较运算相关的类型推断和指令选择。
|
||||
* <p>
|
||||
* 该类主要用于根据左右操作数的静态类型,自动选择正确的 IR 层比较操作码。
|
||||
* 支持自动类型提升,保证 int、long、float、double 等类型的比较均能得到正确的 IR 指令。
|
||||
* </p>
|
||||
*
|
||||
* 类型判定支持:
|
||||
* <ul>
|
||||
* <li>字面量后缀:支持 B/S/I/L/F/D(大小写均可)</li>
|
||||
* <li>浮点数支持:如无后缀但有小数点,视为 double</li>
|
||||
* <li>变量类型:根据传入变量表推断类型,未识别则默认 int</li>
|
||||
* </ul>
|
||||
*/
|
||||
public final class ComparisonUtils {
|
||||
private ComparisonUtils() {
|
||||
}
|
||||
private ComparisonUtils() {}
|
||||
|
||||
/**
|
||||
* 判断给定操作符是否为比较运算符
|
||||
* 判断给定字符串是否为受支持的比较运算符(==, !=, <, >, <=, >=)。
|
||||
* 仅检查 int 类型指令表,因所有类型的比较符号集合相同。
|
||||
*
|
||||
* @param op 比较运算符字符串
|
||||
* @return 若为比较运算符返回 true,否则返回 false
|
||||
*/
|
||||
public static boolean isComparisonOperator(String op) {
|
||||
// 两张表 key 完全一致,只需检查一张
|
||||
// 只需查 int 类型表即可
|
||||
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>
|
||||
* 返回类型宽度优先级(越大代表类型越宽)。类型对应的优先级:
|
||||
* - D (double): 6
|
||||
* - F (float): 5
|
||||
* - L (long): 4
|
||||
* - I (int): 3
|
||||
* - S (short): 2
|
||||
* - B (byte): 1
|
||||
* - 未知类型: 0
|
||||
*
|
||||
* @param p 类型标记字符
|
||||
* @return 优先级数值(越大类型越宽)
|
||||
* @return 类型优先级数值
|
||||
*/
|
||||
private static int rank(char p) {
|
||||
return switch (p) {
|
||||
@ -54,23 +64,28 @@ public final class ComparisonUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回更“宽”的公共类型(即优先级高的类型)。
|
||||
* 返回两个类型中较“宽”的类型(即优先级较高的类型)。
|
||||
* 若优先级相等,返回第一个参数的类型。
|
||||
*
|
||||
* @param a 类型标记字符1
|
||||
* @param b 类型标记字符2
|
||||
* @return 宽度更高的类型标记字符
|
||||
* @return 宽度更高的类型字符
|
||||
*/
|
||||
public static char promote(char a, char b) {
|
||||
return rank(a) >= rank(b) ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回符合操作数位宽的比较 IROpCode。
|
||||
* 根据变量类型映射和操作数表达式,推断操作数类型,
|
||||
* 并自动类型提升后,选择正确的比较操作码(IROpCode)。
|
||||
* 若未能推断类型或操作符不受支持,会抛出异常。
|
||||
*
|
||||
* @param variables 变量->类型的映射
|
||||
* @param variables 变量名到类型的映射(如 "a" -> "int")
|
||||
* @param op 比较符号(==, !=, <, >, <=, >=)
|
||||
* @param left 左操作数 AST
|
||||
* @param right 右操作数 AST
|
||||
* @param left 左操作数表达式
|
||||
* @param right 右操作数表达式
|
||||
* @return 适用的比较 IROpCode
|
||||
* @throws IllegalStateException 如果无法推断合适的类型
|
||||
*/
|
||||
public static IROpCode cmpOp(Map<String, String> variables, String op, ExpressionNode left, ExpressionNode right) {
|
||||
char typeLeft = analysisType(variables, left);
|
||||
@ -84,14 +99,21 @@ public final class ComparisonUtils {
|
||||
case 'L' -> IROpCodeMappings.CMP_L64;
|
||||
case 'F' -> IROpCodeMappings.CMP_F32;
|
||||
case 'D' -> IROpCodeMappings.CMP_D64;
|
||||
default -> throw new IllegalStateException("意外的值: " + type);
|
||||
default -> throw new IllegalStateException("Unexpected value: " + type);
|
||||
};
|
||||
|
||||
return table.get(op);
|
||||
}
|
||||
|
||||
/* ------------ 内部工具 ------------ */
|
||||
|
||||
/**
|
||||
* 内部工具方法:根据表达式节点和变量表推断类型标记字符。
|
||||
* 字面量支持 B/S/I/L/F/D(大小写均可),浮点数默认 double;
|
||||
* 标识符类型按变量表映射,未知则默认 int。
|
||||
*
|
||||
* @param variables 变量名到类型的映射
|
||||
* @param node 表达式节点
|
||||
* @return 类型标记字符(B/S/I/L/F/D),未知时返回 I
|
||||
*/
|
||||
private static char analysisType(Map<String, String> variables, ExpressionNode node) {
|
||||
if (node instanceof NumberLiteralNode(String value, NodeContext _)) {
|
||||
char suffix = Character.toUpperCase(value.charAt(value.length() - 1));
|
||||
@ -101,33 +123,21 @@ public final class ComparisonUtils {
|
||||
if (value.indexOf('.') != -1) {
|
||||
return 'D';
|
||||
}
|
||||
|
||||
return 'I'; // 默认为 'I'
|
||||
return 'I'; // 默认 int
|
||||
}
|
||||
if (node instanceof IdentifierNode(String name, NodeContext _)) {
|
||||
final String type = variables.get(name);
|
||||
if (type != null) {
|
||||
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';
|
||||
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'
|
||||
return 'I'; // 默认 int
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user