diff --git a/src/main/java/org/jcnc/snow/compiler/cli/SnowCLI.java b/src/main/java/org/jcnc/snow/compiler/cli/SnowCLI.java index b61d2ad..54c7e1a 100644 --- a/src/main/java/org/jcnc/snow/compiler/cli/SnowCLI.java +++ b/src/main/java/org/jcnc/snow/compiler/cli/SnowCLI.java @@ -16,7 +16,7 @@ import java.util.function.Supplier; */ public class SnowCLI { /** Snow 编程语言的版本号。 */ - public static final String VERSION = "1.0.0"; + public static final String SNOW_VERSION = "1.0.0"; /** 全局帮助标志,当输入匹配时显示帮助信息。 */ private static final Set GLOBAL_HELP_FLAGS = Set.of("help", "-h", "--help"); diff --git a/src/main/java/org/jcnc/snow/compiler/cli/commands/CompileCommand.java b/src/main/java/org/jcnc/snow/compiler/cli/commands/CompileCommand.java index d26fa20..0ec51d0 100644 --- a/src/main/java/org/jcnc/snow/compiler/cli/commands/CompileCommand.java +++ b/src/main/java/org/jcnc/snow/compiler/cli/commands/CompileCommand.java @@ -25,22 +25,46 @@ import java.nio.file.Path; import java.util.*; /** - * 编译器命令行入口:实现 `snow compile` 命令。 - * 支持编译一个或多个 .snow 源文件为 VM 字节码文件,选项 -o 指定输出名称(不含后缀), - * -d 递归目录编译(输出名自动取目录名),输出后缀统一为 .water。 + *

+ * 编译器命令实现:`snow compile` + *
+ * 将一个或多个 .snow 源文件编译为 VM 字节码文件(.water)。 + *

+ * + *

+ * 用法:
+ * snow compile [run] [-o <name>] [-d <srcDir>] [file1.snow file2.snow …] + *

*/ public final class CompileCommand implements CLICommand { + /** + * 获取命令名。 + * + * @return "compile" + */ @Override public String name() { return "compile"; } + /** + * 获取命令描述。 + * + * @return 命令简介 + */ @Override public String description() { return "Compile .snow source files into VM byte-code (.water)."; } + /** + * 打印该命令的用法说明。 + */ @Override public void printUsage() { System.out.println("Usage:"); @@ -51,20 +75,13 @@ public final class CompileCommand implements CLICommand { System.out.println(" -d recursively compile all .snow files in directory"); } - private static Path deriveOutputPath(List sources, String outName, Path dir) { - String base; - if (outName != null) { - base = outName; - } else if (dir != null) { - base = dir.getFileName().toString(); - } else if (sources.size() == 1) { - base = sources.getFirst().getFileName().toString().replaceFirst("\\.snow$", ""); - } else { - base = "program"; - } - return Path.of(base + ".water"); - } - + /** + * 执行 compile 命令,编译 .snow 源文件。 + * + * @param args 剩余参数(不含命令名) + * @return 0 表示成功,1 表示参数错误或编译失败 + * @throws Exception 编译过程中可能抛出的异常 + */ @Override public int execute(String[] args) throws Exception { boolean runAfterCompile = false; @@ -107,7 +124,7 @@ public final class CompileCommand implements CLICommand { } } - // 目录编译时收集所有 .snow + // 目录编译时收集所有 .snow 文件 if (dir != null) { if (!Files.isDirectory(dir)) { System.err.println("Not a directory: " + dir); @@ -125,13 +142,13 @@ public final class CompileCommand implements CLICommand { return 1; } - // 多文件非目录编译时必须指定 -o + // 多文件且未指定输出时错误 if (sources.size() > 1 && outputName == null && dir == null) { System.err.println("Please specify output name using -o "); return 1; } - // 1. 词法+语法分析 + // 1. 词法和语法分析 List allAst = new ArrayList<>(); for (Path p : sources) { if (!Files.exists(p)) { @@ -176,7 +193,7 @@ public final class CompileCommand implements CLICommand { Files.write(outputFile, finalCode, StandardCharsets.UTF_8); System.out.println("Written to " + outputFile.toAbsolutePath()); - // 6. 执行 + // 6. 可选执行 if (runAfterCompile) { System.out.println("\n=== Launching VM ==="); VMLauncher.main(new String[]{outputFile.toString()}); @@ -185,7 +202,32 @@ public final class CompileCommand implements CLICommand { } /** - * 保证 main 函数为程序入口 + * 推断输出 .water 文件的路径。 + * + * @param sources 源文件列表 + * @param outName 用户指定的输出基名 + * @param dir 目录编译时的源目录 + * @return 输出文件的完整路径 + */ + private static Path deriveOutputPath(List sources, String outName, Path dir) { + String base; + if (outName != null) { + base = outName; + } else if (dir != null) { + base = dir.getFileName().toString(); + } else if (sources.size() == 1) { + base = sources.get(0).getFileName().toString().replaceFirst("\\.snow$", ""); + } else { + base = "program"; + } + return Path.of(base + ".water"); + } + + /** + * 保证 main 函数为程序入口。 + * + * @param in 输入的 IR 程序 + * @return 重新排序,使 main 函数位于首位的 IR 程序 */ private static IRProgram reorderForEntry(IRProgram in) { List ordered = new ArrayList<>(in.functions()); diff --git a/src/main/java/org/jcnc/snow/compiler/cli/commands/VersionCommand.java b/src/main/java/org/jcnc/snow/compiler/cli/commands/VersionCommand.java index 24f5227..79cffc7 100644 --- a/src/main/java/org/jcnc/snow/compiler/cli/commands/VersionCommand.java +++ b/src/main/java/org/jcnc/snow/compiler/cli/commands/VersionCommand.java @@ -5,33 +5,51 @@ import org.jcnc.snow.compiler.cli.SnowCLI; /** *

- * 子命令:`snow version` + * 子命令实现:`snow version` *
- * 用于打印当前 SnowCLI 的版本号。 + * 用于打印当前 Snow 的版本号。 *

*/ public final class VersionCommand implements CLICommand { + /** + * 获取命令名。 + * + * @return "version" + */ @Override public String name() { return "version"; } + /** + * 获取命令描述。 + * + * @return 命令简介 + */ @Override public String description() { return "Print snow version."; } + /** + * 打印该命令的用法说明。 + */ @Override public void printUsage() { System.out.println("Usage:"); System.out.println(" snow version"); } + /** + * 执行 version 命令,输出当前 Snow 的版本号。 + * + * @param args 命令参数,此命令不接受额外参数 + * @return 0 表示成功执行 + */ @Override public int execute(String[] args) { - // 直接输出 SnowCLI.VERSION 常量 - System.out.println("snow version " + SnowCLI.VERSION); + System.out.println("snow version " + SnowCLI.SNOW_VERSION); return 0; } }