From 4e3de185b83f795cbfe61f1d23bc3fc732081927 Mon Sep 17 00:00:00 2001
From: Luke
Date: Sat, 19 Jul 2025 00:09:17 +0800
Subject: [PATCH] =?UTF-8?q?refactor:=E9=87=8D=E6=9E=84=20PRINT=20=E5=92=8C?=
=?UTF-8?q?=20PRINTLN=20=E5=8A=9F=E8=83=BD=E5=B9=B6=E4=BC=98=E5=8C=96?=
=?UTF-8?q?=E8=BE=93=E5=87=BA=E6=96=B9=E6=B3=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 重构了 PRINT 和 PRINTLN 指令的实现,支持更多数据类型输出
- 新增通用的 output辅助方法,统一处理各种类型的输出
- 扩展了输出功能,支持基本类型、数组和任意对象的打印
- 优化了代码结构,提高了可读性和可维护性
---
.../system/control/SyscallCommand.java | 149 +++++++++++-------
1 file changed, 91 insertions(+), 58 deletions(-)
diff --git a/src/main/java/org/jcnc/snow/vm/commands/system/control/SyscallCommand.java b/src/main/java/org/jcnc/snow/vm/commands/system/control/SyscallCommand.java
index 39e63e7..eebcd28 100644
--- a/src/main/java/org/jcnc/snow/vm/commands/system/control/SyscallCommand.java
+++ b/src/main/java/org/jcnc/snow/vm/commands/system/control/SyscallCommand.java
@@ -46,42 +46,7 @@ import static java.nio.file.StandardOpenOption.*;
*/
public class SyscallCommand implements Command {
- /*------------------------------------ 工具方法 ------------------------------------*/
- /**
- * POSIX open 标志到 Java NIO OpenOption 的映射
- *
- * 将 Linux/UNIX 的 open 调用 flags 参数,转换为 Java NIO 的 OpenOption 集合。
- * 目前仅支持 WRITE(0x1)、READ、CREATE(0x40)、TRUNCATE(0x200)、APPEND(0x400)等常用标志。
- *
- *
- * @param flags POSIX 风格 open 标志(如 O_WRONLY=0x1, O_CREAT=0x40 等)
- * @return 映射后的 OpenOption 集合
- */
- private static Set flagsToOptions(int flags) {
- Set opts = new HashSet<>();
- // 0x1 = WRITE,否则默认 READ
- if ((flags & 0x1) != 0) opts.add(WRITE);
- else opts.add(READ);
- if ((flags & 0x40) != 0) opts.add(CREATE);
- if ((flags & 0x200) != 0) opts.add(TRUNCATE_EXISTING);
- if ((flags & 0x400) != 0) opts.add(APPEND);
- return opts;
- }
-
- /**
- * 统一异常处理:
- *
- * 捕获 syscall 内部所有异常,将 -1 压入操作数栈,表示系统调用失败(暂不区分错误类型)。
- * 常见异常如文件不存在、权限不足、通道类型不符、网络故障等。
- *
- *
- * @param stack 当前操作数栈
- * @param e 捕获的异常对象
- */
- private static void pushErr(OperandStack stack, Exception e) {
- stack.push(-1); // 目前统一用 -1,后续可按异常类型/errno 映射
- }
/*--------------------------------------------------------------------------------*/
@@ -92,10 +57,10 @@ public class SyscallCommand implements Command {
* 支持基础文件、网络、管道等 I/O 操作,并对异常统一处理。
*
*
- * @param parts 指令字符串数组,parts[1] 为子命令
- * @param pc 当前指令计数器
- * @param stack 操作数栈
- * @param locals 局部变量表
+ * @param parts 指令字符串数组,parts[1] 为子命令
+ * @param pc 当前指令计数器
+ * @param stack 操作数栈
+ * @param locals 局部变量表
* @param callStack 调用栈
* @return 下一条指令的 pc 值(默认 pc+1)
*/
@@ -345,35 +310,24 @@ public class SyscallCommand implements Command {
/*
* PRINT —— 控制台输出(无换行)。
- * 入栈顺序: data(String 或 byte[])
+ * 入栈顺序: data(任意基本类型或其包装类型、String、byte[] 等)
* 出栈顺序: data
* 返回 0
*/
case "PRINT" -> {
Object dataObj = stack.pop();
- if (dataObj instanceof byte[] b) {
- System.out.print(new String(b));
- } else {
- System.out.print(dataObj);
- }
- stack.push(0); // 表示成功
+ output(dataObj, false);
+ stack.push(0); // success
}
- /*
- * PRINTLN —— 控制台输出(自动换行)。
- * 入栈顺序: data(String 或 byte[])
- * 出栈顺序: data
- * 返回 0
- */
+
+ /* PRINTLN —— 控制台输出(自动换行)。*/
case "PRINTLN" -> {
Object dataObj = stack.pop();
- if (dataObj instanceof byte[] b) {
- System.out.println(new String(b));
- } else {
- System.out.println(dataObj);
- }
- stack.push(0); // 表示成功
+ output(dataObj, true);
+ stack.push(0); // success
}
+
/*==================== 其它未实现/扩展命令 ====================*/
/*
@@ -389,4 +343,83 @@ public class SyscallCommand implements Command {
// 默认:下一条指令
return pc + 1;
}
+
+ /*------------------------------------ 工具方法 ------------------------------------*/
+
+ /**
+ * POSIX open 标志到 Java NIO OpenOption 的映射
+ *
+ * 将 Linux/UNIX 的 open 调用 flags 参数,转换为 Java NIO 的 OpenOption 集合。
+ * 目前仅支持 WRITE(0x1)、READ、CREATE(0x40)、TRUNCATE(0x200)、APPEND(0x400)等常用标志。
+ *
+ *
+ * @param flags POSIX 风格 open 标志(如 O_WRONLY=0x1, O_CREAT=0x40 等)
+ * @return 映射后的 OpenOption 集合
+ */
+ private static Set flagsToOptions(int flags) {
+ Set opts = new HashSet<>();
+ // 0x1 = WRITE,否则默认 READ
+ if ((flags & 0x1) != 0) opts.add(WRITE);
+ else opts.add(READ);
+ if ((flags & 0x40) != 0) opts.add(CREATE);
+ if ((flags & 0x200) != 0) opts.add(TRUNCATE_EXISTING);
+ if ((flags & 0x400) != 0) opts.add(APPEND);
+ return opts;
+ }
+
+ /**
+ * 统一异常处理:
+ *
+ * 捕获 syscall 内部所有异常,将 -1 压入操作数栈,表示系统调用失败(暂不区分错误类型)。
+ * 常见异常如文件不存在、权限不足、通道类型不符、网络故障等。
+ *
+ *
+ * @param stack 当前操作数栈
+ * @param e 捕获的异常对象
+ */
+ private static void pushErr(OperandStack stack, Exception e) {
+ stack.push(-1); // 目前统一用 -1,后续可按异常类型/errno 映射
+ }
+
+ /**
+ * 统一的控制台输出辅助方法,支持:
+ *
+ * - 所有基本类型及其包装类(int、double、long、float…)
+ * - String、byte[]、char[] 以及其他原生数组
+ * - 任意 Object(调用 {@code toString})
+ *
+ *
+ * @param obj 要输出的对象
+ * @param newline 是否追加换行
+ */
+ 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);
+ }
+
+ /**
+ * 将各种原生数组转换成可读字符串。
+ */
+ 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";
+ }
}