'B'; // 字节型
case Double _ -> 'D'; // 双精度浮点型
case Float _ -> 'F'; // 单精度浮点型
+ case Boolean _ -> 'I'; // 布尔(作为 0/1 整型存储)
case null, default ->
throw new IllegalStateException("Unknown const type: " + (value != null ? value.getClass() : null));
};
diff --git a/src/main/java/org/jcnc/snow/compiler/backend/util/IROpCodeMapper.java b/src/main/java/org/jcnc/snow/compiler/backend/util/IROpCodeMapper.java
index 4ff674d..757e8a8 100644
--- a/src/main/java/org/jcnc/snow/compiler/backend/util/IROpCodeMapper.java
+++ b/src/main/java/org/jcnc/snow/compiler/backend/util/IROpCodeMapper.java
@@ -82,7 +82,7 @@ public final class IROpCodeMapper {
opcodeMap.put(IROpCode.NEG_D64, "D_NEG");
// 比较运算映射
- opcodeMap.put(IROpCode.CMP_EQ, "IC_EQ"); // 相等
+ opcodeMap.put(IROpCode.CMP_EQ, "IC_E"); // 相等
opcodeMap.put(IROpCode.CMP_NE, "IC_NE"); // 不等
opcodeMap.put(IROpCode.CMP_LT, "IC_L"); // 小于
opcodeMap.put(IROpCode.CMP_GT, "IC_G"); // 大于
diff --git a/src/main/java/org/jcnc/snow/compiler/ir/builder/ExpressionBuilder.java b/src/main/java/org/jcnc/snow/compiler/ir/builder/ExpressionBuilder.java
index a68120f..a658d9d 100644
--- a/src/main/java/org/jcnc/snow/compiler/ir/builder/ExpressionBuilder.java
+++ b/src/main/java/org/jcnc/snow/compiler/ir/builder/ExpressionBuilder.java
@@ -44,23 +44,27 @@ public record ExpressionBuilder(IRContext ctx) {
*/
public IRVirtualRegister build(ExpressionNode expr) {
return switch (expr) {
- // 数字字面量,如 "123", "1.0f"
+ // 数字字面量
case NumberLiteralNode n -> buildNumberLiteral(n.value());
- // 标识符,如变量x,直接查作用域
+ // 布尔字面量
+ case BoolLiteralNode b -> buildBoolLiteral(b.getValue());
+ // 标识符
case IdentifierNode id -> {
IRVirtualRegister reg = ctx.getScope().lookup(id.name());
- if (reg == null) throw new IllegalStateException("未定义标识符: " + id.name());
+ if (reg == null)
+ throw new IllegalStateException("未定义标识符: " + id.name());
yield reg;
}
- // 二元表达式,如 "a + b"
+ // 二元表达式
case BinaryExpressionNode bin -> buildBinary(bin);
- // 函数调用,如 foo(a, b)
+ // 函数调用
case CallExpressionNode call -> buildCall(call);
- // 其它不支持
- default -> throw new IllegalStateException("不支持的表达式类型: " + expr.getClass().getSimpleName());
+ default -> throw new IllegalStateException(
+ "不支持的表达式类型: " + expr.getClass().getSimpleName());
};
}
+
/**
* 直接将表达式计算结果写入指定的目标寄存器(dest)。
*
@@ -91,8 +95,6 @@ public record ExpressionBuilder(IRContext ctx) {
}
}
- // ===================== 内部私有方法 =====================
-
/**
* 构建二元表达式的IR,生成新寄存器存储结果。
*
@@ -179,4 +181,12 @@ public record ExpressionBuilder(IRContext ctx) {
ctx.addInstruction(new LoadConstInstruction(reg, constant));
return reg;
}
+
+ /** 布尔字面量 → CONST (true=1,false=0)*/
+ private IRVirtualRegister buildBoolLiteral(boolean value) {
+ IRConstant constant = new IRConstant(value ? 1 : 0);
+ IRVirtualRegister reg = ctx.newRegister();
+ ctx.addInstruction(new LoadConstInstruction(reg, constant));
+ return reg;
+ }
}
diff --git a/src/main/java/org/jcnc/snow/compiler/lexer/token/TokenFactory.java b/src/main/java/org/jcnc/snow/compiler/lexer/token/TokenFactory.java
index ab7b9e3..98155f6 100644
--- a/src/main/java/org/jcnc/snow/compiler/lexer/token/TokenFactory.java
+++ b/src/main/java/org/jcnc/snow/compiler/lexer/token/TokenFactory.java
@@ -28,19 +28,12 @@ public class TokenFactory {
/**
* 语言的保留关键字集合。
*/
- private static final Set KEYWORDS = Set.of(
- "module", "function", "parameter", "return_type",
- "body", "end", "if", "then", "else", "loop",
- "declare", "return", "import",
- "initializer", "condition", "update"
- );
+ private static final Set KEYWORDS = Set.of("module", "function", "parameter", "return_type", "body", "end", "if", "then", "else", "loop", "declare", "return", "import", "initializer", "condition", "update");
/**
* 内置类型名称集合,如 int、string 等。
*/
- private static final Set TYPES = Set.of(
- "int", "string", "float", "bool", "void", "double", "long", "short", "byte"
- );
+ private static final Set TYPES = Set.of("int", "string", "float", "boolean", "void", "double", "long", "short", "byte");
/**
* 创建一个根据内容自动推断类型的 {@link Token} 实例。
@@ -69,15 +62,30 @@ public class TokenFactory {
* @return 推断出的 {@link TokenType} 类型
*/
private static TokenType determineTokenType(String raw) {
+ if (isABoolean(raw)) return TokenType.BOOL_LITERAL;
if (isType(raw)) return TokenType.TYPE;
if (isKeyword(raw)) return TokenType.KEYWORD;
if (isIdentifier(raw)) return TokenType.IDENTIFIER;
return TokenType.UNKNOWN;
}
+ /**
+ * 判断指定字符串是否为布尔字面量("true" 或 "false")。
+ *
+ * 本方法通过字符串比较,判断输入是否严格等于 "true" 或 "false"。
+ *
+ * @param raw 待判断的字符串
+ * @return 若为布尔字面量,则返回 {@code true};否则返回 {@code false}
+ */
+ private static boolean isABoolean(String raw) {
+ return "true".equals(raw) || "false".equals(raw);
+ }
+
/**
* 判断指定字符串是否为内置类型标识。
*
+ * 本方法用于辅助语义分析或类型识别,判断输入字符串是否存在于预定义的类型集合 {@code TYPES} 中。
+ *
* @param raw 输入的字符串
* @return 若为类型名则返回 {@code true},否则返回 {@code false}
*/
@@ -85,6 +93,7 @@ public class TokenFactory {
return TYPES.contains(raw);
}
+
/**
* 判断指定字符串是否为语言保留关键字。
*
diff --git a/src/main/java/org/jcnc/snow/compiler/lexer/token/TokenType.java b/src/main/java/org/jcnc/snow/compiler/lexer/token/TokenType.java
index db7f087..4ff4394 100644
--- a/src/main/java/org/jcnc/snow/compiler/lexer/token/TokenType.java
+++ b/src/main/java/org/jcnc/snow/compiler/lexer/token/TokenType.java
@@ -19,6 +19,8 @@ public enum TokenType {
/** 内置类型名称(如 int、string、bool 等) */
TYPE,
+ /** 布尔字面量 (true / false) */
+ BOOL_LITERAL,
/** 字符串字面量(如 "hello") */
STRING_LITERAL,
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/BoolLiteralNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/BoolLiteralNode.java
new file mode 100644
index 0000000..a82b98c
--- /dev/null
+++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/BoolLiteralNode.java
@@ -0,0 +1,39 @@
+package org.jcnc.snow.compiler.parser.ast;
+
+import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode;
+
+/**
+ * 表示布尔字面量(boolean literal)的抽象语法树(AST)节点。
+ *
+ * 本类实现了 {@link ExpressionNode} 接口,用于在编译器前端构建语法分析过程中,
+ * 表达布尔类型的字面量常量(如 "true" 或 "false")。
+ *
+ */
+public class BoolLiteralNode implements ExpressionNode {
+ /**
+ * 字面量的布尔值。
+ */
+ private final boolean value;
+
+ /**
+ * 使用布尔字面量字符串构造一个 {@code BoolLiteralNode} 实例。
+ *
+ * 本构造方法接受一个字符串词素(lexeme),并通过 {@link Boolean#parseBoolean(String)} 解析为布尔值。
+ * 如果传入的字符串为 "true"(忽略大小写),则解析结果为 {@code true};否则为 {@code false}。
+ *
+ *
+ * @param lexeme 布尔字面量的字符串表示
+ */
+ public BoolLiteralNode(String lexeme) {
+ this.value = Boolean.parseBoolean(lexeme);
+ }
+
+ /**
+ * 返回此布尔字面量节点的值。
+ *
+ * @return 布尔值,代表源代码中的布尔字面量
+ */
+ public boolean getValue() {
+ return value;
+ }
+}
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/expression/BoolLiteralParselet.java b/src/main/java/org/jcnc/snow/compiler/parser/expression/BoolLiteralParselet.java
new file mode 100644
index 0000000..cb2ede5
--- /dev/null
+++ b/src/main/java/org/jcnc/snow/compiler/parser/expression/BoolLiteralParselet.java
@@ -0,0 +1,33 @@
+package org.jcnc.snow.compiler.parser.expression;
+
+import org.jcnc.snow.compiler.lexer.token.Token;
+import org.jcnc.snow.compiler.parser.ast.BoolLiteralNode;
+import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode;
+import org.jcnc.snow.compiler.parser.context.ParserContext;
+import org.jcnc.snow.compiler.parser.expression.base.PrefixParselet;
+
+/**
+ * {@code BoolLiteralParselet} 是用于解析布尔字面量的前缀解析子(prefix parselet)。
+ *
+ * 本类实现了 {@link PrefixParselet} 接口,用于在语法分析阶段将布尔类型的词法单元(如 "true" 或 "false")
+ * 转换为相应的抽象语法树(AST)节点 {@link BoolLiteralNode}。
+ */
+public class BoolLiteralParselet implements PrefixParselet {
+
+ /**
+ * 解析布尔字面量的词法单元,并返回对应的布尔字面量节点。
+ *
+ * 本方法被语法分析器在遇到布尔字面量词法单元时调用。
+ * 它将词法单元的词素(lexeme)传递给 {@link BoolLiteralNode} 构造器,
+ * 并返回构造得到的 AST 节点。
+ *
+ *
+ * @param ctx 当前的语法分析上下文,用于提供所需的解析信息
+ * @param token 代表布尔字面量的词法单元
+ * @return 对应的 {@link BoolLiteralNode} 实例
+ */
+ @Override
+ public ExpressionNode parse(ParserContext ctx, Token token) {
+ return new BoolLiteralNode(token.getLexeme());
+ }
+}
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/expression/PrattExpressionParser.java b/src/main/java/org/jcnc/snow/compiler/parser/expression/PrattExpressionParser.java
index 5edcf69..1a1d124 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/expression/PrattExpressionParser.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/expression/PrattExpressionParser.java
@@ -43,6 +43,7 @@ public class PrattExpressionParser implements ExpressionParser {
prefixes.put(TokenType.IDENTIFIER.name(), new IdentifierParselet());
prefixes.put(TokenType.LPAREN.name(), new GroupingParselet());
prefixes.put(TokenType.STRING_LITERAL.name(), new StringLiteralParselet());
+ prefixes.put(TokenType.BOOL_LITERAL.name(), new BoolLiteralParselet());
// 注册中缀解析器
infixes.put("+", new BinaryOperatorParselet(Precedence.SUM, true));
diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/TypeUtils.java b/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/TypeUtils.java
new file mode 100644
index 0000000..0ecfab1
--- /dev/null
+++ b/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/TypeUtils.java
@@ -0,0 +1,33 @@
+package org.jcnc.snow.compiler.semantic.analyzers;
+
+import org.jcnc.snow.compiler.semantic.type.BuiltinType;
+import org.jcnc.snow.compiler.semantic.type.Type;
+
+/**
+ * 实用类型辅助工具类,提供与类型相关的静态方法。
+ *
+ * 本类为静态工具类,无法被实例化,仅用于类型判断等功能。
+ *
+ */
+public final class TypeUtils {
+ /**
+ * 私有构造方法,防止实例化工具类。
+ */
+ private TypeUtils() {
+ // 工具类不允许被实例化
+ }
+
+ /**
+ * 判断给定类型是否为“逻辑类型”。
+ *
+ * 当前的实现仅判断类型是否不是布尔类型(BOOLEAN)。
+ * 如果类型不是 BOOLEAN,则认为是“逻辑类型”。
+ *
+ *
+ * @param t 需要检查的类型对象
+ * @return 如果 t 不是 {@link BuiltinType#BOOLEAN},则返回 {@code true},否则返回 {@code false}
+ */
+ public static boolean isLogic(Type t) {
+ return t != BuiltinType.BOOLEAN;
+ }
+}
diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/expression/BoolLiteralAnalyzer.java b/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/expression/BoolLiteralAnalyzer.java
new file mode 100644
index 0000000..6824717
--- /dev/null
+++ b/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/expression/BoolLiteralAnalyzer.java
@@ -0,0 +1,42 @@
+package org.jcnc.snow.compiler.semantic.analyzers.expression;
+
+import org.jcnc.snow.compiler.parser.ast.BoolLiteralNode;
+import org.jcnc.snow.compiler.parser.ast.FunctionNode;
+import org.jcnc.snow.compiler.semantic.analyzers.base.ExpressionAnalyzer;
+import org.jcnc.snow.compiler.semantic.core.Context;
+import org.jcnc.snow.compiler.semantic.core.ModuleInfo;
+import org.jcnc.snow.compiler.semantic.symbol.SymbolTable;
+import org.jcnc.snow.compiler.semantic.type.BuiltinType;
+import org.jcnc.snow.compiler.semantic.type.Type;
+
+/**
+ * {@code BoolLiteralAnalyzer} 是布尔字面量表达式的语义分析器。
+ *
+ * 本类实现 {@link ExpressionAnalyzer} 接口,用于在语义分析阶段对 {@link BoolLiteralNode}
+ * 进行类型推断和校验。在此实现中,所有布尔字面量表达式都被直接视为内建布尔类型 {@link BuiltinType#BOOLEAN}。
+ *
+ *
+ * 该分析器不涉及值检查,仅负责返回类型信息,用于后续的类型检查与代码生成阶段。
+ *
+ */
+public class BoolLiteralAnalyzer implements ExpressionAnalyzer {
+
+ /**
+ * 分析布尔字面量表达式的语义,并返回其类型。
+ *
+ * 由于布尔字面量具有确定且固定的类型,本方法始终返回 {@link BuiltinType#BOOLEAN}。
+ *
+ *
+ * @param ctx 当前的语义分析上下文,包含全局编译状态
+ * @param mi 所在模块的信息对象
+ * @param fn 当前分析所在的函数节点
+ * @param locals 当前作用域下的符号表
+ * @param expr 被分析的布尔字面量表达式节点
+ * @return {@link BuiltinType#BOOLEAN},表示布尔类型
+ */
+ @Override
+ public Type analyze(Context ctx, ModuleInfo mi, FunctionNode fn,
+ SymbolTable locals, BoolLiteralNode expr) {
+ return BuiltinType.BOOLEAN;
+ }
+}
diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/statement/IfAnalyzer.java b/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/statement/IfAnalyzer.java
index 3483702..8b82080 100644
--- a/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/statement/IfAnalyzer.java
+++ b/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/statement/IfAnalyzer.java
@@ -2,12 +2,12 @@ package org.jcnc.snow.compiler.semantic.analyzers.statement;
import org.jcnc.snow.compiler.parser.ast.FunctionNode;
import org.jcnc.snow.compiler.parser.ast.IfNode;
+import org.jcnc.snow.compiler.semantic.analyzers.TypeUtils;
import org.jcnc.snow.compiler.semantic.analyzers.base.StatementAnalyzer;
import org.jcnc.snow.compiler.semantic.core.Context;
import org.jcnc.snow.compiler.semantic.core.ModuleInfo;
import org.jcnc.snow.compiler.semantic.error.SemanticError;
import org.jcnc.snow.compiler.semantic.symbol.SymbolTable;
-import org.jcnc.snow.compiler.semantic.type.BuiltinType;
import org.jcnc.snow.compiler.semantic.type.Type;
/**
@@ -15,7 +15,7 @@ import org.jcnc.snow.compiler.semantic.type.Type;
*
* 主要职责如下:
*
- * - 条件表达式类型检查:确认 if 的条件表达式类型为 int(用于真假判断),否则记录语义错误。
+ * - 条件表达式类型检查:确认 if 的条件表达式类型为 boolean,否则记录语义错误。
* - 块级作用域:分别为 then 分支和 else 分支创建独立的符号表(SymbolTable),
* 支持分支内变量的块级作用域,防止分支内声明的变量污染外部或互相干扰,允许分支内变量同名遮蔽。
* - 分支递归分析:对 then 和 else 分支的每条语句递归调用对应的语义分析器,进行语义检查。
@@ -48,9 +48,9 @@ public class IfAnalyzer implements StatementAnalyzer {
var exprAnalyzer = ctx.getRegistry().getExpressionAnalyzer(ifn.condition());
// 对条件表达式执行类型分析
Type condType = exprAnalyzer.analyze(ctx, mi, fn, locals, ifn.condition());
- // 判断条件类型是否为 int(SCompiler 约定 int 表示真假),否则报错
- if (condType != BuiltinType.INT) {
- ctx.getErrors().add(new SemanticError(ifn, "if 条件必须为 int 类型(表示真假)"));
+ // 判断条件类型是否为 boolean,否则报错
+ if (TypeUtils.isLogic(condType)) {
+ ctx.getErrors().add(new SemanticError(ifn, "if 条件必须为 boolean"));
}
// 2. 分析 then 分支
diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/statement/LoopAnalyzer.java b/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/statement/LoopAnalyzer.java
index 7b67005..a00d993 100644
--- a/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/statement/LoopAnalyzer.java
+++ b/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/statement/LoopAnalyzer.java
@@ -2,12 +2,12 @@ package org.jcnc.snow.compiler.semantic.analyzers.statement;
import org.jcnc.snow.compiler.parser.ast.FunctionNode;
import org.jcnc.snow.compiler.parser.ast.LoopNode;
+import org.jcnc.snow.compiler.semantic.analyzers.TypeUtils;
import org.jcnc.snow.compiler.semantic.analyzers.base.StatementAnalyzer;
import org.jcnc.snow.compiler.semantic.core.Context;
import org.jcnc.snow.compiler.semantic.core.ModuleInfo;
import org.jcnc.snow.compiler.semantic.error.SemanticError;
import org.jcnc.snow.compiler.semantic.symbol.SymbolTable;
-import org.jcnc.snow.compiler.semantic.type.BuiltinType;
import org.jcnc.snow.compiler.semantic.type.Type;
/**
@@ -17,7 +17,7 @@ import org.jcnc.snow.compiler.semantic.type.Type;
*
* - 为整个循环体(包括初始化、条件、更新、循环体本身)创建独立的块级符号表(作用域),保证循环内变量与外部隔离。
* - 依次分析初始化语句、条件表达式、更新语句和循环体各语句,并递归检查嵌套的语法结构。
- * - 检查条件表达式的类型必须为 int(布尔条件),否则记录语义错误。
+ * - 检查条件表达式的类型必须为 boolean,否则记录语义错误。
* - 支持所有错误的收集而不中断流程,便于一次性输出全部问题。
*
* 该分析器实现了 SCompiler 语言的块级作用域循环与类型健壮性,是健全语义分析的基础部分。
@@ -53,9 +53,9 @@ public class LoopAnalyzer implements StatementAnalyzer {
// 3. 分析条件表达式(如 for(...; cond; ...) 或 while(cond))
var condAnalyzer = ctx.getRegistry().getExpressionAnalyzer(ln.condition());
Type condType = condAnalyzer.analyze(ctx, mi, fn, loopScope, ln.condition());
- // 条件类型必须为 int(即 bool),否则记录错误
- if (condType != BuiltinType.INT) {
- ctx.getErrors().add(new SemanticError(ln, "loop 条件必须为 int 类型(表示真假)"));
+ // 条件类型必须为 boolean,否则记录错误
+ if (TypeUtils.isLogic(condType)) {
+ ctx.getErrors().add(new SemanticError(ln, "loop 条件必须为 boolean"));
}
// 4. 分析更新语句(如 for(...; ...; update))
diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/core/AnalyzerRegistrar.java b/src/main/java/org/jcnc/snow/compiler/semantic/core/AnalyzerRegistrar.java
index d91d08c..865bb5e 100644
--- a/src/main/java/org/jcnc/snow/compiler/semantic/core/AnalyzerRegistrar.java
+++ b/src/main/java/org/jcnc/snow/compiler/semantic/core/AnalyzerRegistrar.java
@@ -39,6 +39,7 @@ public final class AnalyzerRegistrar {
registry.registerStatementAnalyzer(IfNode.class, new IfAnalyzer());
registry.registerStatementAnalyzer(LoopNode.class, new LoopAnalyzer());
registry.registerStatementAnalyzer(ReturnNode.class, new ReturnAnalyzer());
+ registry.registerExpressionAnalyzer(BoolLiteralNode.class, new BoolLiteralAnalyzer());
// 特殊处理:表达式语句(如 "foo();")作为语句包装表达式
registry.registerStatementAnalyzer(ExpressionStatementNode.class,
diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/core/BuiltinTypeRegistry.java b/src/main/java/org/jcnc/snow/compiler/semantic/core/BuiltinTypeRegistry.java
index 876411e..498f4a9 100644
--- a/src/main/java/org/jcnc/snow/compiler/semantic/core/BuiltinTypeRegistry.java
+++ b/src/main/java/org/jcnc/snow/compiler/semantic/core/BuiltinTypeRegistry.java
@@ -31,6 +31,7 @@ public final class BuiltinTypeRegistry {
"float", BuiltinType.FLOAT,
"double", BuiltinType.DOUBLE,
"string", BuiltinType.STRING,
+ "boolean", BuiltinType.BOOLEAN,
"void", BuiltinType.VOID
);
diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/type/BuiltinType.java b/src/main/java/org/jcnc/snow/compiler/semantic/type/BuiltinType.java
index 0602510..213cd80 100644
--- a/src/main/java/org/jcnc/snow/compiler/semantic/type/BuiltinType.java
+++ b/src/main/java/org/jcnc/snow/compiler/semantic/type/BuiltinType.java
@@ -15,6 +15,7 @@ package org.jcnc.snow.compiler.semantic.type;
* - {@link #FLOAT} - 单精度浮点数
* - {@link #DOUBLE} - 双精度浮点数
* - {@link #STRING} - 字符串类型
+ * - {@link #BOOLEAN} - 布尔类型
* - {@link #VOID} - 空类型,用于表示无返回值的函数
*
*
@@ -34,6 +35,7 @@ public enum BuiltinType implements Type {
FLOAT, // 单精度浮点数
DOUBLE, // 双精度浮点数
STRING, // 字符串类型
+ BOOLEAN, // 布尔类型
VOID; // 空类型,用于表示函数无返回值
/**