From 7bc2ec6ebec9d129e20f567d0e77beb2a87556e4 Mon Sep 17 00:00:00 2001
From: Luke
会根据节点的实际类型分别处理: *
-x(取负,生成 NEG_I32 指令)与x == 0 比较指令)- * 支持的运算符包括: + * 运算符扫描器(OperatorTokenScanner) + * + *
负责在词法分析阶段识别由 = ! < > | & % 等字符 + * 起始的单字符或双字符运算符,并生成相应 {@link Token}:
+ * *- * 不符合上述组合的字符会返回 {@code UNKNOWN} 类型的 Token。 + * + *
如果无法匹配到合法组合,将返回 {@link TokenType#UNKNOWN}。
*/ public class OperatorTokenScanner extends AbstractTokenScanner { /** - * 判断是否可以处理当前位置的字符。 - *运算符扫描器关注的起始字符包括:=、!、<、>、|、&
+ * 判断当前字符是否可能是运算符的起始字符。 * * @param c 当前字符 - * @param ctx 当前词法上下文 - * @return 如果是潜在的运算符起始字符,则返回 true + * @param ctx 词法上下文 + * @return 若是关注的起始字符则返回 {@code true} */ @Override public boolean canHandle(char c, LexerContext ctx) { @@ -32,14 +35,12 @@ public class OperatorTokenScanner extends AbstractTokenScanner { } /** - * 扫描并识别运算符 Token。 - *支持组合运算符判断,如 ==、!=、>= 等, - * 若无法匹配组合形式则退回单字符形式。
+ * 按最长匹配优先原则扫描并生成运算符 token。 * - * @param ctx 词法上下文 + * @param ctx 词法上下文 * @param line 当前行号 - * @param col 当前列号 - * @return 对应的运算符 Token,无法识别的运算符返回 {@code UNKNOWN} + * @param col 当前列号 + * @return 已识别的 {@link Token} */ @Override protected Token scanToken(LexerContext ctx, int line, int col) { @@ -51,64 +52,71 @@ public class OperatorTokenScanner extends AbstractTokenScanner { case '=': if (ctx.match('=')) { lexeme = "=="; - type = TokenType.DOUBLE_EQUALS; + type = TokenType.DOUBLE_EQUALS; } else { lexeme = "="; - type = TokenType.EQUALS; + type = TokenType.EQUALS; } break; + case '!': if (ctx.match('=')) { lexeme = "!="; - type = TokenType.NOT_EQUALS; + type = TokenType.NOT_EQUALS; } else { lexeme = "!"; - type = TokenType.NOT; + type = TokenType.NOT; } break; + case '>': if (ctx.match('=')) { lexeme = ">="; - type = TokenType.GREATER_EQUAL; + type = TokenType.GREATER_EQUAL; } else { lexeme = ">"; - type = TokenType.GREATER_THAN; + type = TokenType.GREATER_THAN; } break; + case '<': if (ctx.match('=')) { lexeme = "<="; - type = TokenType.LESS_EQUAL; + type = TokenType.LESS_EQUAL; } else { lexeme = "<"; - type = TokenType.LESS_THAN; + type = TokenType.LESS_THAN; } break; + case '%': lexeme = "%"; - type = TokenType.MODULO; + type = TokenType.MODULO; break; + case '&': if (ctx.match('&')) { lexeme = "&&"; - type = TokenType.AND; + type = TokenType.AND; } else { lexeme = "&"; - type = TokenType.UNKNOWN; + type = TokenType.UNKNOWN; } break; + case '|': if (ctx.match('|')) { lexeme = "||"; - type = TokenType.OR; + type = TokenType.OR; } else { lexeme = "|"; - type = TokenType.UNKNOWN; + type = TokenType.UNKNOWN; } break; + default: lexeme = String.valueOf(c); - type = TokenType.UNKNOWN; + type = TokenType.UNKNOWN; } return new Token(type, lexeme, line, col); diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/UnaryExpressionNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/UnaryExpressionNode.java index be60c24..d956fc8 100644 --- a/src/main/java/org/jcnc/snow/compiler/parser/ast/UnaryExpressionNode.java +++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/UnaryExpressionNode.java @@ -3,15 +3,29 @@ package org.jcnc.snow.compiler.parser.ast; import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode; /** - * 一元表达式节点,例如 -x 或 !x。 + * {@code UnaryExpressionNode} —— 前缀一元运算 AST 节点。 * - * @param operator 运算符字符串 ("-" / "!") - * @param operand 操作数表达式 + *代表两种受支持的一元前缀表达式: + *
当前 parselet 负责解析两种前缀运算: + *
此类仅负责语法结构的构建: + *
目前实现两种一元运算: + *
分析流程: + *
若遇到未支持的运算符,将生成错误并返回 {@code int} 作为占位类型。
+ * + */ public class UnaryExpressionAnalyzer implements ExpressionAnalyzer
* A root stack frame is pushed once via
* {@link #ensureRootFrame()} before the first instruction executes
* and is never popped. When a {@code RET} executed in the root frame
From 5ab850f354fd753a037398488d5b1b2e5347a462 Mon Sep 17 00:00:00 2001
From: zhangxun <1958638841@qq.com>
Date: Thu, 12 Jun 2025 17:39:04 +0800
Subject: [PATCH 12/24] fix: LXorCommand may be truncated
---
.../org/jcnc/snow/vm/commands/bitwise/long64/LXorCommand.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/java/org/jcnc/snow/vm/commands/bitwise/long64/LXorCommand.java b/src/main/java/org/jcnc/snow/vm/commands/bitwise/long64/LXorCommand.java
index 2a668dd..dbce6ab 100644
--- a/src/main/java/org/jcnc/snow/vm/commands/bitwise/long64/LXorCommand.java
+++ b/src/main/java/org/jcnc/snow/vm/commands/bitwise/long64/LXorCommand.java
@@ -48,8 +48,8 @@ public class LXorCommand implements Command {
}
// Pop the top two operands from the stack
- final int b = (int) operandStack.pop();
- final int a = (int) operandStack.pop();
+ final long b = (long) operandStack.pop();
+ final long a = (long) operandStack.pop();
// Perform the long64 bitwise XOR operation and push the result back onto the stack
operandStack.push(a ^ b);
From 84940af2bd6124e7c9aa14b7b00750ff8b650962 Mon Sep 17 00:00:00 2001
From: Luke
- * 支持的节点类型包括:
+ * 支持的节点类型包括(新增对 {@code BoolLiteralNode}、{@code UnaryExpressionNode} 的完整支持):
*
*
*/
public class ASTJsonSerializer {
@@ -174,19 +176,32 @@ public class ASTJsonSerializer {
*/
private static Object exprToMap(ExpressionNode expr) {
return switch (expr) {
+ // 二元表达式
case BinaryExpressionNode(ExpressionNode left, String operator, ExpressionNode right) -> exprMap("BinaryExpression",
"left", exprToMap(left),
"operator", operator,
"right", exprToMap(right)
);
+ // 一元表达式
+ case UnaryExpressionNode(String operator, ExpressionNode operand) -> exprMap("UnaryExpression",
+ "operator", operator,
+ "operand", exprToMap(operand)
+ );
+ // 布尔字面量
+ case BoolLiteralNode(boolean value) -> exprMap("BoolLiteral", "value", value);
+ // 标识符
case IdentifierNode(String name) -> exprMap("Identifier", "name", name);
+ // 数字字面量
case NumberLiteralNode(String value) -> exprMap("NumberLiteral", "value", value);
+ // 字符串字面量
case StringLiteralNode(String value) -> exprMap("StringLiteral", "value", value);
+ // 调用表达式
case CallExpressionNode(ExpressionNode callee, List