diff --git a/src/main/java/org/jcnc/snow/compiler/backend/generator/CallGenerator.java b/src/main/java/org/jcnc/snow/compiler/backend/generator/CallGenerator.java index 58d721d..d2d0a18 100644 --- a/src/main/java/org/jcnc/snow/compiler/backend/generator/CallGenerator.java +++ b/src/main/java/org/jcnc/snow/compiler/backend/generator/CallGenerator.java @@ -23,7 +23,7 @@ import java.util.concurrent.ConcurrentHashMap; * *
+ * 本方法用于将 IR 层的数组下标访问表达式(如 arr[idx]),生成对应的 VM 指令序列。 + * 支持 byte/short/int/long/float/double/reference 等所有基础类型的数组元素访问。 + *
* - * @param ins 调用指令 - * @param out VM 程序构建器 - * @param slotMap 寄存器到槽位映射 - * @param isInt 是否是一维整型下标 + *+ * 本方法负责将底层虚拟机传递的 flags 整数型位域,转换为 Java NIO 标准的文件打开选项集合, + * 以支持文件读、写、创建、截断、追加等多种访问场景。 + * 常用于 SYSCALL 的 OPEN 子命令。 + *
+ * + * @param flags 文件打开模式标志。各标志可组合使用,具体含义请参见虚拟机文档。 + * @return 转换后的 OpenOption 集合,可直接用于 FileChannel.open 等 NIO 方法 + */ + private static Set+ * 本方法是全局错误屏障,任何命令异常都会转换为虚拟机通用的失败信号, + * 保证上层调用逻辑不会被异常打断。实际应用中可拓展错误码机制。 + *
+ * + * @param stack 操作数栈,将失败信号写入此栈 + * @param e 抛出的异常对象,可在调试时输出日志 + */ + private static void pushErr(OperandStack stack, Exception e) { + stack.push(-1); + System.err.println("Syscall exception: " + e); + } + + /** + * 控制台输出通用方法,支持基本类型、字节数组、任意数组、对象等。 + *+ * 该方法用于 SYSCALL PRINT/PRINTLN,将任意类型对象转为易读字符串输出到标准输出流。 + * 字节数组自动按 UTF-8 解码,其它原生数组按格式化字符串输出。 + *
+ * + * @param obj 待输出的内容,可以为任何类型(如基本类型、byte[]、数组、对象等) + * @param newline 是否自动换行。如果为 true,则在输出后换行;否则直接输出。 + */ + private static void output(Object obj, boolean newline) { + String str; + if (obj == null) { + str = "null"; + } else if (obj instanceof byte[] bytes) { + // 字节数组作为文本输出 + str = new String(bytes); + } else if (obj.getClass().isArray()) { + // 其它数组格式化输出 + str = arrayToString(obj); + } else { + str = obj.toString(); + } + if (newline) System.out.println(str); + else System.out.print(str); + } + + /** + * 将各种原生数组和对象数组转换为可读字符串,便于控制台输出和调试。 + *+ * 本方法针对 int、long、double、float、short、char、byte、boolean 等所有原生数组类型 + * 以及对象数组都能正确格式化,统一输出格式风格,避免显示为类型 hashCode。 + * 若为不支持的类型,返回通用提示字符串。 + *
+ * + * @param array 任意原生数组或对象数组 + * @return 该数组的可读字符串表示 + */ + private static String arrayToString(Object array) { + if (array instanceof int[] a) return Arrays.toString(a); + if (array instanceof long[] a) return Arrays.toString(a); + if (array instanceof double[] a) return Arrays.toString(a); + if (array instanceof float[] a) return Arrays.toString(a); + if (array instanceof short[] a) return Arrays.toString(a); + if (array instanceof char[] a) return Arrays.toString(a); + if (array instanceof byte[] a) return Arrays.toString(a); + if (array instanceof boolean[] a) return Arrays.toString(a); + if (array instanceof Object[] a) return Arrays.deepToString(a); + return "Unsupported array"; + } + /** * 分发并执行 SYSCALL 子命令,根据子命令类型从操作数栈取出参数、操作底层资源,并将结果压回栈顶。 * @@ -226,8 +317,24 @@ public class SyscallCommand implements Command { sel.close(); } - // 数组元素访问:arr[idx] -> 返回元素(当前实现返回 int 或字符串/引用原样) +// 数组元素访问:arr[idx] —— 保留所有类型精度(byte/short/int/long/float/double/boolean/string/ref) case "ARR_GET" -> { + /** + * 执行数组下标访问操作 arr[idx],并将对应元素以真实类型压入操作数栈。 + *- * 本方法负责将底层虚拟机传递的 flags 整数型位域,转换为 Java NIO 标准的文件打开选项集合, - * 以支持文件读、写、创建、截断、追加等多种访问场景。 - * 常用于 SYSCALL 的 OPEN 子命令。 - *
- * - * @param flags 文件打开模式标志。各标志可组合使用,具体含义请参见虚拟机文档。 - * @return 转换后的 OpenOption 集合,可直接用于 FileChannel.open 等 NIO 方法 - */ - private static Set- * 本方法是全局错误屏障,任何命令异常都会转换为虚拟机通用的失败信号, - * 保证上层调用逻辑不会被异常打断。实际应用中可拓展错误码机制。 - *
- * - * @param stack 操作数栈,将失败信号写入此栈 - * @param e 抛出的异常对象,可在调试时输出日志 - */ - private static void pushErr(OperandStack stack, Exception e) { - stack.push(-1); - System.err.println("Syscall exception: " + e); - } - - /** - * 控制台输出通用方法,支持基本类型、字节数组、任意数组、对象等。 - *- * 该方法用于 SYSCALL PRINT/PRINTLN,将任意类型对象转为易读字符串输出到标准输出流。 - * 字节数组自动按 UTF-8 解码,其它原生数组按格式化字符串输出。 - *
- * - * @param obj 待输出的内容,可以为任何类型(如基本类型、byte[]、数组、对象等) - * @param newline 是否自动换行。如果为 true,则在输出后换行;否则直接输出。 - */ - private static void output(Object obj, boolean newline) { - String str; - if (obj == null) { - str = "null"; - } else if (obj instanceof byte[] bytes) { - // 字节数组作为文本输出 - str = new String(bytes); - } else if (obj.getClass().isArray()) { - // 其它数组格式化输出 - str = arrayToString(obj); - } else { - str = obj.toString(); - } - if (newline) System.out.println(str); - else System.out.print(str); - } - - /** - * 将各种原生数组和对象数组转换为可读字符串,便于控制台输出和调试。 - *- * 本方法针对 int、long、double、float、short、char、byte、boolean 等所有原生数组类型 - * 以及对象数组都能正确格式化,统一输出格式风格,避免显示为类型 hashCode。 - * 若为不支持的类型,返回通用提示字符串。 - *
- * - * @param array 任意原生数组或对象数组 - * @return 该数组的可读字符串表示 - */ - private static String arrayToString(Object array) { - if (array instanceof int[] a) return Arrays.toString(a); - if (array instanceof long[] a) return Arrays.toString(a); - if (array instanceof double[] a) return Arrays.toString(a); - if (array instanceof float[] a) return Arrays.toString(a); - if (array instanceof short[] a) return Arrays.toString(a); - if (array instanceof char[] a) return Arrays.toString(a); - if (array instanceof byte[] a) return Arrays.toString(a); - if (array instanceof boolean[] a) return Arrays.toString(a); - if (array instanceof Object[] a) return Arrays.deepToString(a); - return "Unsupported array"; - } }