From bb5ba2218fcf6e293f2592b65b30a99750fbe943 Mon Sep 17 00:00:00 2001
From: zhangxun <1958638841@qq.com>
Date: Wed, 25 Jun 2025 11:44:26 +0800
Subject: [PATCH 1/8] =?UTF-8?q?feat:=20=E5=A2=9E=E5=BC=BA=E5=AD=97?=
=?UTF-8?q?=E8=8A=82=E7=A0=81=E6=98=BE=E7=A4=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../snow/compiler/backend/util/OpHelper.java | 34 +++++++++++++++++++
.../org/jcnc/snow/pkg/tasks/CompileTask.java | 10 ++++--
2 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/src/main/java/org/jcnc/snow/compiler/backend/util/OpHelper.java b/src/main/java/org/jcnc/snow/compiler/backend/util/OpHelper.java
index 8c7bba9..947512a 100644
--- a/src/main/java/org/jcnc/snow/compiler/backend/util/OpHelper.java
+++ b/src/main/java/org/jcnc/snow/compiler/backend/util/OpHelper.java
@@ -22,6 +22,11 @@ public final class OpHelper {
*/
private static final Map OPCODE_MAP;
+ /**
+ * opcode 字符串 → 指令名 的静态映射表
+ */
+ private static final Map OPCODE_NAME_MAP;
+
static {
Map map = new HashMap<>();
map.put("I_ADD", Integer.toString(VMOpCode.I_ADD));
@@ -127,6 +132,13 @@ public final class OpHelper {
map.put("RET", Integer.toString(VMOpCode.RET));
map.put("HALT", Integer.toString(VMOpCode.HALT));
OPCODE_MAP = Collections.unmodifiableMap(map);
+
+ Map revmap = new HashMap<>(); // reverse map
+ OPCODE_MAP.forEach((key, value) -> {
+ revmap.put(Integer.parseInt(value), key);
+ });
+
+ OPCODE_NAME_MAP = Collections.unmodifiableMap(revmap);
}
/**
@@ -170,5 +182,27 @@ public final class OpHelper {
throw new IllegalStateException("Unknown const type: " + v.getClass());
}
+ /**
+ * 根据 opcode 数值的字符串形式获取指令名
+ * @param code 字符串形式的 opcode 数值
+ * @return opcode 对应的指令名
+ */
+ public static String opcodeName(String code) {
+ return opcodeName(Integer.parseInt(code));
+ }
+
+ /**
+ * 根据 opcode 获取指令名
+ * @param code opcode
+ * @return opcode 对应的指令名
+ */
+ public static String opcodeName(int code) {
+ String name = OPCODE_NAME_MAP.get(code);
+ if (name == null) {
+ throw new IllegalStateException("Unknown opcode: " + name);
+ }
+ return name;
+ }
+
// endregion
}
\ No newline at end of file
diff --git a/src/main/java/org/jcnc/snow/pkg/tasks/CompileTask.java b/src/main/java/org/jcnc/snow/pkg/tasks/CompileTask.java
index 04519d7..c76537b 100644
--- a/src/main/java/org/jcnc/snow/pkg/tasks/CompileTask.java
+++ b/src/main/java/org/jcnc/snow/pkg/tasks/CompileTask.java
@@ -1,7 +1,7 @@
package org.jcnc.snow.pkg.tasks;
import org.jcnc.snow.cli.commands.CompileCommand;
-import org.jcnc.snow.pkg.model.Project;
+import org.jcnc.snow.compiler.backend.util.OpHelper;
import org.jcnc.snow.compiler.backend.alloc.RegisterAllocator;
import org.jcnc.snow.compiler.backend.builder.VMCodeGenerator;
import org.jcnc.snow.compiler.backend.builder.VMProgramBuilder;
@@ -18,6 +18,7 @@ import org.jcnc.snow.compiler.parser.context.ParserContext;
import org.jcnc.snow.compiler.parser.core.ParserEngine;
import org.jcnc.snow.compiler.parser.function.ASTPrinter;
import org.jcnc.snow.compiler.semantic.core.SemanticAnalyzerRunner;
+import org.jcnc.snow.pkg.model.Project;
import org.jcnc.snow.vm.VMLauncher;
import java.nio.charset.StandardCharsets;
@@ -198,7 +199,12 @@ public final class CompileTask implements Task {
List finalCode = builder.build();
System.out.println("### VM code");
- finalCode.forEach(System.out::println);
+ for (int i = 0; i < finalCode.size(); i++) {
+ String[] parts = finalCode.get(i).split(" ");
+ String name = OpHelper.opcodeName(parts[0]);
+ parts = Arrays.copyOfRange(parts, 1, parts.length);
+ System.out.printf("%04d: %-10s %s\n", i, name, String.join(" ", parts));
+ }
// ---------------- 5. 写出 .water 文件 ----------------
Path outputFile = deriveOutputPath(sources, outputName, dir);
From 6292cdc006f5f8896e6a269079fca600e870faf1 Mon Sep 17 00:00:00 2001
From: zhangxun <1958638841@qq.com>
Date: Wed, 25 Jun 2025 11:46:14 +0800
Subject: [PATCH 2/8] =?UTF-8?q?style:=20=E8=AF=AD=E5=8F=A5=20lambda=20?=
=?UTF-8?q?=E6=9B=BF=E6=8D=A2=E4=B8=BA=E8=A1=A8=E8=BE=BE=E5=BC=8F=20lambda?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../java/org/jcnc/snow/compiler/backend/util/OpHelper.java | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/main/java/org/jcnc/snow/compiler/backend/util/OpHelper.java b/src/main/java/org/jcnc/snow/compiler/backend/util/OpHelper.java
index 947512a..9d2e527 100644
--- a/src/main/java/org/jcnc/snow/compiler/backend/util/OpHelper.java
+++ b/src/main/java/org/jcnc/snow/compiler/backend/util/OpHelper.java
@@ -134,9 +134,7 @@ public final class OpHelper {
OPCODE_MAP = Collections.unmodifiableMap(map);
Map revmap = new HashMap<>(); // reverse map
- OPCODE_MAP.forEach((key, value) -> {
- revmap.put(Integer.parseInt(value), key);
- });
+ OPCODE_MAP.forEach((key, value) -> revmap.put(Integer.parseInt(value), key));
OPCODE_NAME_MAP = Collections.unmodifiableMap(revmap);
}
From 3f5dd92af982a3d78af6d453d3ed564bb8979517 Mon Sep 17 00:00:00 2001
From: Luke
Date: Thu, 26 Jun 2025 12:14:47 +0800
Subject: [PATCH 3/8] =?UTF-8?q?style=EF=BC=9A=E8=B0=83=E6=95=B4=E9=97=B4?=
=?UTF-8?q?=E8=B7=9D=20VMOpCode.java?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../org/jcnc/snow/vm/engine/VMOpCode.java | 124 +++++++-----------
1 file changed, 47 insertions(+), 77 deletions(-)
diff --git a/src/main/java/org/jcnc/snow/vm/engine/VMOpCode.java b/src/main/java/org/jcnc/snow/vm/engine/VMOpCode.java
index 5080fee..f5e8762 100644
--- a/src/main/java/org/jcnc/snow/vm/engine/VMOpCode.java
+++ b/src/main/java/org/jcnc/snow/vm/engine/VMOpCode.java
@@ -47,8 +47,8 @@ import org.jcnc.snow.vm.module.LocalVariableStore;
* Each opcode represents a specific operation executed by the virtual machine.
*/
public class VMOpCode {
- // region 1. Arithmetic Operations (1–80)
- // region 1.1 int32 (1-10)
+ // region 1. Arithmetic Operations (1–100)
+ // region 1.1 int32 (0-9)
/**
* I_ADD Opcode: Represents the int32 addition operation in the virtual machine.
* This opcode is implemented by the {@link IAddCommand} class, which defines its specific execution logic.
@@ -63,7 +63,7 @@ public class VMOpCode {
* This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic int32 addition tasks.
*/
- public static final int I_ADD = 1;
+ public static final int I_ADD = 0;
/**
* I_SUB Opcode: Represents the int32 subtraction operation in the virtual machine.
* This opcode is implemented by the {@link ISubCommand} class, which defines its specific execution logic.
@@ -78,7 +78,7 @@ public class VMOpCode {
* This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic int32 subtraction tasks.
*/
- public static final int I_SUB = 2;
+ public static final int I_SUB = 1;
/**
* I_MUL Opcode: Represents the int32 multiplication operation in the virtual machine.
* This opcode is implemented by the {@link IMulCommand} class, which defines its specific execution logic.
@@ -93,7 +93,7 @@ public class VMOpCode {
* This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic int32 multiplication tasks.
*/
- public static final int I_MUL = 3;
+ public static final int I_MUL = 2;
/**
* I_DIV Opcode: Represents the int32 division operation in the virtual machine.
* This opcode is implemented by the {@link IDivCommand} class, which defines its specific execution logic.
@@ -109,7 +109,7 @@ public class VMOpCode {
* This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic int32 division tasks.
*/
- public static final int I_DIV = 4;
+ public static final int I_DIV = 3;
/**
* I_MOD Opcode: Represents the int32 modulus (remainder) operation in the virtual machine.
* This opcode is implemented by the {@link IModCommand} class, which defines its specific execution logic.
@@ -125,7 +125,7 @@ public class VMOpCode {
* This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic int32 modulus (remainder) tasks.
*/
- public static final int I_MOD = 5;
+ public static final int I_MOD = 4;
/**
* I_INC Opcode: Represents the int32 increment operation for a local variable in the virtual machine.
* This opcode is implemented by the {@link IIncCommand} class, which defines its specific execution logic.
@@ -142,8 +142,7 @@ public class VMOpCode {
*
* This opcode is particularly useful for optimizing scenarios where a local variable, such as a counter or loop index, is frequently incremented.
*/
- public static final int I_INC = 6;
-
+ public static final int I_INC = 5;
/**
* I_NEG Opcode: Represents the int32 negation operation in the virtual machine.
* This opcode is implemented by the {@link INegCommand} class, which defines its specific execution logic.
@@ -157,10 +156,10 @@ public class VMOpCode {
*
* This opcode is typically used to negate an int32 value, making it a fundamental operation for arithmetic logic within the virtual machine.
*/
- public static final int I_NEG = 7;
-
+ public static final int I_NEG = 6;
// endregion
- // region 1.2 long64 (11-20)
+
+ // region 1.2 long64 (10-19)
/**
* L_ADD Opcode: Represents the long64 addition operation in the virtual machine.
* This opcode is implemented by the {@link LAddCommand} class, which defines its specific execution logic.
@@ -175,8 +174,7 @@ public class VMOpCode {
* This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic long64 addition tasks.
*/
- public static final int L_ADD = 11;
-
+ public static final int L_ADD = 10;
/**
* L_SUB Opcode: Represents the long64 subtraction operation in the virtual machine.
* This opcode is implemented by the {@link LSubCommand} class, which defines its specific execution logic.
@@ -191,8 +189,7 @@ public class VMOpCode {
* This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic long64 subtraction tasks.
*/
- public static final int L_SUB = 12;
-
+ public static final int L_SUB = 11;
/**
* L_MUL Opcode: Represents the long64 multiplication operation in the virtual machine.
* This opcode is implemented by the {@link LMulCommand} class, which defines its specific execution logic.
@@ -207,8 +204,7 @@ public class VMOpCode {
* This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic long64 multiplication tasks.
*/
- public static final int L_MUL = 13;
-
+ public static final int L_MUL = 12;
/**
* L_DIV Opcode: Represents the long64 division operation in the virtual machine.
* This opcode is implemented by the {@link LDivCommand} class, which defines its specific execution logic.
@@ -224,8 +220,7 @@ public class VMOpCode {
* This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic long64 division tasks.
*/
- public static final int L_DIV = 14;
-
+ public static final int L_DIV = 13;
/**
* L_MOD Opcode: Represents the long64 modulus (remainder) operation in the virtual machine.
* This opcode is implemented by the {@link LModCommand} class, which defines its specific execution logic.
@@ -241,8 +236,7 @@ public class VMOpCode {
* This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic long64 modulus (remainder) tasks.
*/
- public static final int L_MOD = 15;
-
+ public static final int L_MOD = 14;
/**
* L_INC Opcode: Represents the long64 increment operation for a local variable in the virtual machine.
* This opcode is implemented by the {@link LIncCommand} class, which defines its specific execution logic.
@@ -259,9 +253,7 @@ public class VMOpCode {
*
* This opcode is particularly useful for optimizing scenarios where a local `long64` variable, such as a counter or loop index, is frequently incremented.
*/
- public static final int L_INC = 16;
-
-
+ public static final int L_INC = 15;
/**
* L_NEG Opcode: Represents the long64 negation operation in the virtual machine.
* This opcode is implemented by the {@link LNegCommand} class, which defines its specific execution logic.
@@ -275,10 +267,10 @@ public class VMOpCode {
*
* This opcode is typically used to negate a long64 value, making it a fundamental operation for arithmetic logic within the virtual machine.
*/
- public static final int L_NEG = 17;
-
+ public static final int L_NEG = 16;
// endregion
- // region 1.3 short16 (21-30)
+
+ // region 1.3 short16 (20-29)
/**
* S_ADD Opcode: Represents the short16 addition operation in the virtual machine.
* This opcode is implemented by the {@link SAddCommand} class, which defines its specific execution logic.
@@ -293,8 +285,7 @@ public class VMOpCode {
* This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic short16 addition tasks.
*/
- public static final int S_ADD = 21;
-
+ public static final int S_ADD = 20;
/**
* S_SUB Opcode: Represents the short16 subtraction operation in the virtual machine.
* This opcode is implemented by the {@link SSubCommand} class, which defines its specific execution logic.
@@ -309,8 +300,7 @@ public class VMOpCode {
* This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic short16 subtraction tasks.
*/
- public static final int S_SUB = 22;
-
+ public static final int S_SUB = 21;
/**
* S_MUL Opcode: Represents the short16 multiplication operation in the virtual machine.
* This opcode is implemented by the {@link SMulCommand} class, which defines its specific execution logic.
@@ -325,8 +315,7 @@ public class VMOpCode {
* This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic short16 multiplication tasks.
*/
- public static final int S_MUL = 23;
-
+ public static final int S_MUL = 22;
/**
* S_DIV Opcode: Represents the short16 division operation in the virtual machine.
* This opcode is implemented by the {@link SDivCommand} class, which defines its specific execution logic.
@@ -342,8 +331,7 @@ public class VMOpCode {
* This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic short16 division tasks.
*/
- public static final int S_DIV = 24;
-
+ public static final int S_DIV = 23;
/**
* S_MOD Opcode: Represents the short16 modulus (remainder) operation in the virtual machine.
* This opcode is implemented by the {@link SModCommand} class, which defines its specific execution logic.
@@ -359,8 +347,7 @@ public class VMOpCode {
* This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic short16 modulus (remainder) tasks.
*/
- public static final int S_MOD = 25;
-
+ public static final int S_MOD = 24;
/**
* S_INC Opcode: Represents the short16 increment operation in the virtual machine.
* This opcode is implemented by the {@link SIncCommand} class, which defines its specific execution logic.
@@ -378,8 +365,7 @@ public class VMOpCode {
* This opcode is useful for scenarios where a local variable needs to be incremented, such as counters within loops,
* or for optimizing the modification of variables in tight loops.
*/
- public static final int S_INC = 26;
-
+ public static final int S_INC = 25;
/**
* S_NEG Opcode: Represents the short16 negation operation in the virtual machine.
* This opcode is implemented by the {@link SNegCommand} class, which defines its specific execution logic.
@@ -393,9 +379,9 @@ public class VMOpCode {
*
* This opcode is typically used to negate a short16 value, making it a fundamental operation for arithmetic logic within the virtual machine.
*/
- public static final int S_NEG = 27;
-
+ public static final int S_NEG = 26;
// endregion
+
// region 1.4 byte8 (31-40)
/**
* B_ADD Opcode: Represents the byte8 addition operation in the virtual machine.
@@ -412,7 +398,6 @@ public class VMOpCode {
* primarily used to handle basic byte8 addition tasks.
*/
public static final int B_ADD = 31;
-
/**
* B_SUB Opcode: Represents the byte8 subtraction operation in the virtual machine.
* This opcode is implemented by the {@link BSubCommand} class, which defines its specific execution logic.
@@ -428,7 +413,6 @@ public class VMOpCode {
* primarily used to handle basic byte8 subtraction tasks.
*/
public static final int B_SUB = 32;
-
/**
* B_MUL Opcode: Represents the byte8 multiplication operation in the virtual machine.
* This opcode is implemented by the {@link BMulCommand} class, which defines its specific execution logic.
@@ -444,7 +428,6 @@ public class VMOpCode {
* primarily used to handle basic byte8 multiplication tasks.
*/
public static final int B_MUL = 33;
-
/**
* B_DIV Opcode: Represents the byte8 division operation in the virtual machine.
* This opcode is implemented by the {@link BDivCommand} class, which defines its specific execution logic.
@@ -461,7 +444,6 @@ public class VMOpCode {
* primarily used to handle basic byte8 division tasks.
*/
public static final int B_DIV = 34;
-
/**
* B_MOD Opcode: Represents the byte8 modulus (remainder) operation in the virtual machine.
* This opcode is implemented by the {@link BModCommand} class, which defines its specific execution logic.
@@ -478,7 +460,6 @@ public class VMOpCode {
* primarily used to handle basic byte8 modulus (remainder) tasks.
*/
public static final int B_MOD = 35;
-
/**
* B_INC Opcode: Represents the byte8 increment operation for a local variable in the virtual machine.
* This opcode is implemented by the {@link BIncCommand} class, which defines its specific execution logic.
@@ -496,8 +477,6 @@ public class VMOpCode {
* This opcode is particularly useful for optimizing scenarios where a local `byte8` variable, such as a counter or loop index, is frequently incremented.
*/
public static final int B_INC = 36;
-
-
/**
* B_NEG Opcode: Represents the byte8 negation operation in the virtual machine.
* This opcode is implemented by the {@link BNegCommand} class, which defines its specific execution logic.
@@ -512,8 +491,8 @@ public class VMOpCode {
* This opcode is typically used to negate a byte8 value, making it a fundamental operation for arithmetic logic within the virtual machine.
*/
public static final int B_NEG = 37;
-
// endregion
+
// region 1.5 double64 (41-50)
/**
* D_ADD Opcode: Represents the double64 precision floating-point addition operation in the virtual machine.
@@ -530,7 +509,6 @@ public class VMOpCode {
* primarily used to handle basic double64 precision floating-point addition tasks.
*/
public static final int D_ADD = 41;
-
/**
* D_SUB Opcode: Represents the double64 precision floating-point subtraction operation in the virtual machine.
* This opcode is implemented by the {@link DSubCommand} class, which defines its specific execution logic.
@@ -546,7 +524,6 @@ public class VMOpCode {
* primarily used to handle basic double64 precision floating-point subtraction tasks.
*/
public static final int D_SUB = 42;
-
/**
* D_MUL Opcode: Represents the double64 precision floating-point multiplication operation in the virtual machine.
* This opcode is implemented by the {@link DMulCommand} class, which defines its specific execution logic.
@@ -562,7 +539,6 @@ public class VMOpCode {
* primarily used to handle basic double64 precision floating-point multiplication tasks.
*/
public static final int D_MUL = 43;
-
/**
* D_DIV Opcode: Represents the double64 precision floating-point division operation in the virtual machine.
* This opcode is implemented by the {@link DDivCommand} class, which defines its specific execution logic.
@@ -579,7 +555,6 @@ public class VMOpCode {
* primarily used to handle basic double64 precision floating-point division tasks.
*/
public static final int D_DIV = 44;
-
/**
* D_MOD Opcode: Represents the double64 precision floating-point modulus (remainder) operation in the virtual machine.
* This opcode is implemented by the {@link DModCommand} class, which defines its specific execution logic.
@@ -596,7 +571,6 @@ public class VMOpCode {
* primarily used to handle basic double64 precision floating-point modulus (remainder) tasks.
*/
public static final int D_MOD = 45;
-
/**
* D_INC Opcode: Represents the double64 increment operation for a local variable in the virtual machine.
* This opcode is implemented by the {@link DIncCommand} class, which defines its specific execution logic.
@@ -614,7 +588,6 @@ public class VMOpCode {
* This opcode is particularly useful for optimizing scenarios where a local `double64` variable, such as a counter or loop index, is frequently incremented.
*/
public static final int D_INC = 46;
-
/**
* D_NEG Opcode: Represents the double64 precision floating-point negation operation in the virtual machine.
* This opcode is implemented by the {@link DNegCommand} class, which defines its specific execution logic.
@@ -629,8 +602,8 @@ public class VMOpCode {
* This opcode is typically used to negate a double64 precision floating-point value, making it a fundamental operation for double64 precision arithmetic logic within the virtual machine.
*/
public static final int D_NEG = 47;
-
// endregion
+
// region 1.6 float32 (51-60)
/**
* F_ADD Opcode: Represents the float32 addition operation in the virtual machine.
@@ -726,7 +699,6 @@ public class VMOpCode {
* This opcode is particularly useful for optimizing scenarios where a local `float32` variable, such as a counter or loop index, is frequently incremented.
*/
public static final int F_INC = 56;
-
/**
* F_NEG Opcode: Represents the float32 negation operation in the virtual machine.
* This opcode is implemented by the {@link FNegCommand} class, which defines its specific execution logic.
@@ -741,7 +713,10 @@ public class VMOpCode {
* This opcode is typically used to negate a float32 value, making it a fundamental operation for float32 arithmetic logic within the virtual machine.
*/
public static final int F_NEG = 57;
+ // endregion
+ // endregion
+ // region 2. Type Conversion Operation
/**
* I2L Opcode: Represents the type conversion operation from int32 to long64 in the virtual machine.
* This opcode is implemented by the {@link I2LCommand} class, which defines its specific execution logic.
@@ -756,7 +731,6 @@ public class VMOpCode {
* This opcode is commonly used to widen an int32 value to a long64 type to accommodate larger numeric ranges.
*/
public static final int I2L = 61;
-
/**
* I2S Opcode: Represents the type conversion operation from int32 to short16 in the virtual machine.
* This opcode is implemented by the {@link I2SCommand} class, which defines its specific execution logic.
@@ -771,7 +745,6 @@ public class VMOpCode {
* This opcode is typically used to narrow an int32 value to a short16 type when a smaller data representation is needed.
*/
public static final int I2S = 62;
-
/**
* I2B Opcode: Represents the type conversion operation from int32 to byte8 in the virtual machine.
* This opcode is implemented by the {@link I2BCommand} class, which defines its specific execution logic.
@@ -786,7 +759,6 @@ public class VMOpCode {
* This opcode is used to narrow an int32 value to a byte8 type, suitable when a smaller numeric type is required.
*/
public static final int I2B = 63;
-
/**
* I2D Opcode: Represents the type conversion operation from int32 to double64 in the virtual machine.
* This opcode is implemented by the {@link I2DCommand} class, which defines its specific execution logic.
@@ -801,7 +773,6 @@ public class VMOpCode {
* This opcode is used to widen an int32 value to a double64 type, providing high-precision floating-point calculations.
*/
public static final int I2D = 64;
-
/**
* I2F Opcode: Represents the type conversion operation from int32 to float32 in the virtual machine.
* This opcode is implemented by the {@link I2FCommand} class, which defines its specific execution logic.
@@ -816,7 +787,6 @@ public class VMOpCode {
* This opcode is used to convert an int32 value to a float32 type when floating-point arithmetic is required.
*/
public static final int I2F = 65;
-
/**
* L2I Opcode: Represents the type conversion operation from long64 to int32 in the virtual machine.
* This opcode is implemented by the {@link L2ICommand} class, which defines its specific execution logic.
@@ -831,7 +801,6 @@ public class VMOpCode {
* This opcode is typically used to narrow a long64 value to an int32 type for further integer operations.
*/
public static final int L2I = 66;
-
/**
* L2D Opcode: Represents the type conversion operation from long64 to double64 in the virtual machine.
* This opcode is implemented by the {@link L2DCommand} class, which defines its specific execution logic.
@@ -981,9 +950,8 @@ public class VMOpCode {
* This opcode is used to widen a byte8 value to an int32 type to ensure compatibility with integer-based operations.
*/
public static final int B2I = 76;
+ // endregion
- // endregion
- // endregion
// region 2. Bitwise Operations (81–90)
// region 2.1 int32 (81-85)
/**
@@ -1507,6 +1475,8 @@ public class VMOpCode {
*
*/
public static final int F_PUSH = 116;
+ // endregion
+ // region 4.2 POP (121-125)
/**
* I_POP Opcode: Represents a stack operation that removes the top element from the operand stack.
* This opcode is implemented by the {@link PopCommand} class, which defines its specific execution logic.
@@ -1525,10 +1495,9 @@ public class VMOpCode {
* Ensuring stack balance during function calls or control flow transitions.
*
*/
-
- // endregion
- // region 4.2 POP (121-125)
public static final int POP = 121;
+ // endregion
+ // region 4.3 DUP (126-130)
/**
* DUP Opcode: Represents a stack operation that duplicates the top element of the operand stack.
* This opcode is implemented by the {@link DupCommand} class, which defines its specific execution logic.
@@ -1547,9 +1516,11 @@ public class VMOpCode {
* Managing stack balance when performing operations that require repeated access to the same data.
*
*/
- // endregion
- // region 4.3 DUP (126-130)
+
public static final int DUP = 126;
+ // endregion
+
+ // region 4.4 SWAP (131-135)
/**
* SWAP Opcode: Represents a stack operation that swaps the top two values of the operand stack.
* This opcode is implemented by the {@link SwapCommand} class, which defines its specific execution logic.
@@ -1569,12 +1540,9 @@ public class VMOpCode {
* Ensuring proper operand placement for later instructions that depend on the order of stack elements.
*
*/
-
- // endregion
- // region 4.4 SWAP (131-135)
public static final int SWAP = 131;
-
// endregion
+
// endregion
// region 5. Memory Operations (151–166)
/**
@@ -1818,7 +1786,7 @@ public class VMOpCode {
*
*/
public static final int F_LOAD = 166;
- // endregion
+
/**
* MOV Opcode: Represents a move operation that transfers a value from one local variable to another within the local variable store.
* This opcode is implemented by the {@link MovCommand} class, which defines its specific execution logic.
@@ -1839,7 +1807,8 @@ public class VMOpCode {
*
*/
public static final int MOV = 171;
- // region 6. function call
+ // endregion
+ // region 6. Function Call
/**
* CALL Opcode: Represents a function or subroutine call operation that transfers control to a specified function address.
* This opcode is implemented by the {@link CallCommand} class, which defines its specific execution logic.
@@ -1898,6 +1867,7 @@ public class VMOpCode {
*/
public static final int HALT = 255;
// endregion
+
/**
* Default constructor for creating an instance of VMOpCode.
* This constructor is empty as no specific initialization is required.
From c17ccc7540c791e4f9a585f533bb66387aa1cc47 Mon Sep 17 00:00:00 2001
From: zhangxun <1958638841@qq.com>
Date: Thu, 26 Jun 2025 19:03:51 +0800
Subject: [PATCH 4/8] =?UTF-8?q?style:=20=E5=8C=85=E5=90=8D=20org.jcnc.snow?=
=?UTF-8?q?.compiler.backend.util=20=E5=90=8E=E9=9D=A2=E5=A2=9E=E5=8A=A0?=
=?UTF-8?q?=20s?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../snow/compiler/backend/generator/BinaryOpGenerator.java | 4 ++--
.../jcnc/snow/compiler/backend/generator/CallGenerator.java | 2 +-
.../snow/compiler/backend/generator/CmpJumpGenerator.java | 4 ++--
.../jcnc/snow/compiler/backend/generator/JumpGenerator.java | 2 +-
.../snow/compiler/backend/generator/LoadConstGenerator.java | 2 +-
.../jcnc/snow/compiler/backend/generator/ReturnGenerator.java | 2 +-
.../snow/compiler/backend/generator/UnaryOpGenerator.java | 4 ++--
.../snow/compiler/backend/{util => utils}/IROpCodeMapper.java | 2 +-
.../jcnc/snow/compiler/backend/{util => utils}/OpHelper.java | 2 +-
9 files changed, 12 insertions(+), 12 deletions(-)
rename src/main/java/org/jcnc/snow/compiler/backend/{util => utils}/IROpCodeMapper.java (99%)
rename src/main/java/org/jcnc/snow/compiler/backend/{util => utils}/OpHelper.java (99%)
diff --git a/src/main/java/org/jcnc/snow/compiler/backend/generator/BinaryOpGenerator.java b/src/main/java/org/jcnc/snow/compiler/backend/generator/BinaryOpGenerator.java
index 91a4d91..0d0a983 100644
--- a/src/main/java/org/jcnc/snow/compiler/backend/generator/BinaryOpGenerator.java
+++ b/src/main/java/org/jcnc/snow/compiler/backend/generator/BinaryOpGenerator.java
@@ -2,8 +2,8 @@ package org.jcnc.snow.compiler.backend.generator;
import org.jcnc.snow.compiler.backend.builder.VMProgramBuilder;
import org.jcnc.snow.compiler.backend.core.InstructionGenerator;
-import org.jcnc.snow.compiler.backend.util.IROpCodeMapper;
-import org.jcnc.snow.compiler.backend.util.OpHelper;
+import org.jcnc.snow.compiler.backend.utils.IROpCodeMapper;
+import org.jcnc.snow.compiler.backend.utils.OpHelper;
import org.jcnc.snow.compiler.ir.core.IRValue;
import org.jcnc.snow.compiler.ir.instruction.BinaryOperationInstruction;
import org.jcnc.snow.compiler.ir.value.IRConstant;
diff --git a/src/main/java/org/jcnc/snow/compiler/backend/generator/CallGenerator.java b/src/main/java/org/jcnc/snow/compiler/backend/generator/CallGenerator.java
index ff6961b..d455a4b 100644
--- a/src/main/java/org/jcnc/snow/compiler/backend/generator/CallGenerator.java
+++ b/src/main/java/org/jcnc/snow/compiler/backend/generator/CallGenerator.java
@@ -2,7 +2,7 @@ package org.jcnc.snow.compiler.backend.generator;
import org.jcnc.snow.compiler.backend.builder.VMProgramBuilder;
import org.jcnc.snow.compiler.backend.core.InstructionGenerator;
-import org.jcnc.snow.compiler.backend.util.OpHelper;
+import org.jcnc.snow.compiler.backend.utils.OpHelper;
import org.jcnc.snow.compiler.ir.instruction.CallInstruction;
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
diff --git a/src/main/java/org/jcnc/snow/compiler/backend/generator/CmpJumpGenerator.java b/src/main/java/org/jcnc/snow/compiler/backend/generator/CmpJumpGenerator.java
index e6a3e28..57437b4 100644
--- a/src/main/java/org/jcnc/snow/compiler/backend/generator/CmpJumpGenerator.java
+++ b/src/main/java/org/jcnc/snow/compiler/backend/generator/CmpJumpGenerator.java
@@ -1,7 +1,7 @@
package org.jcnc.snow.compiler.backend.generator;
-import org.jcnc.snow.compiler.backend.util.IROpCodeMapper;
-import org.jcnc.snow.compiler.backend.util.OpHelper;
+import org.jcnc.snow.compiler.backend.utils.IROpCodeMapper;
+import org.jcnc.snow.compiler.backend.utils.OpHelper;
import org.jcnc.snow.compiler.backend.builder.VMProgramBuilder;
import org.jcnc.snow.compiler.backend.core.InstructionGenerator;
import org.jcnc.snow.compiler.ir.instruction.IRCompareJumpInstruction;
diff --git a/src/main/java/org/jcnc/snow/compiler/backend/generator/JumpGenerator.java b/src/main/java/org/jcnc/snow/compiler/backend/generator/JumpGenerator.java
index 85d2907..c8426b3 100644
--- a/src/main/java/org/jcnc/snow/compiler/backend/generator/JumpGenerator.java
+++ b/src/main/java/org/jcnc/snow/compiler/backend/generator/JumpGenerator.java
@@ -1,6 +1,6 @@
package org.jcnc.snow.compiler.backend.generator;
-import org.jcnc.snow.compiler.backend.util.OpHelper;
+import org.jcnc.snow.compiler.backend.utils.OpHelper;
import org.jcnc.snow.compiler.backend.builder.VMProgramBuilder;
import org.jcnc.snow.compiler.backend.core.InstructionGenerator;
import org.jcnc.snow.compiler.ir.instruction.IRJumpInstruction;
diff --git a/src/main/java/org/jcnc/snow/compiler/backend/generator/LoadConstGenerator.java b/src/main/java/org/jcnc/snow/compiler/backend/generator/LoadConstGenerator.java
index 9e75f22..760422a 100644
--- a/src/main/java/org/jcnc/snow/compiler/backend/generator/LoadConstGenerator.java
+++ b/src/main/java/org/jcnc/snow/compiler/backend/generator/LoadConstGenerator.java
@@ -2,7 +2,7 @@ package org.jcnc.snow.compiler.backend.generator;
import org.jcnc.snow.compiler.backend.builder.VMProgramBuilder;
import org.jcnc.snow.compiler.backend.core.InstructionGenerator;
-import org.jcnc.snow.compiler.backend.util.OpHelper;
+import org.jcnc.snow.compiler.backend.utils.OpHelper;
import org.jcnc.snow.compiler.ir.instruction.LoadConstInstruction;
import org.jcnc.snow.compiler.ir.value.IRConstant;
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
diff --git a/src/main/java/org/jcnc/snow/compiler/backend/generator/ReturnGenerator.java b/src/main/java/org/jcnc/snow/compiler/backend/generator/ReturnGenerator.java
index a58af50..6a48847 100644
--- a/src/main/java/org/jcnc/snow/compiler/backend/generator/ReturnGenerator.java
+++ b/src/main/java/org/jcnc/snow/compiler/backend/generator/ReturnGenerator.java
@@ -2,7 +2,7 @@ package org.jcnc.snow.compiler.backend.generator;
import org.jcnc.snow.compiler.backend.builder.VMProgramBuilder;
import org.jcnc.snow.compiler.backend.core.InstructionGenerator;
-import org.jcnc.snow.compiler.backend.util.OpHelper;
+import org.jcnc.snow.compiler.backend.utils.OpHelper;
import org.jcnc.snow.compiler.ir.instruction.ReturnInstruction;
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
diff --git a/src/main/java/org/jcnc/snow/compiler/backend/generator/UnaryOpGenerator.java b/src/main/java/org/jcnc/snow/compiler/backend/generator/UnaryOpGenerator.java
index 46d1f53..a3de573 100644
--- a/src/main/java/org/jcnc/snow/compiler/backend/generator/UnaryOpGenerator.java
+++ b/src/main/java/org/jcnc/snow/compiler/backend/generator/UnaryOpGenerator.java
@@ -1,7 +1,7 @@
package org.jcnc.snow.compiler.backend.generator;
-import org.jcnc.snow.compiler.backend.util.IROpCodeMapper;
-import org.jcnc.snow.compiler.backend.util.OpHelper;
+import org.jcnc.snow.compiler.backend.utils.IROpCodeMapper;
+import org.jcnc.snow.compiler.backend.utils.OpHelper;
import org.jcnc.snow.compiler.backend.builder.VMProgramBuilder;
import org.jcnc.snow.compiler.backend.core.InstructionGenerator;
import org.jcnc.snow.compiler.ir.instruction.UnaryOperationInstruction;
diff --git a/src/main/java/org/jcnc/snow/compiler/backend/util/IROpCodeMapper.java b/src/main/java/org/jcnc/snow/compiler/backend/utils/IROpCodeMapper.java
similarity index 99%
rename from src/main/java/org/jcnc/snow/compiler/backend/util/IROpCodeMapper.java
rename to src/main/java/org/jcnc/snow/compiler/backend/utils/IROpCodeMapper.java
index f2d2997..31c0033 100644
--- a/src/main/java/org/jcnc/snow/compiler/backend/util/IROpCodeMapper.java
+++ b/src/main/java/org/jcnc/snow/compiler/backend/utils/IROpCodeMapper.java
@@ -1,4 +1,4 @@
-package org.jcnc.snow.compiler.backend.util;
+package org.jcnc.snow.compiler.backend.utils;
import org.jcnc.snow.compiler.ir.core.IROpCode;
diff --git a/src/main/java/org/jcnc/snow/compiler/backend/util/OpHelper.java b/src/main/java/org/jcnc/snow/compiler/backend/utils/OpHelper.java
similarity index 99%
rename from src/main/java/org/jcnc/snow/compiler/backend/util/OpHelper.java
rename to src/main/java/org/jcnc/snow/compiler/backend/utils/OpHelper.java
index 8c7bba9..9328218 100644
--- a/src/main/java/org/jcnc/snow/compiler/backend/util/OpHelper.java
+++ b/src/main/java/org/jcnc/snow/compiler/backend/utils/OpHelper.java
@@ -1,4 +1,4 @@
-package org.jcnc.snow.compiler.backend.util;
+package org.jcnc.snow.compiler.backend.utils;
import org.jcnc.snow.vm.engine.VMOpCode;
From c03761ed610fa6df9502091b08ce0a2f87102224 Mon Sep 17 00:00:00 2001
From: zhangxun <1958638841@qq.com>
Date: Thu, 26 Jun 2025 20:39:54 +0800
Subject: [PATCH 5/8] =?UTF-8?q?fix:=20byte=E3=80=81short=20=E8=BF=90?=
=?UTF-8?q?=E7=AE=97=E5=90=8E=E4=BC=9A=E5=8F=98=E4=B8=BA=20int=20=E7=9A=84?=
=?UTF-8?q?=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../jcnc/snow/vm/commands/arithmetic/byte8/BAddCommand.java | 2 +-
.../jcnc/snow/vm/commands/arithmetic/byte8/BDivCommand.java | 2 +-
.../jcnc/snow/vm/commands/arithmetic/byte8/BModCommand.java | 2 +-
.../jcnc/snow/vm/commands/arithmetic/byte8/BMulCommand.java | 2 +-
.../jcnc/snow/vm/commands/arithmetic/byte8/BSubCommand.java | 2 +-
.../snow/vm/commands/arithmetic/short16/SAddCommand.java | 6 +++---
.../snow/vm/commands/arithmetic/short16/SDivCommand.java | 2 +-
.../snow/vm/commands/arithmetic/short16/SModCommand.java | 2 +-
.../snow/vm/commands/arithmetic/short16/SMulCommand.java | 2 +-
.../snow/vm/commands/arithmetic/short16/SSubCommand.java | 2 +-
10 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BAddCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BAddCommand.java
index b05f809..f2a42ca 100644
--- a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BAddCommand.java
+++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BAddCommand.java
@@ -50,7 +50,7 @@ public class BAddCommand implements Command {
byte a = (byte) operandStack.pop();
// Perform the addition and push the result back onto the stack
- operandStack.push(a + b);
+ operandStack.push((byte)(a + b));
// Return the updated program counter (next instruction)
return currentPC + 1;
diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BDivCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BDivCommand.java
index ad24912..582951b 100644
--- a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BDivCommand.java
+++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BDivCommand.java
@@ -56,7 +56,7 @@ public class BDivCommand implements Command {
}
// Perform the division and push the result back onto the stack
- operandStack.push(a / b);
+ operandStack.push((byte)(a / b));
// Return the updated program counter (next instruction)
return currentPC + 1;
diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BModCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BModCommand.java
index 88b12bd..dd5892f 100644
--- a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BModCommand.java
+++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BModCommand.java
@@ -50,7 +50,7 @@ public class BModCommand implements Command {
byte a = (byte) operandStack.pop();
// Perform the modulus operation and push the result back onto the stack
- operandStack.push(a % b);
+ operandStack.push((byte)(a % b));
// Return the updated program counter (next instruction)
return currentPC + 1;
diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BMulCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BMulCommand.java
index e5de63a..0c6d9c3 100644
--- a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BMulCommand.java
+++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BMulCommand.java
@@ -50,7 +50,7 @@ public class BMulCommand implements Command {
byte a = (byte) operandStack.pop();
// Perform the multiplication and push the result back onto the stack
- operandStack.push(a * b);
+ operandStack.push((byte)(a * b));
// Return the updated program counter (next instruction)
return currentPC + 1;
diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BSubCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BSubCommand.java
index 091cafd..4c7957e 100644
--- a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BSubCommand.java
+++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BSubCommand.java
@@ -50,7 +50,7 @@ public class BSubCommand implements Command {
byte a = (byte) operandStack.pop();
// Perform the subtraction and push the result back onto the stack
- operandStack.push(a - b);
+ operandStack.push((byte)(a - b));
// Return the updated program counter (next instruction)
return currentPC + 1;
diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SAddCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SAddCommand.java
index 4137a01..b4b1290 100644
--- a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SAddCommand.java
+++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SAddCommand.java
@@ -46,11 +46,11 @@ public class SAddCommand implements Command {
@Override
public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) {
// Pop the top two operands from the stack
- Short b = (Short) operandStack.pop();
- Short a = (Short) operandStack.pop();
+ short b = (short) operandStack.pop();
+ short a = (short) operandStack.pop();
// Perform the addition and push the result back onto the stack
- operandStack.push(a + b);
+ operandStack.push((short)(a + b));
// Return the updated program counter (next instruction)
return currentPC + 1;
diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SDivCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SDivCommand.java
index f14cefa..9c71b8c 100644
--- a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SDivCommand.java
+++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SDivCommand.java
@@ -56,7 +56,7 @@ public class SDivCommand implements Command {
}
// Perform the division and push the result back onto the stack
- operandStack.push(a / b);
+ operandStack.push((short)(a / b));
// Return the updated program counter (next instruction)
return currentPC + 1;
diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SModCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SModCommand.java
index 0047449..105b5bc 100644
--- a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SModCommand.java
+++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SModCommand.java
@@ -50,7 +50,7 @@ public class SModCommand implements Command {
short a = (short) operandStack.pop();
// Perform the modulus operation and push the result back onto the stack
- operandStack.push(a % b);
+ operandStack.push((short)(a % b));
// Return the updated program counter (next instruction)
return currentPC + 1;
diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SMulCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SMulCommand.java
index 1a2ac4e..f6c022d 100644
--- a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SMulCommand.java
+++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SMulCommand.java
@@ -50,7 +50,7 @@ public class SMulCommand implements Command {
short a = (short) operandStack.pop();
// Perform the multiplication and push the result back onto the stack
- operandStack.push(a * b);
+ operandStack.push((short)(a * b));
// Return the updated program counter (next instruction)
return currentPC + 1;
diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SSubCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SSubCommand.java
index 66c3295..53953b3 100644
--- a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SSubCommand.java
+++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SSubCommand.java
@@ -50,7 +50,7 @@ public class SSubCommand implements Command {
short a = (short) operandStack.pop();
// Perform the subtraction and push the result back onto the stack
- operandStack.push(a - b);
+ operandStack.push((short)(a - b));
// Return the updated program counter (next instruction)
return currentPC + 1;
From 8b421d3c92316020476c749f4a7be9b653c98dc2 Mon Sep 17 00:00:00 2001
From: zhangxun <1958638841@qq.com>
Date: Fri, 27 Jun 2025 13:13:41 +0800
Subject: [PATCH 6/8] =?UTF-8?q?fix:=20=E8=AF=AD=E4=B9=89=E5=88=86=E6=9E=90?=
=?UTF-8?q?=E6=8A=A5=E9=94=99=E6=98=BE=E7=A4=BA=E6=9C=AA=E7=9F=A5=E4=BD=8D?=
=?UTF-8?q?=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../compiler/ir/builder/IRProgramBuilder.java | 10 ++++-
.../compiler/parser/ast/AssignmentNode.java | 11 +++++-
.../parser/ast/BinaryExpressionNode.java | 13 ++++++-
.../parser/ast/CallExpressionNode.java | 1 +
.../compiler/parser/ast/DeclarationNode.java | 39 ++++++++++++++++++-
.../parser/ast/ExpressionStatementNode.java | 10 ++++-
.../compiler/parser/ast/FunctionNode.java | 14 ++++++-
.../compiler/parser/ast/IdentifierNode.java | 10 ++++-
.../jcnc/snow/compiler/parser/ast/IfNode.java | 8 +++-
.../snow/compiler/parser/ast/ImportNode.java | 10 ++++-
.../snow/compiler/parser/ast/LoopNode.java | 14 ++++++-
.../parser/ast/MemberExpressionNode.java | 11 +++++-
.../snow/compiler/parser/ast/ModuleNode.java | 12 +++++-
.../compiler/parser/ast/ParameterNode.java | 11 +++++-
.../snow/compiler/parser/ast/ReturnNode.java | 39 ++++++++++++++++++-
.../parser/ast/UnaryExpressionNode.java | 12 +++++-
.../expression/BinaryOperatorParselet.java | 7 +++-
.../parser/expression/CallParselet.java | 12 +++---
.../parser/expression/IdentifierParselet.java | 7 +++-
.../parser/expression/MemberParselet.java | 7 +++-
.../expression/UnaryOperatorParselet.java | 7 +++-
.../parser/function/FunctionParser.java | 23 ++++++++---
.../compiler/parser/module/ImportParser.java | 7 +++-
.../compiler/parser/module/ModuleParser.java | 7 +++-
.../statement/DeclarationStatementParser.java | 7 +++-
.../statement/ExpressionStatementParser.java | 9 ++++-
.../parser/statement/IfStatementParser.java | 7 +++-
.../parser/statement/LoopStatementParser.java | 14 ++++++-
.../statement/ReturnStatementParser.java | 7 +++-
29 files changed, 303 insertions(+), 43 deletions(-)
diff --git a/src/main/java/org/jcnc/snow/compiler/ir/builder/IRProgramBuilder.java b/src/main/java/org/jcnc/snow/compiler/ir/builder/IRProgramBuilder.java
index a1168ec..5513fdc 100644
--- a/src/main/java/org/jcnc/snow/compiler/ir/builder/IRProgramBuilder.java
+++ b/src/main/java/org/jcnc/snow/compiler/ir/builder/IRProgramBuilder.java
@@ -76,6 +76,14 @@ public final class IRProgramBuilder {
* @return 生成的 FunctionNode,用于后续 IRFunction 构建
*/
private FunctionNode wrapTopLevel(StatementNode stmt) {
- return new FunctionNode("_start", null, String.valueOf(List.of()), List.of(stmt));
+ return new FunctionNode(
+ "_start",
+ null,
+ String.valueOf(List.of()),
+ List.of(stmt),
+ -1,
+ -1,
+ ""
+ );
}
}
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/AssignmentNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/AssignmentNode.java
index 69781b9..eace610 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/ast/AssignmentNode.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/AssignmentNode.java
@@ -16,8 +16,17 @@ import org.jcnc.snow.compiler.parser.ast.base.StatementNode;
*
* @param variable 左值变量名(即赋值目标)
* @param value 表达式右值(即赋值来源)
+ * @param line 当前节点所在的行号
+ * @param column 当前节点所在的列号
+ * @param file 当前节点所在的文件
*/
-public record AssignmentNode(String variable, ExpressionNode value) implements StatementNode {
+public record AssignmentNode(
+ String variable,
+ ExpressionNode value,
+ int line,
+ int column,
+ String file
+) implements StatementNode {
/**
* 返回赋值语句的字符串形式,便于调试与日志输出。
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/BinaryExpressionNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/BinaryExpressionNode.java
index 6e49e63..40412de 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/ast/BinaryExpressionNode.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/BinaryExpressionNode.java
@@ -12,9 +12,18 @@ import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode;
* @param left 左操作数(子表达式)
* @param operator 运算符字符串(如 "+", "-", "*", "/" 等)
* @param right 右操作数(子表达式)
+ * @param line 当前节点所在的行号
+ * @param column 当前节点所在的列号
+ * @param file 当前节点所在的文件
*/
-public record BinaryExpressionNode(ExpressionNode left, String operator,
- ExpressionNode right) implements ExpressionNode {
+public record BinaryExpressionNode(
+ ExpressionNode left,
+ String operator,
+ ExpressionNode right,
+ int line,
+ int column,
+ String file
+) implements ExpressionNode {
/**
* 返回该二元运算表达式的字符串表示形式。
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/CallExpressionNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/CallExpressionNode.java
index ac36871..22f47bc 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/ast/CallExpressionNode.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/CallExpressionNode.java
@@ -14,6 +14,7 @@ import java.util.List;
* @param arguments 参数表达式列表,表示函数调用中传递给函数的实际参数。参数的顺序与调用顺序一致。
* @param line 当前表达式所在的行号,方便调试和错误定位。
* @param column 当前表达式所在的列号,用于精确定位错误位置。
+ * @param file 当前表达式所在的文件,用于错误定位。
*/
public record CallExpressionNode(
ExpressionNode callee, // 被调用的表达式节点,表示函数或方法名
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/DeclarationNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/DeclarationNode.java
index 1819d1f..9e1edf5 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/ast/DeclarationNode.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/DeclarationNode.java
@@ -23,6 +23,15 @@ public class DeclarationNode implements StatementNode {
/** 可选的初始化表达式 */
private final Optional initializer;
+ /** 当前节点所在的行号 **/
+ private final int line;
+
+ /** 当前节点所在的列号 **/
+ private final int column;
+
+ /** 当前节点所在的文件 **/
+ private final String file;
+
/**
* 构造一个 {@code DeclarationNode} 实例。
*
@@ -30,10 +39,13 @@ public class DeclarationNode implements StatementNode {
* @param type 变量类型字符串(如 "int"、"string")
* @param initializer 可选初始化表达式,若为 {@code null} 表示未初始化
*/
- public DeclarationNode(String name, String type, ExpressionNode initializer) {
+ public DeclarationNode(String name, String type, ExpressionNode initializer, int line, int column, String file) {
this.name = name;
this.type = type;
this.initializer = Optional.ofNullable(initializer);
+ this.line = line;
+ this.column = column;
+ this.file = file;
}
/**
@@ -62,4 +74,29 @@ public class DeclarationNode implements StatementNode {
public Optional getInitializer() {
return initializer;
}
+
+ /**
+ * 获取当前表达式所在的行号。
+ *
+ * @return 当前表达式的行号。
+ */
+ public int line() {
+ return line;
+ }
+
+ /**
+ * 获取当前表达式所在的列号。
+ *
+ * @return 当前表达式的列号。
+ */
+ public int column() {
+ return column;
+ }
+
+ /**
+ * 获取当前表达式所在的文件名。
+ *
+ * @return 当前表达式所在的文件名。
+ */
+ public String file() { return file; }
}
\ No newline at end of file
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/ExpressionStatementNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/ExpressionStatementNode.java
index cf62fb1..1a2f7a5 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/ast/ExpressionStatementNode.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/ExpressionStatementNode.java
@@ -11,6 +11,14 @@ import org.jcnc.snow.compiler.parser.ast.base.StatementNode;
*
*
* @param expression 表达式主体,通常为函数调用、赋值、方法链式调用等可求值表达式。
+ * @param line 当前节点所在的行号
+ * @param column 当前节点所在的列号
+ * @param file 当前节点所在的文件
*/
-public record ExpressionStatementNode(ExpressionNode expression) implements StatementNode {
+public record ExpressionStatementNode(
+ ExpressionNode expression,
+ int line,
+ int column,
+ String file
+) implements StatementNode {
}
\ No newline at end of file
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/FunctionNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/FunctionNode.java
index 7ab55dd..29ab884 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/ast/FunctionNode.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/FunctionNode.java
@@ -17,7 +17,17 @@ import java.util.List;
* @param parameters 参数列表,每项为 {@link ParameterNode} 表示一个形参定义
* @param returnType 函数的返回类型(如 "int"、"void" 等)
* @param body 函数体语句块,由一组 {@link StatementNode} 构成
+ * @param line 当前节点所在的行号
+ * @param column 当前节点所在的列号
+ * @param file 当前节点所在的文件
*/
-public record FunctionNode(String name, List parameters, String returnType,
- List body) implements Node {
+public record FunctionNode(
+ String name,
+ List parameters,
+ String returnType,
+ List body,
+ int line,
+ int column,
+ String file
+) implements Node {
}
\ No newline at end of file
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/IdentifierNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/IdentifierNode.java
index cfce3d4..de0ed17 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/ast/IdentifierNode.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/IdentifierNode.java
@@ -10,8 +10,16 @@ import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode;
*
*
* @param name 标识符的文本名称(如变量名 "x",函数名 "foo")
+ * @param line 当前节点所在的行号
+ * @param column 当前节点所在的列号
+ * @param file 当前节点所在的文件
*/
-public record IdentifierNode(String name) implements ExpressionNode {
+public record IdentifierNode(
+ String name,
+ int line,
+ int column,
+ String file
+) implements ExpressionNode {
/**
* 返回标识符节点的字符串形式,通常为其名称本身。
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/IfNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/IfNode.java
index 9ac9371..a26c8e2 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/ast/IfNode.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/IfNode.java
@@ -29,10 +29,16 @@ import java.util.List;
* @param condition 控制分支执行的条件表达式
* @param thenBranch 条件为 true 时执行的语句块
* @param elseBranch 条件为 false 时执行的语句块(可为空)
+ * @param line 当前节点所在的行号
+ * @param column 当前节点所在的列号
+ * @param file 当前节点所在的文件
*/
public record IfNode(
ExpressionNode condition,
List thenBranch,
- List elseBranch
+ List elseBranch,
+ int line,
+ int column,
+ String file
) implements StatementNode {
}
\ No newline at end of file
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/ImportNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/ImportNode.java
index f551fd9..c6b65e9 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/ast/ImportNode.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/ImportNode.java
@@ -14,6 +14,14 @@ import org.jcnc.snow.compiler.parser.ast.base.Node;
*
*
* @param moduleName 被导入的模块名称,通常为点分层次结构(如 "core.utils")
+ * @param line 当前节点所在的行号
+ * @param column 当前节点所在的列号
+ * @param file 当前节点所在的文件
*/
-public record ImportNode(String moduleName) implements Node {
+public record ImportNode(
+ String moduleName,
+ int line,
+ int column,
+ String file
+) implements Node {
}
\ No newline at end of file
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/LoopNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/LoopNode.java
index 7821ae4..a8ddbe1 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/ast/LoopNode.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/LoopNode.java
@@ -17,7 +17,17 @@ import java.util.List;
* @param condition 每次迭代前评估的条件表达式,控制循环是否继续
* @param update 每轮迭代完成后执行的更新语句
* @param body 循环体语句列表,表示循环主体执行逻辑
+ * @param line 当前节点所在的行号
+ * @param column 当前节点所在的列号
+ * @param file 当前节点所在的文件
*/
-public record LoopNode(StatementNode initializer, ExpressionNode condition, StatementNode update,
- List body) implements StatementNode {
+public record LoopNode(
+ StatementNode initializer,
+ ExpressionNode condition,
+ StatementNode update,
+ List body,
+ int line,
+ int column,
+ String file
+) implements StatementNode {
}
\ No newline at end of file
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/MemberExpressionNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/MemberExpressionNode.java
index 7b49db3..d0ac38e 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/ast/MemberExpressionNode.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/MemberExpressionNode.java
@@ -11,8 +11,17 @@ import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode;
*
* @param object 左侧对象表达式,表示成员所属的作用域或容器
* @param member 要访问的成员名称(字段名或方法名)
+ * @param line 当前节点所在的行号
+ * @param column 当前节点所在的列号
+ * @param file 当前节点所在的文件
*/
-public record MemberExpressionNode(ExpressionNode object, String member) implements ExpressionNode {
+public record MemberExpressionNode(
+ ExpressionNode object,
+ String member,
+ int line,
+ int column,
+ String file
+) implements ExpressionNode {
/**
* 返回成员访问表达式的字符串形式。
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/ModuleNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/ModuleNode.java
index 564402a..05d47de 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/ast/ModuleNode.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/ModuleNode.java
@@ -13,8 +13,18 @@ import java.util.StringJoiner;
* @param name 模块名称。
* @param imports 模块导入列表,每个导入是一个 {@link ImportNode}。
* @param functions 模块中的函数列表,每个函数是一个 {@link FunctionNode}。
+ * @param line 当前节点所在的行号
+ * @param column 当前节点所在的列号
+ * @param file 当前节点所在的文件
*/
-public record ModuleNode(String name, List imports, List functions) implements Node {
+public record ModuleNode(
+ String name,
+ List imports,
+ List functions,
+ int line,
+ int column,
+ String file
+) implements Node {
/**
* 返回模块节点的字符串表示形式,包含模块名、导入模块列表和函数列表。
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/ParameterNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/ParameterNode.java
index 91e93aa..0fbdc18 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/ast/ParameterNode.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/ParameterNode.java
@@ -11,8 +11,17 @@ import org.jcnc.snow.compiler.parser.ast.base.Node;
*
* @param name 参数名称标识符
* @param type 参数类型字符串(如 "int"、"string")
+ * @param line 当前节点所在的行号
+ * @param column 当前节点所在的列号
+ * @param file 当前节点所在的文件
*/
-public record ParameterNode(String name, String type) implements Node {
+public record ParameterNode(
+ String name,
+ String type,
+ int line,
+ int column,
+ String file
+) implements Node {
/**
* 返回参数的字符串形式,格式为 {@code name:type}。
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/ast/ReturnNode.java b/src/main/java/org/jcnc/snow/compiler/parser/ast/ReturnNode.java
index 28143dd..0fc2254 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/ast/ReturnNode.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/ast/ReturnNode.java
@@ -23,13 +23,25 @@ public class ReturnNode implements StatementNode {
/** 可选的返回值表达式 */
private final Optional expression;
+ /** 当前节点所在的行号 **/
+ private final int line;
+
+ /** 当前节点所在的列号 **/
+ private final int column;
+
+ /** 当前节点所在的文件 **/
+ private final String file;
+
/**
* 构造一个 {@code ReturnNode} 实例。
*
* @param expression 返回值表达式,如果无返回值则可为 {@code null}
*/
- public ReturnNode(ExpressionNode expression) {
+ public ReturnNode(ExpressionNode expression, int line, int column, String file) {
this.expression = Optional.ofNullable(expression);
+ this.line = line;
+ this.column = column;
+ this.file = file;
}
/**
@@ -40,4 +52,29 @@ public class ReturnNode implements StatementNode {
public Optional getExpression() {
return expression;
}
+
+ /**
+ * 获取当前表达式所在的行号。
+ *
+ * @return 当前表达式的行号。
+ */
+ public int line() {
+ return line;
+ }
+
+ /**
+ * 获取当前表达式所在的列号。
+ *
+ * @return 当前表达式的列号。
+ */
+ public int column() {
+ return column;
+ }
+
+ /**
+ * 获取当前表达式所在的文件名。
+ *
+ * @return 当前表达式所在的文件名。
+ */
+ public String file() { return file; }
}
\ No newline at end of file
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 d956fc8..7e38ebc 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
@@ -15,9 +15,17 @@ import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode;
*
* @param operator 一元运算符(仅 "-" 或 "!")
* @param operand 运算对象 / 右操作数
+ * @param line 当前节点所在的行号
+ * @param column 当前节点所在的列号
+ * @param file 当前节点所在的文件
*/
-public record UnaryExpressionNode(String operator,
- ExpressionNode operand) implements ExpressionNode {
+public record UnaryExpressionNode(
+ String operator,
+ ExpressionNode operand,
+ int line,
+ int column,
+ String file
+) implements ExpressionNode {
/**
* 生成调试友好的字符串表示,例如 {@code "-x"} 或 {@code "!flag"}。
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/expression/BinaryOperatorParselet.java b/src/main/java/org/jcnc/snow/compiler/parser/expression/BinaryOperatorParselet.java
index da86f01..adee8bd 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/expression/BinaryOperatorParselet.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/expression/BinaryOperatorParselet.java
@@ -37,6 +37,11 @@ public record BinaryOperatorParselet(Precedence precedence, boolean leftAssoc) i
*/
@Override
public ExpressionNode parse(ParserContext ctx, ExpressionNode left) {
+ // 获取当前 token 的行号、列号和文件名
+ int line = ctx.getTokens().peek().getLine();
+ int column = ctx.getTokens().peek().getCol();
+ String file = ctx.getSourceName();
+
Token op = ctx.getTokens().next();
int prec = precedence.ordinal();
@@ -46,7 +51,7 @@ public record BinaryOperatorParselet(Precedence precedence, boolean leftAssoc) i
leftAssoc ? Precedence.values()[prec] : Precedence.values()[prec - 1]
);
- return new BinaryExpressionNode(left, op.getLexeme(), right);
+ return new BinaryExpressionNode(left, op.getLexeme(), right, line, column, file);
}
/**
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/expression/CallParselet.java b/src/main/java/org/jcnc/snow/compiler/parser/expression/CallParselet.java
index 9499f6d..9f5478a 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/expression/CallParselet.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/expression/CallParselet.java
@@ -26,14 +26,15 @@ public class CallParselet implements InfixParselet {
*/
@Override
public ExpressionNode parse(ParserContext ctx, ExpressionNode left) {
+ // 获取函数名 token 的行号、列号和文件名
+ int line = ctx.getTokens().peek(-1).getLine();
+ int column = ctx.getTokens().peek(-1).getCol();
+ String file = ctx.getSourceName();
+
ctx.getTokens().next(); // 消费 "("
List args = new ArrayList<>();
- // 获取当前 token 的行号和列号
- int line = ctx.getTokens().peek().getLine();
- int column = ctx.getTokens().peek().getCol();
-
// 解析函数调用参数
if (!ctx.getTokens().peek().getLexeme().equals(")")) {
do {
@@ -43,8 +44,7 @@ public class CallParselet implements InfixParselet {
ctx.getTokens().expect(")"); // 消费并验证 ")"
- // 创建 CallExpressionNode 并传递位置信息,文件名称
- String file = ctx.getSourceName();
+ // 创建 CallExpressionNode 并传递位置信息
return new CallExpressionNode(left, args, line, column, file);
}
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/expression/IdentifierParselet.java b/src/main/java/org/jcnc/snow/compiler/parser/expression/IdentifierParselet.java
index 057c425..7e46337 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/expression/IdentifierParselet.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/expression/IdentifierParselet.java
@@ -24,6 +24,11 @@ public class IdentifierParselet implements PrefixParselet {
*/
@Override
public ExpressionNode parse(ParserContext ctx, Token token) {
- return new IdentifierNode(token.getLexeme());
+ // 获取标识符 token 的行号、列号和文件名
+ int line = ctx.getTokens().peek(-1).getLine();
+ int column = ctx.getTokens().peek(-1).getCol();
+ String file = ctx.getSourceName();
+
+ return new IdentifierNode(token.getLexeme(), line, column, file);
}
}
\ No newline at end of file
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/expression/MemberParselet.java b/src/main/java/org/jcnc/snow/compiler/parser/expression/MemberParselet.java
index b0f1e5f..ed3cd58 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/expression/MemberParselet.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/expression/MemberParselet.java
@@ -28,8 +28,13 @@ public class MemberParselet implements InfixParselet {
TokenStream ts = ctx.getTokens();
ts.expect("."); // 消费点号
+ // 获取当前 token 的行号、列号和文件名
+ int line = ctx.getTokens().peek().getLine();
+ int column = ctx.getTokens().peek().getCol();
+ String file = ctx.getSourceName();
+
String member = ts.expectType(TokenType.IDENTIFIER).getLexeme();
- return new MemberExpressionNode(left, member);
+ return new MemberExpressionNode(left, member, line, column, file);
}
/**
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/expression/UnaryOperatorParselet.java b/src/main/java/org/jcnc/snow/compiler/parser/expression/UnaryOperatorParselet.java
index abfa97a..5aedf93 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/expression/UnaryOperatorParselet.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/expression/UnaryOperatorParselet.java
@@ -41,6 +41,11 @@ public class UnaryOperatorParselet implements PrefixParselet {
*/
@Override
public ExpressionNode parse(ParserContext ctx, Token token) {
+ // 获取当前 token 的行号、列号和文件名
+ int line = ctx.getTokens().peek().getLine();
+ int column = ctx.getTokens().peek().getCol();
+ String file = ctx.getSourceName();
+
/* ------------------------------------------------------------
* 1. 以 UNARY 优先级递归解析操作数,避免错误结合顺序。
* ------------------------------------------------------------ */
@@ -50,6 +55,6 @@ public class UnaryOperatorParselet implements PrefixParselet {
/* ------------------------------------------------------------
* 2. 封装成 AST 节点并返回。
* ------------------------------------------------------------ */
- return new UnaryExpressionNode(token.getLexeme(), operand);
+ return new UnaryExpressionNode(token.getLexeme(), operand, line, column, file);
}
}
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/function/FunctionParser.java b/src/main/java/org/jcnc/snow/compiler/parser/function/FunctionParser.java
index af2251e..a7a3449 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/function/FunctionParser.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/function/FunctionParser.java
@@ -57,6 +57,11 @@ public class FunctionParser implements TopLevelParser {
public FunctionNode parse(ParserContext ctx) {
TokenStream ts = ctx.getTokens();
+ // 获取当前 token 的行号、列号和文件名
+ int line = ctx.getTokens().peek().getLine();
+ int column = ctx.getTokens().peek().getCol();
+ String file = ctx.getSourceName();
+
parseFunctionHeader(ts);
String functionName = parseFunctionName(ts);
@@ -69,7 +74,7 @@ public class FunctionParser implements TopLevelParser {
parseFunctionFooter(ts);
- return new FunctionNode(functionName, parameters, returnType[0], body);
+ return new FunctionNode(functionName, parameters, returnType[0], body, line, column, file);
}
/**
@@ -92,7 +97,7 @@ public class FunctionParser implements TopLevelParser {
map.put("parameter", new SectionDefinition(
(TokenStream stream) -> stream.peek().getLexeme().equals("parameter"),
- (ParserContext context, TokenStream stream) -> params.addAll(parseParameters(stream))
+ (ParserContext context, TokenStream stream) -> params.addAll(parseParameters(context))
));
map.put("return_type", new SectionDefinition(
@@ -154,10 +159,12 @@ public class FunctionParser implements TopLevelParser {
*
*
*
- * @param ts 当前使用的 {@link TokenStream}。
+ * @param ctx 当前解析上下文,包含 {@link TokenStream} 和符号表等作用域信息。
* @return 所有参数节点的列表。
*/
- private List parseParameters(TokenStream ts) {
+ private List parseParameters(ParserContext ctx) {
+ TokenStream ts = ctx.getTokens();
+
ts.expect("parameter");
ts.expect(":");
skipComments(ts);
@@ -175,13 +182,19 @@ public class FunctionParser implements TopLevelParser {
if (lex.equals("return_type") || lex.equals("body") || lex.equals("end")) {
break;
}
+
+ // 获取当前 token 的行号、列号和文件名
+ int line = ctx.getTokens().peek().getLine();
+ int column = ctx.getTokens().peek().getCol();
+ String file = ctx.getSourceName();
+
ts.expect("declare");
String pname = ts.expectType(TokenType.IDENTIFIER).getLexeme();
ts.expect(":");
String ptype = ts.expectType(TokenType.TYPE).getLexeme();
skipComments(ts);
ts.expectType(TokenType.NEWLINE);
- list.add(new ParameterNode(pname, ptype));
+ list.add(new ParameterNode(pname, ptype, line, column, file));
}
return list;
}
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/module/ImportParser.java b/src/main/java/org/jcnc/snow/compiler/parser/module/ImportParser.java
index 38dd788..d5443ac 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/module/ImportParser.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/module/ImportParser.java
@@ -46,13 +46,18 @@ public class ImportParser {
// 解析一个或多个模块名(标识符),允许使用逗号分隔多个模块
do {
+ // 获取当前 token 的行号、列号和文件名
+ int line = ctx.getTokens().peek().getLine();
+ int column = ctx.getTokens().peek().getCol();
+ String file = ctx.getSourceName();
+
// 获取当前标识符类型的词法单元,并提取其原始词素
String mod = ctx.getTokens()
.expectType(TokenType.IDENTIFIER)
.getLexeme();
// 创建 ImportNode 节点并加入列表
- imports.add(new ImportNode(mod));
+ imports.add(new ImportNode(mod, line, column, file));
} while (ctx.getTokens().match(",")); // 如果匹配到逗号,继续解析下一个模块名
// 最后必须匹配换行符,标志 import 语句的结束
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/module/ModuleParser.java b/src/main/java/org/jcnc/snow/compiler/parser/module/ModuleParser.java
index b696410..ac9e05d 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/module/ModuleParser.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/module/ModuleParser.java
@@ -40,6 +40,11 @@ public class ModuleParser implements TopLevelParser {
// 获取当前上下文中提供的词法流
TokenStream ts = ctx.getTokens();
+ // 获取当前 token 的行号、列号和文件名
+ int line = ctx.getTokens().peek().getLine();
+ int column = ctx.getTokens().peek().getCol();
+ String file = ctx.getSourceName();
+
// 期望模块声明以关键字 "module:" 开始
ts.expect("module");
ts.expect(":");
@@ -90,6 +95,6 @@ public class ModuleParser implements TopLevelParser {
ts.expect("module");
// 构建并返回完整的模块语法树节点
- return new ModuleNode(name, imports, functions);
+ return new ModuleNode(name, imports, functions, line, column, file);
}
}
\ No newline at end of file
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/statement/DeclarationStatementParser.java b/src/main/java/org/jcnc/snow/compiler/parser/statement/DeclarationStatementParser.java
index b99d09c..2323ada 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/statement/DeclarationStatementParser.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/statement/DeclarationStatementParser.java
@@ -43,6 +43,11 @@ public class DeclarationStatementParser implements StatementParser {
*/
@Override
public DeclarationNode parse(ParserContext ctx) {
+ // 获取当前 token 的行号、列号和文件名
+ int line = ctx.getTokens().peek().getLine();
+ int column = ctx.getTokens().peek().getCol();
+ String file = ctx.getSourceName();
+
// 声明语句必须以 "declare" 开头
ctx.getTokens().expect("declare");
@@ -69,6 +74,6 @@ public class DeclarationStatementParser implements StatementParser {
ctx.getTokens().expectType(TokenType.NEWLINE);
// 返回构建好的声明语法树节点
- return new DeclarationNode(name, type, init);
+ return new DeclarationNode(name, type, init, line, column, file);
}
}
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/statement/ExpressionStatementParser.java b/src/main/java/org/jcnc/snow/compiler/parser/statement/ExpressionStatementParser.java
index dd9df94..526dbf0 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/statement/ExpressionStatementParser.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/statement/ExpressionStatementParser.java
@@ -50,6 +50,11 @@ public class ExpressionStatementParser implements StatementParser {
throw new IllegalStateException("Cannot parse expression starting with keyword: " + ts.peek().getLexeme());
}
+ // 获取当前 token 的行号、列号和文件名
+ int line = ctx.getTokens().peek().getLine();
+ int column = ctx.getTokens().peek().getCol();
+ String file = ctx.getSourceName();
+
// 处理赋值语句:格式为 identifier = expression
if (ts.peek().getType() == TokenType.IDENTIFIER
&& ts.peek(1).getLexeme().equals("=")) {
@@ -58,13 +63,13 @@ public class ExpressionStatementParser implements StatementParser {
ts.expect("="); // 消耗等号
ExpressionNode value = new PrattExpressionParser().parse(ctx); // 解析表达式
ts.expectType(TokenType.NEWLINE); // 语句必须以换行符结束
- return new AssignmentNode(varName, value); // 返回赋值节点
+ return new AssignmentNode(varName, value, line, column, file); // 返回赋值节点
}
// 处理普通表达式语句,如函数调用、字面量、运算表达式等
ExpressionNode expr = new PrattExpressionParser().parse(ctx);
ts.expectType(TokenType.NEWLINE); // 语句必须以换行符结束
- return new ExpressionStatementNode(expr); // 返回表达式语句节点
+ return new ExpressionStatementNode(expr, line, column, file); // 返回表达式语句节点
}
}
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/statement/IfStatementParser.java b/src/main/java/org/jcnc/snow/compiler/parser/statement/IfStatementParser.java
index f0e2498..eda8bb1 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/statement/IfStatementParser.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/statement/IfStatementParser.java
@@ -47,6 +47,11 @@ public class IfStatementParser implements StatementParser {
public IfNode parse(ParserContext ctx) {
var ts = ctx.getTokens(); // 获取 token 流引用
+ // 获取当前 token 的行号、列号和文件名
+ int line = ctx.getTokens().peek().getLine();
+ int column = ctx.getTokens().peek().getCol();
+ String file = ctx.getSourceName();
+
// 消耗起始关键字 "if"
ts.expect("if");
@@ -120,6 +125,6 @@ public class IfStatementParser implements StatementParser {
ts.expectType(TokenType.NEWLINE);
// 构建并返回 IfNode,包含条件、then 分支和 else 分支
- return new IfNode(condition, thenBranch, elseBranch);
+ return new IfNode(condition, thenBranch, elseBranch, line, column, file);
}
}
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/statement/LoopStatementParser.java b/src/main/java/org/jcnc/snow/compiler/parser/statement/LoopStatementParser.java
index 583b5c9..4422636 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/statement/LoopStatementParser.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/statement/LoopStatementParser.java
@@ -64,6 +64,12 @@ public class LoopStatementParser implements StatementParser {
public LoopNode parse(ParserContext ctx) {
TokenStream ts = ctx.getTokens();
+ // 获取当前 token 的行号、列号
+ int loop_line = ctx.getTokens().peek().getLine();
+ int loop_column = ctx.getTokens().peek().getCol();
+
+ String file = ctx.getSourceName();
+
// 匹配 loop: 起始语法
ParserUtils.matchHeader(ts, "loop");
@@ -101,12 +107,16 @@ public class LoopStatementParser implements StatementParser {
sections.put("update", new FlexibleSectionParser.SectionDefinition(
ts1 -> ts1.peek().getLexeme().equals("update"),
(ctx1, ts1) -> {
+ // 获取当前 token 的行号、列号
+ int line = ctx.getTokens().peek().getLine();
+ int column = ctx.getTokens().peek().getCol();
+
ParserUtils.matchHeader(ts1, "update");
String varName = ts1.expectType(TokenType.IDENTIFIER).getLexeme();
ts1.expect("=");
ExpressionNode expr = new PrattExpressionParser().parse(ctx1);
ts1.expectType(TokenType.NEWLINE);
- update[0] = new AssignmentNode(varName, expr);
+ update[0] = new AssignmentNode(varName, expr, line, column, file);
ParserUtils.skipNewlines(ts1);
}
));
@@ -140,6 +150,6 @@ public class LoopStatementParser implements StatementParser {
ParserUtils.matchFooter(ts, "loop");
// 返回构造完成的 LoopNode
- return new LoopNode(initializer[0], condition[0], update[0], body);
+ return new LoopNode(initializer[0], condition[0], update[0], body, loop_line, loop_column, file);
}
}
diff --git a/src/main/java/org/jcnc/snow/compiler/parser/statement/ReturnStatementParser.java b/src/main/java/org/jcnc/snow/compiler/parser/statement/ReturnStatementParser.java
index 8a6a6a2..080f1e6 100644
--- a/src/main/java/org/jcnc/snow/compiler/parser/statement/ReturnStatementParser.java
+++ b/src/main/java/org/jcnc/snow/compiler/parser/statement/ReturnStatementParser.java
@@ -35,6 +35,11 @@ public class ReturnStatementParser implements StatementParser {
*/
@Override
public ReturnNode parse(ParserContext ctx) {
+ // 获取当前 token 的行号、列号和文件名
+ int line = ctx.getTokens().peek().getLine();
+ int column = ctx.getTokens().peek().getCol();
+ String file = ctx.getSourceName();
+
// 消耗 "return" 关键字
ctx.getTokens().expect("return");
@@ -49,6 +54,6 @@ public class ReturnStatementParser implements StatementParser {
ctx.getTokens().expectType(TokenType.NEWLINE);
// 构建并返回 ReturnNode(可能为空表达式)
- return new ReturnNode(expr);
+ return new ReturnNode(expr, line, column, file);
}
}
From 43fd1d175d90d2c0654cbbe5eba012c13dcac7e1 Mon Sep 17 00:00:00 2001
From: zhangxun <1958638841@qq.com>
Date: Fri, 27 Jun 2025 13:14:52 +0800
Subject: [PATCH 7/8] =?UTF-8?q?fix:=20=E5=8C=85=E5=90=8D=E9=94=99=E8=AF=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/main/java/org/jcnc/snow/pkg/tasks/CompileTask.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/org/jcnc/snow/pkg/tasks/CompileTask.java b/src/main/java/org/jcnc/snow/pkg/tasks/CompileTask.java
index c76537b..4d8e9d1 100644
--- a/src/main/java/org/jcnc/snow/pkg/tasks/CompileTask.java
+++ b/src/main/java/org/jcnc/snow/pkg/tasks/CompileTask.java
@@ -1,7 +1,7 @@
package org.jcnc.snow.pkg.tasks;
import org.jcnc.snow.cli.commands.CompileCommand;
-import org.jcnc.snow.compiler.backend.util.OpHelper;
+import org.jcnc.snow.compiler.backend.utils.OpHelper;
import org.jcnc.snow.compiler.backend.alloc.RegisterAllocator;
import org.jcnc.snow.compiler.backend.builder.VMCodeGenerator;
import org.jcnc.snow.compiler.backend.builder.VMProgramBuilder;
From 237c35f0a0032ed15e31aa8c883d318e3cab3485 Mon Sep 17 00:00:00 2001
From: zhangxun <1958638841@qq.com>
Date: Fri, 27 Jun 2025 13:18:03 +0800
Subject: [PATCH 8/8] =?UTF-8?q?fix:=20=E9=83=A8=E5=88=86=E4=BB=A3=E7=A0=81?=
=?UTF-8?q?=E5=B5=8C=E5=A5=97=E6=A8=A1=E5=BC=8F=E6=95=B0=E4=B8=8D=E6=AD=A3?=
=?UTF-8?q?=E7=A1=AE=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../jcnc/snow/compiler/ir/builder/StatementBuilder.java | 9 ++++++---
.../analyzers/expression/CallExpressionAnalyzer.java | 6 +++---
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/src/main/java/org/jcnc/snow/compiler/ir/builder/StatementBuilder.java b/src/main/java/org/jcnc/snow/compiler/ir/builder/StatementBuilder.java
index 2290278..f731c57 100644
--- a/src/main/java/org/jcnc/snow/compiler/ir/builder/StatementBuilder.java
+++ b/src/main/java/org/jcnc/snow/compiler/ir/builder/StatementBuilder.java
@@ -66,12 +66,12 @@ public class StatementBuilder {
buildIf(ifNode);
return;
}
- if (stmt instanceof ExpressionStatementNode(ExpressionNode exp)) {
+ if (stmt instanceof ExpressionStatementNode(ExpressionNode exp, _, _, _)) {
// 纯表达式语句,如 foo();
expr.build(exp);
return;
}
- if (stmt instanceof AssignmentNode(String var, ExpressionNode rhs)) {
+ if (stmt instanceof AssignmentNode(String var, ExpressionNode rhs, _, _, _)) {
// 赋值语句,如 a = b + 1;
final String type = ctx.getScope().lookupType(var);
@@ -208,7 +208,10 @@ public class StatementBuilder {
if (cond instanceof BinaryExpressionNode(
ExpressionNode left,
String operator,
- ExpressionNode right
+ ExpressionNode right,
+ _,
+ _,
+ _
)
&& ComparisonUtils.isComparisonOperator(operator)) {
diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/expression/CallExpressionAnalyzer.java b/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/expression/CallExpressionAnalyzer.java
index b82d78f..9a6f923 100644
--- a/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/expression/CallExpressionAnalyzer.java
+++ b/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/expression/CallExpressionAnalyzer.java
@@ -51,8 +51,8 @@ public class CallExpressionAnalyzer implements ExpressionAnalyzer