refactor:重构 PRINT 和 PRINTLN 功能并优化输出方法

- 重构了 PRINT 和 PRINTLN 指令的实现,支持更多数据类型输出
- 新增通用的 output辅助方法,统一处理各种类型的输出
- 扩展了输出功能,支持基本类型、数组和任意对象的打印
- 优化了代码结构,提高了可读性和可维护性
This commit is contained in:
Luke 2025-07-19 00:09:17 +08:00
parent 8ec5120e54
commit 4e3de185b8

View File

@ -46,42 +46,7 @@ import static java.nio.file.StandardOpenOption.*;
*/ */
public class SyscallCommand implements Command { public class SyscallCommand implements Command {
/*------------------------------------ 工具方法 ------------------------------------*/
/**
* <b>POSIX open 标志到 Java NIO OpenOption 的映射</b>
* <p>
* Linux/UNIX open 调用 flags 参数转换为 Java NIO OpenOption 集合
* 目前仅支持 WRITE0x1READCREATE0x40TRUNCATE0x200APPEND0x400等常用标志
* </p>
*
* @param flags POSIX 风格 open 标志 O_WRONLY=0x1, O_CREAT=0x40
* @return 映射后的 OpenOption 集合
*/
private static Set<OpenOption> flagsToOptions(int flags) {
Set<OpenOption> 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;
}
/**
* <b>统一异常处理</b>
* <p>
* 捕获 syscall 内部所有异常 -1 压入操作数栈表示系统调用失败暂不区分错误类型
* 常见异常如文件不存在权限不足通道类型不符网络故障等
* </p>
*
* @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 操作并对异常统一处理 * 支持基础文件网络管道等 I/O 操作并对异常统一处理
* </p> * </p>
* *
* @param parts 指令字符串数组parts[1] 为子命令 * @param parts 指令字符串数组parts[1] 为子命令
* @param pc 当前指令计数器 * @param pc 当前指令计数器
* @param stack 操作数栈 * @param stack 操作数栈
* @param locals 局部变量表 * @param locals 局部变量表
* @param callStack 调用栈 * @param callStack 调用栈
* @return 下一条指令的 pc 默认 pc+1 * @return 下一条指令的 pc 默认 pc+1
*/ */
@ -345,35 +310,24 @@ public class SyscallCommand implements Command {
/* /*
* PRINT 控制台输出无换行 * PRINT 控制台输出无换行
* 入栈顺序: dataString byte[] * 入栈顺序: data任意基本类型或其包装类型Stringbyte[]
* 出栈顺序: data * 出栈顺序: data
* 返回 0 * 返回 0
*/ */
case "PRINT" -> { case "PRINT" -> {
Object dataObj = stack.pop(); Object dataObj = stack.pop();
if (dataObj instanceof byte[] b) { output(dataObj, false);
System.out.print(new String(b)); stack.push(0); // success
} else {
System.out.print(dataObj);
}
stack.push(0); // 表示成功
} }
/*
* PRINTLN 控制台输出自动换行 /* PRINTLN —— 控制台输出(自动换行)。*/
* 入栈顺序: dataString byte[]
* 出栈顺序: data
* 返回 0
*/
case "PRINTLN" -> { case "PRINTLN" -> {
Object dataObj = stack.pop(); Object dataObj = stack.pop();
if (dataObj instanceof byte[] b) { output(dataObj, true);
System.out.println(new String(b)); stack.push(0); // success
} else {
System.out.println(dataObj);
}
stack.push(0); // 表示成功
} }
/*==================== 其它未实现/扩展命令 ====================*/ /*==================== 其它未实现/扩展命令 ====================*/
/* /*
@ -389,4 +343,83 @@ public class SyscallCommand implements Command {
// 默认下一条指令 // 默认下一条指令
return pc + 1; return pc + 1;
} }
/*------------------------------------ 工具方法 ------------------------------------*/
/**
* <b>POSIX open 标志到 Java NIO OpenOption 的映射</b>
* <p>
* Linux/UNIX open 调用 flags 参数转换为 Java NIO OpenOption 集合
* 目前仅支持 WRITE0x1READCREATE0x40TRUNCATE0x200APPEND0x400等常用标志
* </p>
*
* @param flags POSIX 风格 open 标志 O_WRONLY=0x1, O_CREAT=0x40
* @return 映射后的 OpenOption 集合
*/
private static Set<OpenOption> flagsToOptions(int flags) {
Set<OpenOption> 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;
}
/**
* <b>统一异常处理</b>
* <p>
* 捕获 syscall 内部所有异常 -1 压入操作数栈表示系统调用失败暂不区分错误类型
* 常见异常如文件不存在权限不足通道类型不符网络故障等
* </p>
*
* @param stack 当前操作数栈
* @param e 捕获的异常对象
*/
private static void pushErr(OperandStack stack, Exception e) {
stack.push(-1); // 目前统一用 -1后续可按异常类型/errno 映射
}
/**
* 统一的控制台输出辅助方法支持
* <ul>
* <li>所有基本类型及其包装类intdoublelongfloat</li>
* <li>Stringbyte[]char[] 以及其他原生数组</li>
* <li>任意 Object调用 {@code toString}</li>
* </ul>
*
* @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";
}
} }