diff --git a/src/main/java/org/jcnc/snow/compiler/Main.java b/src/main/java/org/jcnc/snow/compiler/Main.java
index 6c4cffe..5298ae3 100644
--- a/src/main/java/org/jcnc/snow/compiler/Main.java
+++ b/src/main/java/org/jcnc/snow/compiler/Main.java
@@ -34,14 +34,9 @@ public class Main {
// 3. 可读地打印 AST
ASTPrinter.print(ast);
- // 1) 输出紧凑 JSON
- String compact = ASTJsonSerializer.toJsonString(ast);
-// System.out.println("=== Compact JSON ===");
-// System.out.println(compact);
-
- // 2) 输出美化后的 JSON
+ // 4. AST JSON
System.out.println("=== Pretty JSON ===");
- System.out.println(JsonFormatter.prettyPrint(compact));
+ System.out.println(JsonFormatter.prettyPrint(ASTJsonSerializer.toJsonString(ast)));
}
}
\ No newline at end of file
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/util/ASTJsonSerializer.java b/src/main/java/org/jcnc/snow/compiler/parser/util/ASTJsonSerializer.java
index 2d643a2..1b3c023 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/util/ASTJsonSerializer.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/util/ASTJsonSerializer.java
@@ -4,183 +4,170 @@ import org.jcnc.snow.compiler.parser.ast.*;
import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode;
import org.jcnc.snow.compiler.parser.ast.base.Node;
-import java.util.List;
-import java.util.function.Function;
-import java.util.stream.Collectors;
+import java.util.*;
+/**
+ * ASTJsonSerializer 工具类
+ *
+ * 将编译器生成的 AST(抽象语法树)节点列表转换为通用的 Map/List 结构
+ * 并借助 JSONParser.toJson(Object) 方法序列化为 JSON 字符串。
+ *
+ * 支持的节点类型包括:ModuleNode、FunctionNode、DeclarationNode、
+ * AssignmentNode、IfNode、LoopNode、ReturnNode、ExpressionStatementNode
+ * 以及各种 ExpressionNode(如 BinaryExpressionNode、IdentifierNode 等)。
+ */
public class ASTJsonSerializer {
- public static String toJsonString(List ast) {
- return ast.stream()
- .map(ASTJsonSerializer::nodeToJson)
- .collect(Collectors.joining(",", "[", "]"));
+ /**
+ * 快速创建一个 LinkedHashMap,并写入 type 字段
+ */
+ private static Map newNodeMap(String type) {
+ Map m = new LinkedHashMap<>();
+ m.put("type", type);
+ return m;
}
- private static String nodeToJson(Node n) {
- return switch (n) {
- case ModuleNode m -> moduleToJson(m);
- case FunctionNode f -> functionToJson(f);
- case DeclarationNode d -> declarationToJson(d);
- case AssignmentNode a -> assignmentToJson(a);
- case IfNode i -> ifToJson(i);
- case LoopNode l -> loopToJson(l);
- case ReturnNode r -> returnToJson(r);
- case ExpressionStatementNode e -> exprStmtToJson(e);
- default -> simpleTypeJson(n.getClass().getSimpleName());
- };
- }
-
- private static String moduleToJson(ModuleNode m) {
- return """
- {"type":"Module","name":%1$s,"imports":%2$s,"functions":%3$s}
- """.formatted(
- quote(m.name()),
- listToJsonArray(m.imports(),
- imp -> String.format("{\"type\":\"Import\",\"module\":%s}", quote(imp.moduleName()))
- ),
- listToJsonArray(m.functions(), ASTJsonSerializer::functionToJson)
- );
- }
-
- private static String functionToJson(FunctionNode f) {
- return """
- {"type":"Function","name":%1$s,"parameters":%2$s,"returnType":%3$s,"body":%4$s}
- """.formatted(
- quote(f.name()),
- listToJsonArray(f.parameters(),
- p -> String.format("{\"name\":%s,\"type\":%s}", quote(p.name()), quote(p.type()))
- ),
- quote(f.returnType()),
- listToJsonArray(f.body(), ASTJsonSerializer::nodeToJson)
- );
- }
-
- private static String declarationToJson(DeclarationNode d) {
- var base = new StringBuilder();
- base.append("""
- {"type":"Declaration","name":%1$s,"varType":%2$s
- """.formatted(quote(d.getName()), quote(d.getType())));
- d.getInitializer().ifPresent(init ->
- base.append(",\"initializer\":").append(exprToJson(init))
- );
- base.append("}");
- return base.toString();
- }
-
- private static String assignmentToJson(AssignmentNode a) {
- return """
- {"type":"Assignment","variable":%1$s,"value":%2$s}
- """.formatted(quote(a.variable()), exprToJson(a.value()));
- }
-
- private static String ifToJson(IfNode i) {
- var thenJson = listToJsonArray(i.thenBranch(), ASTJsonSerializer::nodeToJson);
- var elseJson = i.elseBranch().isEmpty() ? ""
- : ",\"else\":" + listToJsonArray(i.elseBranch(), ASTJsonSerializer::nodeToJson);
- return """
- {"type":"If","condition":%1$s,"then":%2$s%3$s}
- """.formatted(exprToJson(i.condition()), thenJson, elseJson);
- }
-
- private static String loopToJson(LoopNode l) {
- return """
- {"type":"Loop","initializer":%1$s,"condition":%2$s,"update":%3$s,"body":%4$s}
- """.formatted(
- l.initializer() != null ? nodeToJson(l.initializer()) : "null",
- l.condition() != null ? exprToJson(l.condition()) : "null",
- l.update() != null ? nodeToJson(l.update()) : "null",
- listToJsonArray(l.body(), ASTJsonSerializer::nodeToJson)
- );
- }
-
- private static String returnToJson(ReturnNode r) {
- var sb = new StringBuilder("{\"type\":\"Return\"");
- r.getExpression().ifPresent(expr ->
- sb.append(",\"value\":").append(exprToJson(expr))
- );
- sb.append("}");
- return sb.toString();
- }
-
- private static String exprStmtToJson(ExpressionStatementNode e) {
- return """
- {"type":"ExpressionStatement","expression":%s}
- """.formatted(exprToJson(e.expression()));
- }
-
- private static String exprToJson(ExpressionNode expr) {
- return switch (expr) {
- case BinaryExpressionNode b -> binaryToJson(b);
- case IdentifierNode id -> idToJson(id);
- case NumberLiteralNode n -> numToJson(n);
- case StringLiteralNode s -> strToJson(s);
- case CallExpressionNode c -> callToJson(c);
- case MemberExpressionNode m -> memberToJson(m);
- default -> simpleTypeJson(expr.getClass().getSimpleName());
- };
- }
-
- private static String binaryToJson(BinaryExpressionNode b) {
- return """
- {"type":"BinaryExpression","left":%1$s,"operator":%2$s,"right":%3$s}
- """.formatted(exprToJson(b.left()), quote(b.operator()), exprToJson(b.right()));
- }
-
- private static String idToJson(IdentifierNode id) {
- return """
- {"type":"Identifier","name":%s}
- """.formatted(quote(id.name()));
- }
-
- private static String numToJson(NumberLiteralNode n) {
- return """
- {"type":"NumberLiteral","value":%s}
- """.formatted(quote(n.value()));
- }
-
- private static String strToJson(StringLiteralNode s) {
- return """
- {"type":"StringLiteral","value":%s}
- """.formatted(quote(s.value()));
- }
-
- private static String callToJson(CallExpressionNode c) {
- return """
- {"type":"CallExpression","callee":%1$s,"arguments":%2$s}
- """.formatted(exprToJson(c.callee()), listToJsonArray(c.arguments(), ASTJsonSerializer::exprToJson));
- }
-
- private static String memberToJson(MemberExpressionNode m) {
- return """
- {"type":"MemberExpression","object":%1$s,"member":%2$s}
- """.formatted(exprToJson(m.object()), quote(m.member()));
- }
-
- // ======== 通用辅助 ========
-
- private static String simpleTypeJson(String typeName) {
- return "{\"type\":" + quote(typeName) + "}";
- }
-
- private static String listToJsonArray(List list, Function mapper) {
- return list.stream()
- .map(mapper)
- .collect(Collectors.joining(",", "[", "]"));
- }
-
- private static String quote(String s) {
- var sb = new StringBuilder("\"");
- for (char c : s.toCharArray()) {
- switch (c) {
- case '\\' -> sb.append("\\\\");
- case '\"' -> sb.append("\\\"");
- case '\n' -> sb.append("\\n");
- case '\r' -> sb.append("\\r");
- case '\t' -> sb.append("\\t");
- default -> sb.append(c);
- }
+ /**
+ * 用于构建表达式节点的 Map
+ */
+ private static Map exprMap(String type, Object... kv) {
+ Map m = new LinkedHashMap<>();
+ m.put("type", type);
+ for (int i = 0; i < kv.length; i += 2) {
+ m.put((String) kv[i], kv[i + 1]);
}
- sb.append('"');
- return sb.toString();
+ return m;
}
-}
+
+ /**
+ * 将 AST 根节点列表序列化为 JSON 字符串。
+ *
+ * @param ast 表示抽象语法树根节点的 List
+ * @return 对应的 JSON 格式字符串
+ */
+ public static String toJsonString(List ast) {
+ List